Yii2 - filter strtolower, but save the without lowering characters - yii

I have this rule:
['name', 'filter', 'filter'=>'strtolower'],
is it possible to use the rule only for validation, but to save the normal string (without the filter)?

Yes it is:
you add a property to your model call it whatever
public $notFiltered;
add beforeValidate method
protected function beforeValidate()
{
$this->notFiltered = $this->yourPropertyToValidate;
return parent::beforeValidate();
}
then add before save to the model
protected function beforeSave()
{
$this->yourPropertyToValidate = $this->notFiltered;
return parent::beforeSave()
}
That should bypass it.

Related

how to set validation rule for password in prestashop 1.6.3

how to set validation rule for password in prestashop 1.6.3
I need to add validation for alpha numeric and some validation rules.Currently prestashop by default takes any password without any validation
You can achieve that with a hook actionBeforeSubmitAccount. In that hook you can validate any POST field and pass errors to the controller's error array.
public function hookActionBeforeSubmitAccount()
{
$password = Tools::getValue('passwd');
// some validation logic here
if ($some_validation_failed) {
// Add error to AuthController's errors array
$this->context->controller->errors[] = Tools::displayError('Password validation failed!');
}
}
The AuthController creates an account only if its property $errors array is empty, otherwise it will put you back into account form with errors.
Pretty much every other controller works the same way when it comes to validations.
In file /classes/Validate.php, you will see a function as follows:
public static function isPasswd($passwd, $size = Validate::PASSWORD_LENGTH)
{
return (Tools::strlen($passwd) >= $size && Tools::strlen($passwd) < 255);
}
This function is responsible for the current validation of any password, you can simply modify the same as per your requirements.

Aurelia validation errors not displayed when validation initialized on attached

I want to show invalid input fields when the view is shown.
I have validation rules setup in a separate class (UserValidation) with one function (initValidatorOn).
export class UserValidation {
public _validation: Validation;
constructor(validation: Validation) {
this._validation = validation;
}
initValidatorOn(user: UserDto): ValidationGroup {
return this._validation.on(user, null)
.ensure('name').isNotEmpty();
}
}
Everything works for this setup.
export class User {
public validationGroup : ValidationGroup;
public userValidation : UserValidation;
public user : UserDto;
constructor(uv: UserValidation) {
this.userValidation = uv;
//this code works here and in activate method
this.validationGroup = this.userValidation.initValidatorOn(this.user);
}
attached() {
this.validationGroup.validate();
}
}
As I said before, the above works. But sometimes the object that I need to validate I not available in constructor or in activate function so I need to initialize validation in attached function. When I do that, my view no longer shows validation errors until I update the value in input.
So, this doesn't work
attached() {
this.validationGroup = this.userValidation.initValidatorOn(this.user);
//no validation errors displayed on the view
this.validationGroup.validate();
}
Can someone explain why errors aren't displayed on the view after I call validate when I initialize validationGroup in attached function?
Thank you.

How do I make a construct to have beforeAuth only apply to certain views/functions in Laravel 4

I have a resource in Laravel I have called artists with an ArtistsController. I would like to add filters to some of the pages, but not all. I know I can add a filter to all of the functions/views in the resource controller like so:
public function __construct()
{
$this->beforeFilter('auth', array('except' => array()));
}
How do I add the beforeAuth filter to only a certain view/function? I would like a user to be logged in in order to go the "index" view, but I would like a user to be able to go to the "show" pages without necessarily being logged in:
public function index()
{
$artists = Artist::all();
return View::make('artists.index', compact('artists'))
->with('artists', Artist::all())
->with('artists_new', Artist::artists_new());
}
public function show($id)
{
$artist = Artist::find($id);
return View::make('artists.show', compact('artist'))
->with('fans', Fan::all());
}
Is there a way to do this? Thank you.
Not sure if this helps but you could use the only key instead of the except (if I understand your question correctly).
$this->beforeFilter('auth', array('only' => array('login', 'foo', 'bar')));
Although that would still go in the constructor.

Using RedirectToAction to break out of a controller/action

In every action in every controller, I would like to have a check that, in certain cases, would return the app to another controller/action. I would like the check to be as simple as possible, something like TestForExit( );
Here's my problem: all my actions return ActionResult, and here is a sample:
public ActionResult Partial()
{
TestForExit( );
...
return PartialView( "ViewPartial", data );
}
If TextForExit returns RedirectToAction( "Index", "Home" ) I have to have something like this:
public ActionResult Partial()
{
var result = TestForExit( );
if( result == null )
{
...
result = PartialView( "ViewPartial", data );
}
return result;
}
But, as I am going to have this everywhere, I'd really like to have TestForExit( ) itself be able to send me to Home/Index rather than return an ActionResult that my Action has to return.
In other words, how can I have TestForExit ACTUALLY go to Home/Index, instead of just returning an ActionResult the the original Action must return?
You will want to use an custom ActionFilter. You can apply this action filter globally. Then in the OnActionExecuting, you can perform the TestForExit check, and redirect if needed.
For example.
public void TestForExitActionFilterAttribute : ActionFilterAttribute, IActionFilter
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if(TextForExit())
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary {{ "Controller", "ExitController" },
{ "Action", "ExitAction" } });
}
base.OnActionExecuting(filterContext);
}
}
Now apply your [TestForExitActionFilter] attribute to your controllers, or individual actions. Or, to add it everywhere, add the following line to FilterConfig.RegisterGlobalFilters filters.Add(new TextForExitActionFilterAttribute()).
Here are some related links.
Redirecting to specified controller and action in asp.net mvc action filter
http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-custom-action-filters
Alternatively, you can just override the OnActionExecuting method directly in your controller class and add the logic there. This would make more sense than a custom attribute if you only need this exit logic for one particular controller.
Well your controller action method has to return eventually, so you still have to return an ActionResult no matter what if the action is executed.
If you want to avoid adding that code to every action, you could think about creating a custom Action Filter and then marking your actions with that filter, or applying a global filter if you need it for EVERY action.
Then in your action filter, you check your exit condition and redirect if necessary.

Yii Behaviors and scenario

i have a behavior for my models, the behavior has beforeFind, beforeSave, in methods i override user_id, something like:
...
public functio beforeSave() {
$this->owner->user_id = Yii::app()->user->id
}
I have model User, how can i disable behavior for registration new user?
Saving code:
$user = new User();
$user->id = 1332;
$user->field1 = 'data';
$user->save();
but on save i have null in $user->id (because work behavior).
i tried
$user->disableBehaviors();
$user->detachBehavior();
Without result.
Maybe its not right way? I create behaviors for identify users in system (find only user something, save only with user id...), but that if i have new user with full previegies, i should again detach behaviors?
If condition can be changed in future I just pass it as callback parameter into behavior from model.
This give you a bit more control over the condition. Hence, behavior becomes more reusable - if it is used by several models this condition can be unique for each.
Example below is a bit simplified, but you should get the idea.
Behavior:
class SomeBehavior extends CActiveRecordBehavior
{
public $trigger;
public function beforeSave($event)
{
if(!call_user_func($this->trigger))
return;
// do what you need
$this->owner->user_id = Yii::app()->user->id;
}
}
Model:
class SomeModel extends CActiveRecord
{
public function behaviors()
{
$me=$this;
return array(
'some'=>array(
'class'=>'SomeBehavior',
'trigger'=>function() use($me){
return $me->scenario=='some-scenario';
}
)
);
}
}
Also I use PHP 5.3. So, I use closure for trigger callback.
If your PHP version is less than 5.3 - anything callable can be used instead. Check here http://www.php.net/manual/en/function.is-callable.php
Because of behavior is a method, you can declare your own logic inside.
The model knows about its scenario, so there is no problem to return different arrays for different conditions:)
Hope it be helpful for somebody.
You can check Yii::app()-user->isGuest to determine if the user is logged in or not. or you can just try looking for the null. Like this:
if (!Yii::app()->user->isGuest)
$this->owner->user_id = Yii::app()->user->id;
or
if (null !== Yii::app()->user->id)
$this->owner->user_id = Yii::app()->user->id;