Yii2 model rules match validation - yii2

In model rules I have this rule:
[
['field1', 'field2,]
'match',
'pattern' => "/^[а-яА-ЯіІїЇєЄa-zA-Z\s\`\'\-\,]*$/u",
]
On form submit this rule works fine. But on client side it's not working. In console I see error:
Uncaught SyntaxError: Invalid regular expression: /^[а-яА-ЯіІїЇєЄa-zA-Z\s\`'-,]*$/: Invalid escape
Why this rule doesn't works on client side?

Escape with double slash fixes client side without crashing server side
[
['field1', 'field2,]
'match',
'pattern' => "/^[а-яА-ЯіІїЇєЄa-zA-Z\s\\\`\\\'-\\\,]*$/u",
]

Related

Yii2 ActiveForm Stripe token

In Yii2, we are using \Stripe\Charge::create following the site's documentation example:
https://stripe.com/docs/payments/accept-a-payment-charges
Everything works great as long we use straight HTML in the views, but when we embed the card-element in an ActiveForm, the stripe.js returns:
XMLHttpRequest cannot load https://api.stripe.com/v1/tokens due to
access control checks.
We would like to use ActiveForm to simplify the validation and handling of other fields on the form. Any help?
Best,
Joe
The error is CORS related, see CORS. Use the appropriate Access-Control as described there.
You can use Yii's build in behavior yii\filters\Cors in your controller.
Try first without any restriction:
public function behaviors()
{
return [
'corsFilter' => [
'class' => \yii\filters\Cors::className(),
],
];
}
If it works, than you can restrict the access by parametrising the behavior, something like that:
public function behaviors()
{
return [
'corsFilter' => [
'class' => \yii\filters\Cors::className(),
'cors' => [
'Origin' => [https://api.stripe.com'],
'Access-Control-Request-Method' => ['POST', 'PUT'],
],
],
];
}
So, for anyone landing here, the only way I can get this to work is to remove the ActiveForm scaffolding. Real bummer because I've had to validate the non-Stripe input fields with Javascript, which is lot more work.
I do challenge anyone to post working code in Yii using ActiveForm that will return a token. I don't think it can be done...but I would love to be wrong.
Best,
Joe

Yii2 Make endpoint accessible through web and rest api

A customer has requested to have the exact same endpoints available through web interface as well as through REST API.
The same endpoint should be visible using web browser only when being logged in. When accessing it via REST API, a valid access token must be submitted.
The rule for this specific endpoint is defined as follows:
[
'class' => 'yii\rest\UrlRule',
'controller' => 'site',
'pluralize' => false,
'extraPatterns' => [
'POST upload-raw-data' => 'uploadRawData'
],
]
Now, when I try to access this endpoint, I've got these results:
Browser: no problem
Postman / POST: 404 error
Postman / GET: no problem
When trying the same with enableStrictParsing enabled, I've got 404 errors all around.
If I need to provide other parts of the code, I'll happily provide them.
I think I found the solution for my issue. The problem seems to have been the CSRF validation.
By disabling it for this specific action in beforeAction(), the POST call behaves as intended.
public function beforeAction($action) {
if ($action->id == 'upload-raw-data')
Yii::$app->controller->enableCsrfValidation = false;
return parent::beforeAction($action);
}
source: https://gist.github.com/guerreiro/9e9cb3154b9047f5d2a0

Laravel 5.4 won't validate JSON

I'm using Laravel 5.4 and trying to validate JSON in my POST request however the validator fails stating that the JSON isn't valid, even though it is. I'm assuming I'm not understanding the validation rules correctly and my implementation is wrong, rather than a bug or something else.
I have a simple POST endpoint which has both the Accept and Content-Type headers set to application/json.
In my POST request (testing using Postman) I'm supplying RAW data.
{
"only_this_key": { "one": "two" }
}
In my controller method I have the following:
// I'm using intersect to remove any other parameters that may have been supplied as this endpoint only requires one
$requestData = $request->intersect(['only_this_key']);
$messages = [
'only_this_key.required' => 'The :attribute is required',
'only_this_key.json' => 'The :attribute field must be valid JSON',
];
$validator = \Validator::make($requestData, [
'only_this_key' => 'required|json',
], $messages);
if ($validator->fails()) {
return new APIErrorValidationResponse($request, $validator);
}
return response()->json(['all good' => 'here']);
The error I get back is The inventory field must be valid JSON even though it is!
Passing in the raw data using Postman
{
"only-this-key": {
"item-one": "one",
"item-two": "two",
"item-three": "three"
},
"not": "wanted"
}
When I use dd($request->all()); within the method
array:2 [
"what-i-want" => array:3 [
"item-one" => "one"
"item-two" => "two"
"item-three" => "three"
]
"not" => "wanted"
]
The problem is with how Laravel is interpreting the raw data in the request. If you run dd($request->all()) in your controller you will see this output:
array:1 [
"{"only_this_key":{"one":"two"}}" => ""
]
Your entire JSON string is getting set as a key with a value of an empty string. If you absolutely must send it as raw data, then you're going to have to grab that key value and save it to an array with the key that you want. This should work (instead of the intersect line).
$requestData = ['only_this_key' => key($request->all())];
Alternatively, you can just send the body as x-www-form-urlencoded with your entire JSON string as the only value for one key.

Yii2 isGuest giving exception in console application

In console application when I used Yii::$app->user->isGuest it is giving the below exception:
Exception 'yii\base\UnknownPropertyException' with message 'Getting unknown prop
erty: yii\console\Application::user'
I even tried adding the user in components array in config file. But it didn't worked. Any idea what am I doing wrong?
In Console application Yii->$app->user does not exist. So, you need to configure user component in config\console.php.
like as,
config\console.php
'components' => [
.........
......
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'app\models\User',
//'enableAutoLogin' => true,
],
'session' => [ // for use session in console application
'class' => 'yii\web\Session'
],
.......
]
To check it works or not using below code.
public function actionIndex($message = 'hello world')
{
echo $message . "\n";
$session = \Yii::$app->session->set('name', 'ASG');
if(\Yii::$app->session) // to check session works or not
echo \Yii::$app->session->get('name')."\n";
print_R(\Yii::$app->user);
}
More info about your problem : Link
Note : There's no session in console.
The reason is simple. Guide says about application components (user is a component):
user: represents the user authentication information. This component
is only available in Web applications Please refer to the
Authentication section for more details.
So Yii::$app->user it not available in console applications.
As a consequence you have to consider using this component in model classes that are also used by console applications.
Extra note: it is internally used by BlameableBehavior, however, this makes no problems since user will be null if a model gets saved/created and no user is available.

YII - Adding error code in form validation

I have a web-service and want to send a custom error-code and string in case form validation fails. We can specify error 'message' in form validation rules, but I want to add a numerical error code, that I can use later to get a text string. Extending CValidator is not an option as I want to use standard validators.
Ideally, I would like something like this in my rules() function.
array('page', 'numerical', 'integerOnly' => true, 'min' => 1, 'message' => '{attribute} is invalid', 'code' => 10079),
Later I return a JSON block like
{
'code': 10079,
'message' : 'page is invalid'
}
I am thinking of attaching a behavior to validators, but not quite able to figure out a way to make it work. Is there any other yii-way to do it?
instead of message , you just return the error code as message and on the view page just call a function to retrieve the appropriate error message.
provide $form->error(); as parameter to get errorMessage on the view page.