How to generate mobile phone number with Faker - php

I'm using Laravel 9 and I want to make a faker for my users table:
public function definition()
{
return [
'usr_first_name' => fake()->name(),
'usr_last_name' => fake()->name(),
'usr_user_name' => fake()->unique()->name(),
'usr_mobile_phone' => , // generates a unique phone number
'usr_password_hash' => Hash::make('123456'),
'usr_email_address' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'usr_is_superuser' => now(),
'usr_is_active' => 1,
'usr_str' => Str::random(10),
'remember_token' => Str::random(10),
];
}
So as you can see for the column usr_mobile_phone, I need to add a unique mobile number which has 11th character length.
But I don't know what is the command for doing that in faker!
So if you know, please let me know, thanks in advance.

You can use the fake()->e164PhoneNumber() method to get a phone number (E164 format) with the plus sign and country code, based on the app locale which you can customise.
Now to get unique phone number we can combine the use of unique() method: fake()->unique()
This should get you unique phone number:
fake()->unique()->e164PhoneNumber()
Example output: +14809888523, +12705838722, +13869134701
...now as per your requirement of 11 digit length, you can replace the plus sign:
'usr_mobile_phone' => str_replace('+', '', fake()->unique()->e164PhoneNumber())
Please note that different countries have different country code length, resulting in different phone number length output which you need to take care of yourself.
Alternatively, you can use the fake()->numerify() method to generate dynamic format number by passing the the format to the method or by default format ###:
fake()->unique()->numerfiy('##########');
Example output: 0733375159, 8270962398, 5125950018
...and then join the country code:
'usr_mobile_phone' => '1' . fake()->unique()->numerfiy('##########')

Related

How to make Laravel unique validation work on an input array?

UpdateEntityRequest.php:
'phones' => 'sometimes|nullable|array',
'phones.*.id' => 'sometimes|required|integer|distinct|exists:entity_phones,id,entity_id,'.$this->id,
'phones.*.number' => 'required|alpha_num|max:255|distinct|unique:entity_phones,number,'.$this->id.',entity_id',
entity_phones table:
id, number, entity_id.
unique constraint: (number, entity_id)
EntityRepository.php:
foreach ($attributes['phones'] as $phone) {
if (isset($phone['id'])) {
$entity->phones()->updateOrCreate([
'id' => $phone['id'],
'entity_id' => $entity->id
], $phone);
} else {
$entity->phones()->create($phone);
}
}
My entity can have more than phone associated, but not a repeated number. My intention is to check the unique (entity_id, number) in the UpdateEntityRequest.php so:
If the phone object comes without an id, it should check that the combination of number, entity_id doesn't exists. But the number can exist with other entity_id.
If the request comes with an id, it should check that the combination of number, entity_id doesn't exists only in other ids, but ignore the given id.
I'm having trouble witht the Laravel Unique rule validating only when i want it to make the validation. Any ideas how could I make this solution would be appreciated.
If you need to ignore a given ID during the unique check try using the Rule class to fluently define the rule.
use Illuminate\Validation\Rule;
Validator::make($request_data, [
'number' => [
'required',
'alpha_num', (...all your other rules)
Rule::unique('entity_phones')->ignore($entity_id),
],
]);
You can read more in laravel docs about unique rule in paragraph: Forcing A Unique Rule To Ignore A Given ID.
I ended up doing this:
$phoneIds = $this->input('phones.*.id');
'phones.*.number' =>
[
'required_with:phones',
'alpha_num',
'max:255',
'distinct',
Rule::unique('entity_phones', 'number')
->where('entity_id', $this->id)
->where(function ($query) use ($phoneIds) {
return $query->where('id', '!=', array_shift($phoneIds));
})
],

How to add a "pipe" into a get parameter during guzzle query building

I'm using an api that has a "range" parameter that can apply to several different parameter items. The range i'm focusing on is "price". I'm using guzzle in laravel and according to the api documentation, the query for this particular parameter should be written like this "&range_facet=price|500|2500|250"...this is broken down into the minimum, maximum, and interval values of the price range parameter. That's not necessarily important to this question. When i try and run this query as is, i get nothing returned. When I remove that particular parameter, i get values but obviously they're not filtered the way i want them to be. When i run this in Insomnia, the pipes are replaced by "%7C", which is obviously (obviously?) not interpreted by the api as it's not how it's waiting for the GET request to be made. How can I insert the pipes into the query so that it calls the correct way?
I've tried to create an additional nested array with the price value being broken up into key value pairs but that didn't work either.
'range_facets' => ['price'['start'=>'500', end=>'2500', 'interval'=>'250']],
$client = new Client();
$result = $client->request('GET', "http://api.example.com", [
'headers' => [
'Host' => 'example-host',
'Content-Type' => 'application/json'
],
'query' => [
'api_key' => 'my_api_key',
'range_facets' => 'price|500|2500|250',
'year' => $year,
'latitude' => '30.170222',
'longitude' => '92.01320199',
'radius' => 500,
'start' => 0,
'rows' => 50
]
]);
I'd like to filter my prices but I need the pipe to be able to do it.
This is exactly how it should be. %7C should be decoded on the server side to | automatically (about query string encoding).
I bet the issue is in different place.

Odoo PHP API and Laradoo - how to save many2many many2one and selection fields

Could someone please provide a simple example of the usage for dealing with Odoo's one2many, many2many and selection fields when using Laradoo (or ripcord)?
Specifically how one would use them with create() and update(). In Python, it seems as if these are dealt with using special tuple commands however for PHP documentation seems very hard to find for these types of things and it would be extremely helpful.
For illustrative purposes in my particular project, I haven't been able to figure out how to relate a CRM lead tag to a lead during the creation process using Laradoo:
$id = $odoo->create('crm.lead', [
'type' => 'lead',
'priority' => 0, <-- what do we pass here for this selection field?
'name' => 'Example',
'contact_name' => 'John Doe',
'phone' => '555-555-5555',
'email_from' => 'example#domain.com',
'description' => 'Just some text.',
'tag_ids' => [1], <-- What do we pass here for this one2many field?
]);
In the example above when trying to set the priority selection field to an int other than 0 fails and when trying to pass an array of tag_ids (1 is valid tag id in my project), the lead remains untagged.
First of all selection field values are just string values that need to be part of the field defined selection values.
The values for relational fields like Onetomany and Many2many are ruled by the command formated values that you could read at:
https://github.com/odoo/odoo/blob/11.0/odoo/models.py#L3020-L3055
For the php api usage with ripcord you could set the tag_ids field value like:
$id = $odoo->create('crm.lead', [
'type' => 'lead',
'priority' => '0',
'name' => 'Example',
'contact_name' => 'John Doe',
'phone' => '555-555-5555',
'email_from' => 'example#domain.com',
'description' => 'Just some text.',
'tag_ids' => array(array(4,1)),
]);
This translate as that 1 is the id of a known and already existing crm.lead.tag that you could link to the m2m tag_ids field using the command 4. This could also be expressed using command 6 to link multiple ids on the same command value:
'tag_ids' => array(array(6,0,array(1,2,3))),
where using command 4 it will be:
'tag_ids' => array(array(4,1), array(4,2), array(4,3)),

Laravel 5.6 - how to create a model factory with a vertical table?

I am working on application that is made up of Leads, each Lead -> hasMany -> Fields. My application will accept an infinite amount of whitelisted fields. Some Leads will have a lot of Fields, others will have maybe around 5. Due to this, I've opted for the Field table to be vertical, rather than fit in all the fields I accept horizontally, and then run into MySQL errors down the line (table too wide, etc.)
Here's my structure:
Lead Table
id
...
Field Table:
id
lead_id
field_name
field_value
I have created a model factory for my Lead model, that automatically creates 5 random fields using Faker.
I have an array of texts, numbers, dates (etc) fields which my application accepts.
Field Factory:
...
$texts = config('fields.whitelist.text');
foreach ($texts as $text) {
$fields[$text] = $faker->sentence();
}
...
$randomField = array_random(array_keys($fields));
return [
'field_name' => $randomField,
'field_value' => $fields[$randomField],
];
I've been doing this:
$lead = factory(Lead::class)->create()
->each(function ($l) {
$l->fields()->save(factory(Field::class, 5)->make());
});
However, I now have a minimum array of Fields which each Lead must have. I have these minimum fields in another config.
Is it possible to automatically create the x minimum Fields on the vertical table, using a factory?
E.g.
Minimum Fields
first_name
date_of_birth
How can I write a factory to automatically create the following structure:
[
'field_name' => 'first_name',
'field_value' => '<random name>',
],
[
'field_name' => 'date_of_birth',
'field_value' => '<random date>',
],
Edit: and if possible, not insert duplicate field_name values. Not like it's 100% deal breaker, but I want to make sure I 100% know what data I am working with, so checking x number of duplicates I imagine would be a nightmare
If you want each Lead to have those minimum fields, then add those fields to your each() closure. Like this:
$lead = factory(Lead::class)->create()->each(function ($lead) {
$lead->fields()->createMany([
'field_name' => 'first_name',
'field_value' => $faker->firstName,
],
[
'field_name' => 'date_of_birth',
'field_value' => $faker->dateTime(),
]);
$lead->fields()->save(factory(Field::class, 3)->make());
});
I changed the Field factory to 3 because there are 2 fields from the "minimum fields" that are inserted for every Lead.

Why AmazonDynamoDB::TYPE_STRING or NUMBER?

What are these constants defined in Amazon DynamoDB?
Can someone please explain the need of these constants?
Why are these placed in key of associative array?
I see a strange notation during putting items in table like
'Name' => array( AmazonDynamoDB::TYPE_STRING => 'Amazon S3')
PHP SDK guide says 4 type of constants.
TYPE_ARRAY_OF_NUMBERS
TYPE_ARRAY_OF_STRINGS
TYPE_NUMBER
TYPE_STRING
$dynamodb->batch($queue)->put_item(array(
'TableName' => 'Forum',
'Item' => array(
'Name' => array( AmazonDynamoDB::TYPE_STRING => 'Amazon S3'), // Hash Key
'Category' => array( AmazonDynamoDB::TYPE_STRING => 'Amazon Web Services'),
// Range Key
'Threads' => array( AmazonDynamoDB::TYPE_NUMBER => '0')
)
));
These constants reflect the four available Amazon DynamoDB Data Types:
String - Strings are Unicode with UTF8 binary encoding. There is no limit to the string size when you assign it to an attribute except
when the attribute is part of the primary key. [...]
Number - Numbers are positive or negative exact-value decimals and integers. A number can have up to 38 digits of precision after the
decimal point, and can be between 10^-128 to 10^+126. The
representation in Amazon DynamoDB is of variable length. [...]
String and Number Sets - Amazon DynamoDB also supports both Number Sets and String Sets.
[...] Note that, because it is a
set, the values in the set must be unique. String Sets and Number Sets
are not ordered; the order of the values returned in a set is not
preserved.
You will need to specify or handle these data types in various API calls, e.g. for the KeySchema in CreateTable or the Item in PutItem as seen in the example you provided.
The newest version of the AWS PHP SDK adds convenience methods to help make formatting your request easier. See the docs for the attributes() method. For example:
$dynamodb->put_item(array(
'TableName' => 'my-table',
'Item' => $dynamodb->attributes(array(
'id' => 1,
'key1' => 'value1',
'key2' => 'value2',
))
));
Seems much easier to work with this way.

Categories