Assign validation groups Symfony 2.5 - validation

I have Entity with some fields, for example name and name has validation group:
<?php
namespace RFQ\IronilBundle\Entity;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="users")
* #ORM\HasLifecycleCallbacks
*/
class User extends BaseUser {
/**
* #ORM\Column(type="string", length=50)
* #Assert\NotBlank(groups={"qqq"})
*/
protected $name;
My FormType:
public function buildForm(FormBuilderInterface $builder, array $options) {
$this->buildUserForm($builder, $options);
$builder->add('name', null, array(
'label' => 'Name',
'attr' => array(
'class' =>'form-control',
'placeholder' =>'Name'
)));
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => $this->class,
'intention' => 'profile',
'validation_groups' => array('qqq')
));
}
Problem is there that my validation group 'qqq' doesn't work, I can submit form with empty name input. In Symfony documentation is said that validation groups can pass trough setDefaultOptions method, like I did, but it just doesn't work. What I have missed?
Thank you!
EDIT:
After some testing I can say that there only works 'default' validation group, not my definied 'qqq'.

Related

Laravel JsonResource return specific key

<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class PostResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
Sometimes I need to return some specific key instead whole resource.
How to return a specific array of key from JsonResource toArray()? like Request with only(['key1', 'key4']) function.
From your controller, when you pass data to your view or API, you simply specify the exact key you want to access.
For example, in your controller
public function store(Request $request){
//You other logic here
$post = new PostResource( $request->all() );
//Here, you return only the specific key you want to access
return response([
'title' => $post->title,
]);
}
All the best

Code going through laravel basic authentication

Ok so I'm half way trough my app and I notice that I can pass code into my database. For example I use standard laravel authentication and if I type e.g.<?php die(); ?> instead of first name it passes right trough and goes into database. I'm confused now , I tought that laravel takes care of those things and thats one of the reasons I chose this framework. This is my last resort, I have been searching something in laravel documentation and all over the web about this and I found nothing.
Register Controller:
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'role' => ['required', 'string', 'max:100'],
'gendre' => ['required', 'string', 'max:100'],
'firstname' => ['required', 'string', 'max:100'],
'lastname' => ['required', 'string', 'max:100'],
'country' => ['required', 'string', 'max:100'],
'company' => ['required', 'string', 'max:100'],
'phone' => ['required', 'string', 'max:15'],
'email' => ['required', 'string', 'email', 'max:100', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'role' => $data['role'],
'gendre'=>$data['gendre'],
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
'country' => $data['country'],
'company' => $data['company'],
'phone' => $data['phone'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}
User model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'firstname', 'lastname' , 'email','password', 'company', 'phone','country','role','gendre'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
I only did some minor changes to what laravel already provides, nothing that special.
And Migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('role');
$table->string('gendre');
$table->string('firstname');
$table->string('lastname');
$table->string('country');
$table->string('company');
$table->string('phone');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
I think there may be a little bit of confusion going on here!
SQL Injection Attacks
The Laravel framework uses things like prepared statements to prevent SQL Injection Attacks. The stops things like
"; DELETE FROM `users`"
being appended to a database query when inserting data provided by form requests.
Escaping Rendered Characters
Trying to render content into a blade template will also be escaped by default unless you explicitly tell it otherswise
# $php_code = "<?php die(); ?>"
{{ $php_code }}
This will render as a a string of "".
# $php_code = "<?php die(); ?>"
{!! $php_code !!}
This will render the php and stop the script from running
TLDR;
The fact the the input is "<?php die(); ?>" is fine provided it is treated as a string. At the end of the day, It's just a string of valid characters

How to add multiple table relationship in laravel

I have following tables and building query with Laravel relationship. In my panel, once the user logged I am getting user details & user business details but now I don't know how to get business types details too.
User Table:
id | business_id | username | email | password
1 1 john632 john#gmail.com *******
Users Business Table
id | user_id | business_type_id | business_name
1 1 2 Fortune
Business Types Table
id | business_type_name | description
1 Hotel Lorem Ipsum
2 Movie Lorem Ipsum
Models:
User
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Zizaco\Entrust\Traits\EntrustUserTrait;
use App\Notifications\ResetPassword as ResetPasswordNotification;
use Laravel\Passport\HasApiTokens;
use Illuminate\Database\Eloquent\SoftDeletes;
use Webpatser\Uuid\Uuid;
use App\RoleUser;
use App\UsersBusiness;
class User extends Authenticatable
{
use Notifiable;
use EntrustUserTrait;
use HasApiTokens;
use SoftDeletes, EntrustUserTrait {
SoftDeletes::restore as sfRestore;
EntrustUserTrait::restore as euRestore;
}
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'business_id', 'username', 'email'
];
public function usersBusiness()
{
return $this->belongsTo('App\UsersBusiness', 'business_id', 'id');
}
}
UsersBusiness
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class UsersBusiness extends Model
{
use SoftDeletes;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'tbl_users_business';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'user_id', 'business_type_id', 'business_name'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
/**
* Dates to be treated as Carbon instances
*
* #var array
*/
public $dates = [
'deleted_at'
];
}
BusinessTypes
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class BusinessTypes extends Model
{
use SoftDeletes;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'tbl_master_business_types';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'business_type_name', 'description'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
/**
* Dates to be treated as Carbon instances
*
* #var array
*/
public $dates = [
'deleted_at'
];
}
Code:
$user = Auth::user();
$data['data'] = $user->load(['usersBusiness'] => function ($query) {
$query->select(["id", "user_id", "business_name"])->get();
}]);
I am getting below response data:
{
"data": {
"id": 1,
"business_id": 1,
"username": "john632",
"email": "john632#gmail.com",
"password": "john632",
"users_business": {
"id": 1,
"user_id": 4,
"business_type_id": 3,
"business_name": "Honest"
},
"business_types": null
},
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6Ijk4YTQ5OTBmOGQxOWQ5NTg1OGFlZWU1MDY0NTBiY2Y2OWJmOWQ3NzFhZjRmN2RmMzBmMWRkZWNmNWY4OTAzM2UyNmI2MzE3MTY3MDMxOTk4In0.eyJhdWQiOiIxIiwianRpIjoiOThhNDk5MGY4ZDE5ZDk1ODU4YWVlZTUwNjQ1MGJjZjY5YmY5ZDc3MWFmNGY3ZGYzMGYxZGRlY2Y1Zjg5MDMzZTI2YjYzMTcxNjcwMzE5OTgiLCJpYXQiOjE1MzIyNjA3ODUsIm5iZiI6MTUzMjI2MDc4NSwiZXhwIjoxNTYzNzk2Nzg1LCJzdWIiOiI1Iiwic2NvcGVzIjpbXX0.f_Xv0SrtTZ9m-40oHjAglCbKv76s_bARQ74XDihhFnI-jtHKwCWiF-jai5Yt6h9QyakCTZEo1bPAJdeph7Bj0_tKJpq3sGvK4t73_LZg_OOcsmAt61a4OSAgI1pjPV0tMMwHCoHm-xLlNnriAyaLCAbTQLQkfrw53467ys6rchE5V0rzy-JswjTfmB6SvZcqXsJQo6CWDRTWYbKvJO0FSmdZfLxxO_u4i_8ah5W63qJ4MSN9q22zkZLQ-L3NZhOux2KkwWiySioL2K25Y_UZmefClYwk1h-EY_LEVht3U7Kpqn9fmM6_Q4ByD-sSzLdAixdbq4REqinSaayzfMY934nijLu7ysEIc0oIukiHYcIk9tGV6DNuQ0CWhqEn0W_308MSBU4Ffyi5SQo7ubb5uPG7l_XOdomIR9dK9KtVONbPe7iF6TuccPCWZwvqKgfFl7TqEgiUWSiAl_ekkiaUDEM3cIuIH8AOLE17UuW4W0VyR2ziIt68au8SEuP2ilMBRsRMsFGbRKQWcvLluNw_qubcdzZ4yX9kuQAvXuBrHAcXb9WMlki2votvd7RKVDwxqwsTJRoeKNtJQdEQRbRZUD6nXyzGkmtEMrfwYoLVgTX3vAgVjO_erYtI5x-NV-EnoLT352odtRDYh5gTzVbmzYAxbLf_XUCDHjvlMEvM81g",
"status": true,
"status_code": 1,
"message": "Login successfully."
}
I want to add business types details too, so can you please guide me how to add relation for that table.
Thanks.
Create a belongsTo relation in your UserBusiness model like this
UserBusiness Model
public function businessType(){
return $this->belongsTo(BusinessType::class, 'business_type_id');
}
After that load it like this
$user = Auth::user();
$user->load(['usersBusiness.businessType']); //lazy loading
dd($user);
if you want userBusiness and their type only then
dd($user->usersBusiness);
Side Note: i think you don't need business_id in users table. Just keep user_id in userbusiness table and then add either hasOne ( if user can have only one business) or hasMany (if user can have more than one business) relation in User model for userBusness.
I recommend you to use API Resources.
For example, in my case I have ChannelItemResource.php:
public function toArray($request)
{
return [
'id' => $this->id,
'channel_id' => $this->channel_id,
'channel' => $this->channel->title,
'type' => $this->type,
'description' => $this->description,
'price' => $this->price,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
and ChannelResource.php:
return [
'id' => $this->id,
'title' => $this->title,
'user_id' => $this->user_id,
'description' => $this->description,
'type' => $this->type,
'url' => $this->url,
'ranking_total' => $this->ranking_total,
'ranking_flag' => $this->ranking_flag,
'ranking_country' => $this->ranking_country,
'thumbnail' => $this->thumbnail,
'state' => $this->state,
'hit' => $this->hit,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'items' => ChannelItemResource::collection($this->items),
];
With this structure, you can easily include which relation you want and the result will be in JSON.
In Controller use:
public function all(Request $request)
{
return new ChannelsResource(Channel::where("state", "active")->orderBy('id', 'desc')->paginate(30));
}

how to set cakephp 3 email unique validation

I created a table users with 2 fields id(primary),(email)
I want email unique validation used following code but not working only not empty working.
<?php
namespace App\Controller;
use App\Model\Validation\UserValidator;
class UsersController extends AppController
{
public function register()
{
$this->loadModel("users");
if ($this->request->is('post')) {
$validator = new UserValidator();
$errors = $validator->errors($this->request->getData());
if (empty($errors)) {
} else {
$this->set('errors', $errors);
}
}
}
}
src/Model/Validation/UserValidator.php
<?php
namespace App\Model\Validation;
use Cake\Validation\Validator;
use Cake\ORM\Table;
use Cake\ORM\Rule\IsUnique;
class UserValidator extends Validator {
public function __construct()
{
parent::__construct();
$this
->notEmpty('name', 'The name field cannot be left empty')
->notEmpty('email', 'Fill Valid Email Id')
->add('email',['unique' => ['rule' => 'validateUnique', 'provider' => 'table', 'message' => 'Not unique']])
->notEmpty('mobile', 'Fill Valid 10 Digit Mobile No.');
}
}
create this file under \src\Model\Table\Userstable.php
updated
change the the filename capitalize the to make it \src\Model\Table\UsersTable.php
in my code below I validated my username and email as unique
use App\Model\Entity\User;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\ORM\Rule\IsUnique;
/**
* Users Model
*
*/
class UsersTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('users');
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->requirePresence('username','create')
->notBlank('username', 'A username is required')
->add('username', 'unique', [
'rule' => 'validateUnique',
'provider' => 'table',
'message' => 'Username is already used'
]);
$validator
->requirePresence('email','create')
->notBlank('email', 'An email is required')
->add('email', 'unique', [
'rule' => 'validateUnique',
'provider' => 'table',
'message' => 'Email is already used'
]);
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['username']));
$rules->add($rules->isUnique(['email']));
return $rules;
}
}

How to build rule exist in or equal to a number in cakephp 3?

I have table comments with column parent_id.
And this is content of CommentsTable.php:
namespace App\Model\Table;
use App\Model\Entity\Comment;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* Comments Model
*/
class CommentsTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
$this->table('comments');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Posts', [
'foreignKey' => 'post_id',
'joinType' => 'INNER'
]);
$this->belongsTo('ParentComments', [
'className' => 'Comments',
'foreignKey' => 'parent_id'
]);
$this->hasMany('ChildComments', [
'className' => 'Comments',
'foreignKey' => 'parent_id'
]);
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create')
->requirePresence('body', 'create')
->notEmpty('body')
->requirePresence('path', 'create')
->notEmpty('path')
->add('status', 'valid', ['rule' => 'numeric'])
->requirePresence('status', 'create')
->notEmpty('status')
->add('created_at', 'valid', ['rule' => 'datetime'])
->requirePresence('created_at', 'create')
->notEmpty('created_at')
->add('updated_at', 'valid', ['rule' => 'datetime'])
->requirePresence('updated_at', 'create')
->notEmpty('updated_at');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* #param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* #return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['user_id'], 'Users'));
$rules->add($rules->existsIn(['post_id'], 'Posts'));
$rules->add($rules->existsIn(['parent_id'], 'ParentComments'));
return $rules;
}
}
I want to build rule for field parent_id: exist in ParentComments or equal to 0.
Can you help me?
Thank you very much.
Rules are just callable functions or callable classes. The existsIn() function is just an alias for the ExistsIn class. We can use the to our advantage:
...
use Cake\ORM\Rule\ExistsIn;
class CommentsTable extends Table
{
...
public function buildRules(RulesChecker $rules)
{
...
$rules->add(
function ($entity, $options) {
$rule = new ExistsIn(['parent_id'], 'ParentComments');
return $entity->parent_id === 1 || $rule($entity, $options);
},
['errorField' => 'parent_id', 'message' => 'Wrong Parent']
);
return $rules;
}
}

Resources