Skip to content
This repository has been archived by the owner on Dec 11, 2020. It is now read-only.

Improving pt_BR Providers #545

Merged
merged 18 commits into from
May 19, 2015
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,44 @@ echo $faker->taxpayerIdentificationNumber; // '165249277'

```

### `Faker\Provider\pt_BR\PhoneNumber`

```php
<?php

echo $faker->areaCode; // 21
echo $faker->cellphone; // 9432-5656
echo $faker->landline; // 2654-3445
echo $faker->phone; // random landline, 8-digit or 9-digit cellphone number

// Using the phone functions with a false argument returns unformatted numbers
echo $faker->cellphone(false); // 74336667

// cellphone() has a special second argument to add the 9th digit. Ignored if generated a Radio number
echo $faker->cellphone(true, true); // 98983-3945 or 7343-1290

// Using the "Number" suffix adds area code to the phone
echo $faker->cellphoneNumber; // (11) 98309-2935
echo $faker->landlineNumber(false); // 3522835934
echo $faker->phoneNumber; // formatted, random landline or cellphone (obbeying the 9th digit rule)
echo $faker->phoneNumberCleared; // not formatted, random landline or cellphone (obbeying the 9th digit rule)
```

### `Faker\Provider\pt_BR\Person`

```php
<?php

// The name generator may include double first or double last names, plus title and suffix
echo $faker->name; // 'Sr. Luis Adriano Sepúlveda Filho'

// Valid document generators have a boolean argument to remove formatting
echo $faker->cpf; // '145.343.345-76'
echo $faker->cpf(false); // '45623467866'
echo $faker->rg; // '84.405.736-3'
echo $faker->cnpj; // '23.663.478/0001-24'
```

### `Faker\Provider\ro_RO\Person`

```php
Expand Down
17 changes: 17 additions & 0 deletions src/Faker/Provider/pt_BR/Company.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Faker\Provider\pt_BR;

require_once "check_digit.php";

class Company extends \Faker\Provider\Company
{
protected static $formats = array(
Expand All @@ -13,4 +15,19 @@ class Company extends \Faker\Provider\Company
);

protected static $companySuffix = array('e Filho', 'e Filha', 'e Filhos', 'e Associados', 'e Flia.', 'SRL', 'SA', 'S. de H.');

/**
* A random CNPJ number.
* @link http://en.wikipedia.org/wiki/CNPJ
* @param bool $formatted If the number should have dots/slashes/dashes or not.
* @return string
*/
public function cnpj($formatted = true)
{
$n = $this->generator->numerify('########0001');
$n .= check_digit($n);
$n .= check_digit($n);

return $formatted? vsprintf('%d%d.%d%d%d.%d%d%d/%d%d%d%d-%d%d', str_split($n)) : $n;
}
}
33 changes: 32 additions & 1 deletion src/Faker/Provider/pt_BR/Person.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Faker\Provider\pt_BR;

require_once "check_digit.php";

class Person extends \Faker\Provider\Person
{
protected static $maleNameFormats = array(
Expand Down Expand Up @@ -90,7 +92,7 @@ class Person extends \Faker\Provider\Person

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file permissions have changed, please revert to 644.

protected static $titleFemale = array('Sra.', 'Srta.', 'Dr.',);

private static $suffix = array('Filho', 'Neto', 'Sobrinho', 'Jr.');
protected static $suffix = array('Filho', 'Neto', 'Sobrinho', 'Jr.');

/**
* @example 'Jr.'
Expand All @@ -99,4 +101,33 @@ public static function suffix()
{
return static::randomElement(static::$suffix);
}

/**
* A random CPF number.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you link to a definition of the format, e.g. in Wikipedia? Same for cnpj.

* @link http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
* @param bool $formatted If the number should have dots/dashes or not.
* @return string
*/
public function cpf($formatted = true)
{
$n = $this->generator->numerify('#########');
$n .= check_digit($n);
$n .= check_digit($n);

return $formatted? vsprintf('%d%d%d.%d%d%d.%d%d%d-%d%d', str_split($n)) : $n;
}

/**
* A random RG number, following Sao Paulo state's rules.
* @link http://pt.wikipedia.org/wiki/C%C3%A9dula_de_identidade
* @param bool $formatted If the number should have dots/dashes or not.
* @return string
*/
public function rg($formatted = true)
{
$n = $this->generator->numerify('########');
$n .= check_digit($n);

return $formatted? vsprintf('%d%d.%d%d%d.%d%d%d-%s', str_split($n)) : $n;
}
}
157 changes: 134 additions & 23 deletions src/Faker/Provider/pt_BR/PhoneNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,139 @@

class PhoneNumber extends \Faker\Provider\PhoneNumber
{
protected static $formats = array(
'+## (##) #### - ####',
'+## (##) 9#### - ####',
'(##) #### - ####',
'(##) ##### - ####',
'+##(##) ####-####',
'+##(##) 9####-####',
'(##) ####-####',
'(##) 9####-####',
'+##(##) #### - ####',
'+##(##) 9#### - ####',
'(##)#### - ####',
'(##)##### - ####',
'+##(##)####-####',
'+##(##)9####-####',
'(##)####-####',
'(##)9####-####',
'#### - ####',
'9#### - ####',
'####-####',
'9####-####',
'## #### ####',
'## 9#### ####',

protected static $landlineFormats = array('2###-####', '3###-####');

protected static $cellphoneFormats = array('7###-####', '8###-####', '9###-####');

/**
* Extracted from http://portal.embratel.com.br/embratel/9-digito/ (point 11)
*/
protected static $ninthDigitAreaCodes = array(
11, 12, 13, 14, 15, 16, 17, 18, 19,
21, 22, 24, 27, 28,
91, 92, 93, 94, 95, 96, 97, 98, 99,
//31, 32, 33, 34, 35, 37, 38, 71, 73, 74, 75, 77, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, //by dec/2015
//41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 53, 54, 55, 61,62, 63, 64, 65, 66, 67, 68, 69 //by dec/2016
);

/**
* Generates a 2-digit area code not composed by zeroes.
* @return string
*/
public static function areaCode()
{
return static::randomDigitNotNull().static::randomDigitNotNull();
}

/**
* Generates a 8/9-digit cellphone number without formatting characters.
* @param bool $formatted [def: true] If it should return a formatted number or not.
* @param bool $ninth [def: false] If the number should have a nine in the beginning or not.
* If the generated number begins with 7 this is ignored.
* @return string
*/
public static function cellphone($formatted = true, $ninth = false)
{
$number = static::numerify(static::randomElement(static::$cellphoneFormats));

if ($ninth && $number[0] != 7) {
$number = "9$number";
}

if (!$formatted) {
$number = strtr($number, array('-' => ''));
}

return $number;
}

/**
* Generates an 8-digit landline number without formatting characters.
* @param bool $formatted [def: true] If it should return a formatted number or not.
* @return string
*/
public static function landline($formatted = true)
{
$number = static::numerify(static::randomElement(static::$landlineFormats));

if (!$formatted) {
$number = strtr($number, array('-' => ''));
}

return $number;
}

/**
* Randomizes between cellphone and landline numbers.
* @param bool $formatted [def: true] If it should return a formatted number or not.
* @return mixed
*/
public static function phone($formatted = true)
{
$options = static::randomElement(array(
array('cellphone', false),
array('cellphone', true),
array('landline', null),
));

return call_user_func("static::{$options[0]}", $formatted, $options[1]);
}

/**
* Generates a complete phone number.
* @param string $type [def: landline] One of "landline" or "cellphone". Defaults to "landline" on invalid values.
* @param bool $formatted [def: true] If the number should be formatted or not.
* @return string
*/
protected static function anyPhoneNumber($type, $formatted = true)
{
$area = static::areaCode();
$number = ($type == 'cellphone')?
static::cellphone($formatted, in_array($area, static::$ninthDigitAreaCodes)) :
static::landline($formatted);

return $formatted? "($area) $number" : $area.$number;
}

/**
* Concatenates {@link areaCode} and {@link cellphone} into a national cellphone number. The ninth digit is
* derived from the area code.
* @param bool $formatted [def: true] If it should return a formatted number or not.
* @return string
*/
public static function cellphoneNumber($formatted = true)
{
return static::anyPhoneNumber('cellphone', $formatted);
}

/**
* Concatenates {@link areaCode} and {@link landline} into a national landline number.
* @param bool $formatted [def: true] If it should return a formatted number or not.
* @return string
*/
public static function landlineNumber($formatted = true)
{
return static::anyPhoneNumber('landline', $formatted);
}

/**
* Randomizes between complete cellphone and landline numbers.
* @return mixed
*/
public static function phoneNumber()
{
$method = static::randomElement(array('cellphoneNumber', 'landlineNumber'));
return call_user_func("static::$method", true);
}

/**
* Randomizes between complete cellphone and landline numbers, cleared from formatting symbols.
* @return mixed
*/
public static function phoneNumberCleared()
{
$method = static::randomElement(array('cellphoneNumber', 'landlineNumber'));
return call_user_func("static::$method", false);
}
}
35 changes: 35 additions & 0 deletions src/Faker/Provider/pt_BR/check_digit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Faker\Provider\pt_BR;

/**
* Calculates one MOD 11 check digit based on customary Brazilian algorithms.
* @link http://en.wikipedia.org/wiki/Check_digit
* @link http://pt.wikipedia.org/wiki/CNPJ#Algoritmo_de_Valida.C3.A7.C3.A3o
* @link http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas#Validation
*
* @param string|integer $numbers Numbers on which generate the check digit
* @return integer
*/
function check_digit($numbers)
{
$length = strlen($numbers);
$second_algorithm = $length >= 12;
$verifier = 0;

for ($i = 1; $i <= $length; $i++) {
if (!$second_algorithm) {
$multiplier = $i+1;
} else {
$multiplier = ($i >= 9)? $i-7 : $i+1;
}
$verifier += $numbers[$length-$i] * $multiplier;
}

$verifier = 11 - ($verifier % 11);
if ($verifier >= 10) {
$verifier = 0;
}

return $verifier;
}
25 changes: 25 additions & 0 deletions test/Faker/Provider/pt_BR/CompanyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Faker\Test\Provider\pt_BR;

use Faker\Generator;
use Faker\Provider\pt_BR\Company;

class CompanyTest extends \PHPUnit_Framework_TestCase
{

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Company($faker));
$this->faker = $faker;
}

public function testCnpjFormatIsValid()
{
$cnpj = $this->faker->cnpj(false);
$this->assertRegExp('/\d{8}\d{4}\d{2}/', $cnpj);
$cnpj = $this->faker->cnpj(true);
$this->assertRegExp('/\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}/', $cnpj);
}
}
35 changes: 35 additions & 0 deletions test/Faker/Provider/pt_BR/PersonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Faker\Test\Provider\pt_BR;

use Faker\Generator;
use Faker\Provider\pt_BR\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testCpfFormatIsValid()
{
$cpf = $this->faker->cpf(false);
$this->assertRegExp('/\d{9}\d{2}/', $cpf);
$cpf = $this->faker->cpf(true);
$this->assertRegExp('/\d{3}\.\d{3}\.\d{3}-\d{2}/', $cpf);
}

public function testRgFormatIsValid()
{
$rg = $this->faker->rg(false);
echo $rg."\n";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove

$this->assertRegExp('/\d{8}\d/', $rg);
$rg = $this->faker->rg(true);
echo $rg."\n";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove

$this->assertRegExp('/\d{2}\.\d{3}\.\d{3}-[0-9X]/', $rg);
}
}