Add letters only validation in a form Yii2 - yii

I want to validate my name text box from the special character
I try this:-
public function rules()
{
[
'full_name', 'match',
'pattern' => '/^[a-zA-Z\s]+$/',
'full_name' => 'full_name can only contain word characters'
]
}

Try this:
public function rules()
{
return [
'full_name', 'match',
'pattern' => '/^[a-zA-Z\s]+$/',
'message' => 'full_name can only contain word characters'
];
}
Refer Yii2 Core Match Validator

Related

Laravel 8: Extending UserCrudController from Package BackPack Permission-Manager

I want to add Department field in User entity, so I decided to extend the default UserCrudController from this package https://github.com/Laravel-Backpack/PermissionManager.
So I created a custom controller with this command php artisan make:controller Admin\UserController
In file \app\Providers\AppServiceProvider.php I also add this (as instructed)
public function register()
{
$this->app->bind(
\Backpack\PermissionManager\app\Http\Controllers\UserCrudController::class,
\App\Http\Controllers\Admin\UserController::class,
);
}
Then here is the content of \App\Http\Controllers\Admin\UserController
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Backpack\PermissionManager\app\Http\Controllers\UserCrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
class UserController extends UserCrudController
{
public function setupCreateOperation()
{
parent::setupCreateOperation();
$fields['departments'] = [
'label' => 'Departments',
'type' => 'select2_multiple',
'name' => 'tags',
'entity' => 'tags',
'attribute' => 'name',
'model' => "App\Models\Tag",
'pivot' => true,
'wrapper' => ['class' => 'form-group col-6 col-md-4'],
'options' => (function ($query) {
return $query->where('type', 'Department')->get();
}),
];
foreach($fields as $key=>$field) {
CRUD::addField($field);
}
}
public function setupUpdateOperation()
{
parent::setupUpdateOperation();
$this->setupCreateOperation();
}
}
All seems fine, I can see all default information such as: username, email, roles, permission and my custom department fields.
The problem is, when I try to modify an existing user adding some Departments, I got this error
The email has already been taken.
The password field is required.
Somehow it's treated as new user registration. What could be the problems?
Somehow, I solved it by copying setupCreateOperation to setupUpdateOperation.
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Backpack\PermissionManager\app\Http\Controllers\UserCrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
class UserController extends UserCrudController
{
...
public function setupUpdateOperation()
{
parent::setupUpdateOperation();
$fields['departments'] = [
'label' => 'Departments',
'type' => 'select2_multiple',
'name' => 'tags',
'entity' => 'tags',
'attribute' => 'name',
'model' => "App\Models\Tag",
'pivot' => true,
'wrapper' => ['class' => 'form-group col-6 col-md-4'],
'options' => (function ($query) {
return $query->where('type', 'Department')->get();
}),
];
foreach($fields as $key=>$field) {
CRUD::addField($field);
}
}
}
Hopefully there's a shorter way to reduce this duplication.

EasyAdmin 3 Symfony 5 CrudController AssociationField

I'm using EasyAmdin 3 with Symfony 5 and I have a OneToMany relation between Challenge and Encadrement. Defined In Challenge.php:
/**
* #ORM\OneToMany(targetEntity=Encadrement::class, mappedBy="challengePartner")
*/
private $bornes;
I made a CRUDController for Challenge, and I want to be able to add Encadrement directly when creating/editing a Challenge. I did this :
AssociationField::new('bornes'),
I can choose between all the Encadrement already created. But what I want is to be able to multiple add Encadrement and I can't find how to do this. I tried making my own EncadrementType :
class EncadrementType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, array(
"label" => "Nom"
))
->add('low', IntegerType::class, array(
"label" => "Borne basse"
))
->add('high', IntegerType::class, array(
"label" => "Borne haute"
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Encadrement::class,
]);
}
}
And something like this in the ChallengeCRUD:
AssociationField::new('bornes')->setFormType(EncadrementType::class),
But I get this error when I don't even use those options:
An error has occurred resolving the options of the form "App\Form\EncadrementType": The options "class", "multiple", "query_builder" do not exist. Defined options are: "action", "allow_extra_fields", "allow_file_upload", "attr", "attr_translation_parameters", "auto_initialize", "block_name", "block_prefix", "by_reference", "compound", "constraints", "csrf_field_name", "csrf_message", "csrf_protection", "csrf_token_id", "csrf_token_manager", "data", "data_class", "disabled", "ea_crud_form", "empty_data", "error_bubbling", "error_mapping", "extra_fields_message", "getter", "help", "help_attr", "help_html", "help_translation_parameters", "inherit_data", "invalid_message", "invalid_message_parameters", "is_empty_callback", "label", "label_attr", "label_format", "label_html", "label_translation_parameters", "legacy_error_messages", "mapped", "method", "post_max_size_message", "property_path", "required", "row_attr", "setter", "translation_domain", "trim", "upload_max_size_message", "validation_groups".
I tried adding the multiple option to the AssociationField but it does nothing:
AssociationField::new('bornes')->setFormTypeOption("multiple","true"),
I'm stuck there, thanks for any help !
Try CollectionField like this:
<?php
yield CollectionField::new('bornes')
->setFormTypeOptions([
'delete_empty' => true,
'by_reference' => false,
])
->setEntryIsComplex(false)
->setCustomOptions([
'allowAdd' => true,
'allowDelete' => true,
'entryType' => EncadrementType::class,
'showEntryLabel' => false,
])
;

How to apply rules on update in yii2

I am new to yii2 and I don't exactly know how to apply same rules of insert into update. Here is my rules for insert and I want all rules to effect on update too.
public $tag;
public function rules()
{
return [
[['user_id', 'name', 'address', 'state'], 'required'],
[['user_id'], 'integer'],
[['tag'], 'safe'],
[['name'], 'string', 'max' => 30],
[['address'], 'string', 'max' => 250],
[['state'], 'string', 'max' => 255],
];
}
Adding 'on' => 'update' doesn't effect in my code. Sorry for my english. Thanks.
The default rules are applied in the creation and update, you only have to create new rules if you want different behaviors between update and create.
To apply the rules just make a $model->validate() to check the rules, see this example of the documentation of yii2
$model->load(\Yii::$app->request->post());
if ($model->validate()) {
// all inputs are valid
} else {
// validation failed: $errors is an array containing error messages
$errors = $model->errors;
}
You can add validation rules to yii model like this
public function rules(){
return [
[['boolean_var'],'boolean'],
[[ 'range_in_string'],'required'],
[['default_value'],'default','value'=>'DEFAULT VALUE'],
[['integer_var'],'integer'],
[['double_var'],'double'],
[['number_min'],'number','min'=>10],
[['number_max'],'number','max'=>100],
[['number_min_max'],'number','min'=>10,'max'=>100],
[['file_image'],'image'],
[['file_var'],'file','types'=>['gif','jpg']],
[['date_var'],'date', 'format'=>'d-m-yy'],
[['min_string'],'string','min'=>10],
[['max_string'],'string','max'=>10],
[['min_max_string'],'string','min'=>5,'max'=>10],
['min_max_string2', 'string', 'length' => [4, 10]],
['email_var','email'],
['url_var','url'],
[['unique_var'],'unique'],
[['filter_trim'],'filter','filter'=>'trim'],
[['filter_trim'],'filter','filter'=>'strtolower'],
['filter_custom_function', 'filter', 'filter' => function ($value) {
// your concept
if($value=='')
return '';
return 'Value Changed';}],
['range_in_min_max', 'in','range'=>range(5,20)],
['range_in','in','range'=>['en','fr','zn'],'strict'=>false], //strict false
['range_in_string','in','range'=>['EN','FR','ZN'],'strict'=>true],
['custom_validation','custom_function_validation'],
[['passwordConfirm'], 'compare', 'compareAttribute' => 'password'],
[['password','date_var'],'safe'],
];
}
if you need to trigger only when updating but not creating, you can add a scenario like this
public function rules()
{
return [
// username, email and password are all required in "update" scenario
[['username', 'email', 'password'], 'required', 'on' => 'update'],
// username and password are required in "login" scenario
[['username', 'password'], 'required', 'on' => 'login'],
];
}
and in your action before calling validate add the scenario
// scenario is set as a property
$model = new User;
$model->scenario = 'update';

Laravel Auth::attempt() fails. I use SQLite btw

What i'm doing wrong?
<?php
public function login() {
$user_name = time();
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => Hash::make('123123'),
));
$user = array(
'email' => $user_name.'#test.com',
'password' => '123123',
);
$m = User::where('email' , '=', $user_name.'#test.com')->first();
dd([
'Auth::attempt($user)',
Auth::attempt($user),
'Auth::check()',
Auth::check(),
'Hash::check($m->password, \'123123\')',
Hash::check($m->password, '123123')
]);
}
Result:
array(6) {
[0]=>
string(20) "Auth::attempt($user)"
[1]=>
bool(false)
[2]=>
string(13) "Auth::check()"
[3]=>
bool(false)
[4]=>
string(38) "Hash::check($user->password, '123123')"
[5]=>
bool(false)
}
Not sure what information should I add.
app/config/auth.php
'driver' => 'eloquent',
'model' => 'User',
'table' => 'users',
app/config/app.php
'key' => 'DMmiPAxSYz4O2jG44S92OcdPZN7ZsGGs',
'cipher' => MCRYPT_RIJNDAEL_256,
models/User.php
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* Validation rules
*/
public static $rules = array(
'name' => 'required',
'email' => 'email|required|unique',
'password' => 'min:6',
);
/**
* Validation rules
*/
public static $messages = array(
'name.required' => 'The name field is required',
'email.email' => 'The email field must contain properly formatted email.',
'email.required' => 'The email field is required',
'password.required' => 'The password field is required',
'password.min:6' => 'The password must be minimum 6 characters long',
);
protected $table = 'users';
protected $hidden = array('password', 'remember_token');
protected $guarded = array('id');
public function setPasswordAttribute($value) {
if ($value) {
$this->attributes['password'] = Hash::make($value);
}
}
}
Well here's some checks that you can do
Have you setup config/auth.php with driver, model and table?
Have you filled the fillable array of the User's model?
Have you change the key inside config/app.php ?
Also try to dd($m) in order to see what you got from that query.
I found what is wrong.
This part of code hash password for first time:
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => Hash::make('123123'), // <---- first time
));
And this mutator in User model does hashing for second time before put password to database:
public function setPasswordAttribute($value) {
if ($value) {
$this->attributes['password'] = Hash::make($value); // <---- second time
}
}
So I just changed first block to this:
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => '123123', // <---- no hashing here
));

CakePHP 2, how to AuthComponent::login() with plain-text password?

I would like to implement CakePHP 2 website over existing database with plain-text password field.
This is my AppController
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'home'),
'authError' => 'You cannot view this page',
'authorize' => array('Controller'),
'authenticate' => array(
'Form' => array(
'userModel' => 'User',
'fields' => array('username' => 'user_id', 'password' => 'user_password')
)
)
)
);
public function isAuthorized($user) {
return true;
}
function beforeFilter() {
$this->Auth->allow('home');
//$this->Auth->authenticate = $this->User;
parent::beforeFilter();
}
This is my UserController.
class UsersController extends AppController {
public $paginate = array(
'fields' => array('user_id', 'user_desc', 'user_password'),
'limit' => 25,
'order' => array(
'user_id' => 'asc'
)
);
function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Cannot Login');
}
}
}
}
This is my User model
class User extends AppModel {
public $name = 'User';
public $primaryKey = 'user_id';
public $belongsTo = 'Group';
}
According to those files above, when I pressed the Login button on login.ctp, I saw
select * from users where user_password = 'this_is_hashing_password'
on the sql dump section.
So, how to turn-off the automatic hashing algorithm, so the login() will compare the user input to the database stored password as plain-text???
I have tried lots of reading on the CakePHP book but I cannot find any, also using hashPasswords($data) technique which found from the internet is not working.
Please help.
Kongthap.
The best answer really is to batch-process your stored passwords so they are hashed, however there are cases where you may be adding a Cake app to an existing application that hashes passwords differently (say by not hashing them at all), so the question is valid even if the goal in this case is not.
Try these resources for modifying Cake's password hashing function, depending on your Cake version:
Cake 2.x
Cake 1.3
I got plain text password working in Cakephp 3, this should only be use for DEVELOPMENT purpose, you should never store password in plain text in production.
That being said, during development, plain text password allows me to focus on login instead of implementing a fully functional user encrypt/decrypt logic. Which is going to be replaced by an OAuth / SAML module anyway...
OK here comes the source code:
ROOT/src/Auth/PlainTextPasswordHasher.php
<?php
namespace App\Auth;
use Cake\Auth\AbstractPasswordHasher;
/**
* Plain text password for demo use, DO NOT PUSTH THIS TO PROD
*/
class PlainTextPasswordHasher extends AbstractPasswordHasher
{
public function hash($password)
{
return $password;
}
public function check($password, $hashedPassword)
{
return $password === $hashedPassword;
}
}
ROOT/src/Controller/PagesController.php
<?php
class PagesController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'username',
'password' => 'password',
],
'passwordHasher' => [
'className' => 'PlainText',
],
'userModel' => 'YourUsers',
]
],
'loginAction' => [
'controller' => 'Logins',
'action' => 'login'
]
]);
}
}
Source: This video https://www.youtube.com/watch?v=eASSNS1f3V4 and this section of the official doc: https://book.cakephp.org/3.0/en/controllers/components/authentication.html#creating-custom-password-hasher-classes