Yii2 store text in DB, limited to 1829 bytes - mysql

I'm assigning to a model attribute the content of a text file. When I save it with AR to Mysql DB, innoDB table, mediumtext (I've tried with largetext, too) field type, it's truncated at 1829 bytes. I have no limitation rule in Yii2 for this attribute. Before saving, the full content is there. I have no clue if it's up to Yii2 or Mysql. When in Mysql I change the content of this field however, and import from file, then it's stored fully. I haven't found any infos on the web with such limitation. Any ideas? Thanks a lot!
public function rules() {
return [
...
[['text'], 'string'],
or:
[['text'], 'string', 'length' => 2000000],
];
}
Controller:
$model->text = preg_replace('/,(\r\n|\r|\n)\* /', ',', file_get_contents($file->tempName));
echo $model->text; // at this point still full content is there
$model->save(false);

Related

How can I translate Laravel's default validation errors in JSON file?

I need to translate Laravel's default validation errors in JSON files. The problem is if I want to overwrite a translation, like the 'required' validation error in resourses/lang/de.json file, it doesn't work.
The reason why I have to do this is the Phrase translator system what I am using.
Any idea? Thanks!
UPDATE
After some research, now I see what is my 'problem'. Laravel using the trans() function for translating the validation errors but if you want to use Laravel's JSON translation then you have to use the __() function. Okey, I know why they are doing in that way, because the validation errors are structured by 'short keys' and the JSON formatted translation if for use strings as keys.
But what if I still want to translate the default errors in the JSONish (I know it's a futuristic word) way? Follow my solution here:
First of all you have to create a form request (https://laravel.com/docs/7.x/validation#creating-form-requests):
php artisan make:request UserUpdateRequest
In the newly created form request file you have to overwrite the messages function to be able to translate the validation errors:
namespace App\Http\Requests\v1;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use App\Exceptions\ApiValidationException;
class UserUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => ['required', 'string', 'min:3', 'max:255'],
];
}
/**
* Get custom messages for validator errors.
*
* #return array
*/
public function messages()
{
return [
'name.required' => __('The user name is required.'),
'name.string' => __('The user name must be a string.'),
'name.min' => __('The user name must be at least three characters.'),
'name.max' => __('The user name may not be greater than 255 characters.'),
];
}
}
Now we have to create the translations files (https://laravel.com/docs/7.x/localization#using-translation-strings-as-keys) and put the new translation strings into them.
# resourses/lang/de.json
{
"The user name is required." : "The user name is required.",
"The user name must be a string." : "The user name must be a string.",
"The user name must be at least three characters." : "The user name must be at least three characters.",
"The user name may not be greater than 255 characters." : "The user name may not be greater than 255 characters."
}
And that's all.
I hope this description of translation process it will be useful for someone else.
I need to translate Laravel's default validation errors in JSON files. The problem is if I want to overwrite a translation, like the 'required' validation error in resourses/lang/de.json file, it doesn't work.
The reason why I have to do this is the Phrase translator system what I am using.
Any idea? Thanks!
ANSWER
After some research, now I see what is my 'problem'. Laravel using the trans() function for translating the validation errors but if you want to use Laravel's JSON translation then you have to use the __() function. Okey, I know why they are doing in that way, because the validation errors are structured by 'short keys' and the JSON formatted translation if for use strings as keys.
But what if I still want to translate the default errors in the JSONish (I know it's a futuristic word) way? Follow my solution here:
First of all you have to create a form request (https://laravel.com/docs/7.x/validation#creating-form-requests):
php artisan make:request UserUpdateRequest
In the newly created form request file you have to overwrite the messages function to be able to translate the validation errors:
namespace App\Http\Requests\v1;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use App\Exceptions\ApiValidationException;
class UserUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => ['required', 'string', 'min:3', 'max:255'],
];
}
/**
* Get custom messages for validator errors.
*
* #return array
*/
public function messages()
{
return [
'name.required' => __('The user name is required.'),
'name.string' => __('The user name must be a string.'),
'name.min' => __('The user name must be at least three characters.'),
'name.max' => __('The user name may not be greater than 255 characters.'),
];
}
}
Now we have to create the translations files (https://laravel.com/docs/7.x/localization#using-translation-strings-as-keys) and put the new translation strings into them.
# resourses/lang/de.json
{
"The user name is required." : "The user name is required.",
"The user name must be a string." : "The user name must be a string.",
"The user name must be at least three characters." : "The user name must be at least three characters.",
"The user name may not be greater than 255 characters." : "The user name may not be greater than 255 characters."
}
And that's all.
I hope this description of translation process it will be useful for someone else.
Based on the answer provided I digged some more and discovered the double underscore function is working as intended in the default validation.php file! I tested it with Laravel 5.6.
I have a similar issue that I need to provide a way for users to give translations for everything in the web app and so I started to test the solution. While it works as explained it does not use the placeholder attribute anymore and therefore it is not very scalable in my situation.
I tested using the double underscore function with the following requirements:
locale and fallback_locale are set to 'en' in app.php
There is an en folder inside resources/lang
There is a validation.php file inside the en folder
There is a locale json file (like pt-br.json) inside resources/lang folder
The application sets the locale dynamically using App::setlocale()
All that is needed to change in validation.php is to use the function in the string, like the following:
# before
'unique' => 'The :attribute has already been taken.',
#after
'unique' => __('The :attribute has already been taken.'),
And the json file needs to have a string key with the same string, like the following:
"The :attribute has already been taken.": ":attribute j\u00e1 existe!"
Thanks for making me thinking more on this problem. I think Laravel should have better support for use cases like this.

The default remember_me token in Laravel is too long

TL;DR How can I use my own way of generating the remember_me token?
I have an old site, written without any framework, and I have been given the job to rewrite it in Laravel (5.4.23). The DB is untouchable, cannot be refactored, cannot be modified in any way.
I was able to customise the Laravel authentication process using a different User model, one that reflect the old DB. But when it comes to the "Remember me" functionality, I have an issue with the length of the token.
The old site already uses the "Remember me" functionality but its DB field has been defined as BINARY(25). The token generated by the SessionGuard class is 60 characters long.
My first attempt was to try and find a way to shorten the token before writing it into the DB, and expand it again after reading it from the DB. I couldn't find such a way (and I'm not even sure there is such a way).
Then I looked into writing my own guard to override the cycleRememberToken (where the token is generated). I couldn't make it work, I think because the SessionGuard class is actually instantiated in a couple of places (as opposed to instantiate a class based on configuration).
So, I am stuck. I need a shorten token and I don't know how to get it.
Well, I was on the right track at one point.
I had to create my own guard, register it and use it. My problem, when I tried the first time, was that I did not register it in the right way. Anyway, this is what I did.
I put the following in AuthServiceProvides
Auth::extend('mysession', function ($app, $name, array $config) {
$provider = Auth::createUserProvider($config['provider']);
$guard = new MyGuard('lrb', $provider, app()->make('session.store'));
$guard->setCookieJar($this->app['cookie']);
$guard->setDispatcher($this->app['events']);
$guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
return $guard;
});
I change the guard in config/auth.php as
'guards' => [
'web' => [
'driver' => 'mysession',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
and finally my new guard
class MyGuard extends SessionGuard implements StatefulGuard, SupportsBasicAuth
{
/**
* #inheritdoc
*/
protected function cycleRememberToken(AuthenticatableContract $user)
{
$user->setRememberToken($token = Str::random(25));
$this->provider->updateRememberToken($user, $token);
}
}

Symfony 2 / Doctrine Not Saving Any Zeros in varchar field

UPDATE
As asked for,
$NewUser = new Users();
$Form = $this->createForm(new UserType(), $NewUser, [])
->add('save', 'submit', ['label' => 'Save',
'attr' => ['class' => 'SaveButton ftLeft'],
]);
$Form->handleRequest($request);
if ($Form->isValid()) {
/*
Sometimes add more data to the entity.....
*/
$em = $this->getDoctrine()->getManager();
$em->persist( $NewUser );
$em->flush();
}
$FormRender = $Form->createView();
return $this->render('xxxxBundle:Users/add.html.twig',
['AddUser' => $FormRender]);
Sometimes I will add extra to the entity, on fields being set within the php code, e.g. account sign up date, but in most cases just save the entity with the form data.
Very simple issue, I have a new (ish) system and have notice that when trying to save zeros, for anything, phone number inputs, it does not save any zeros?
I am using YMAL files to control my doctrine ORM, here is how I have set it up within my User table,
mobileNumber:
type: string
nullable: false
length: 50
options:
fixed: false
column: mobile_number
This does save/make the field has a varchar, and thought nothing about it until I did a random test and saw it was not saving any leading zeros?
I know you can not save leading zeros in a int field type, but this is a varchar. Also when I go into the database, and manually add a zero to that input, its fine, so I take its not the database. Something to do with how I get doctrine to save the data?
If so how do I change that? I have just been saving the data with a standard persist() and flush() commands? Not sure why it would not save the zeros? I was thinking that I had to change the YMAL type to something like phone? I have been over the docs, can not see it.
All help most welcome..
Thanks.
The reason is in your comment:
User form type has the mobile number set to 'number' input.
This value is being casted to int by the Form component. Change the field type to regular string.
If you want to validate value to be only digits, use Validation component

Cakephp 3: Modifying Results from the database

In my database there is a content table and when fetching data from this table I would like to append field url to the results, which is based on slug field which is contained in the table. Anyway, I have seen a way to do this in the previous versions of cakephp using behavior for the model of this table and then modifying results in afterFind callback in the behavior class. But in version 3 there is no afterFind callback, and they recommend using mapReduce() method instead in the manual, but this method is poorly explained in the manual and I cant figure out how to achieve this using mapReduce().
After little bit of research I realized that the best way to append the url field field to find results is using formatResults method, So this is what I did in my finders:
$query->formatResults(function (\Cake\Datasource\ResultSetInterface $results) {
return $results->map(function ($row) {
$row['url'] = array(
'controller' => 'content',
'action' => 'view',
$row['slug'],
$row['content_type']['alias']
);
return $row;
});
});

Yii2: Prevent empty string in attribute of ActiverRecord

What's the best way to prevent that an empty string gets inserted into a field of an MySQL's InnoDB table? Allowed values are strings with more than zero characters or NULL.
I'm asking that because ActiveRecord model objects often get loaded with view's form data which don't know and thus don't send NULL values. In such a case I'd prefer that a NULL gets stored instead of the empty string.
Should I define a rule? Should I implement a setter? Use a trigger?
You should simply use the default validator, add this rule to your model :
public function rules()
{
return [
// ...
['attribute', 'default', 'value' => null],
// ...
];
}