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

Commit

Permalink
Merge pull request #545 from igorsantos07/improved-pt-cherry-picked
Browse files Browse the repository at this point in the history
Improving pt_BR Providers
  • Loading branch information
fzaninotto committed May 19, 2015
2 parents 6ce684d + 6aeea1f commit 0ae75f0
Show file tree
Hide file tree
Showing 7 changed files with 314 additions and 24 deletions.
38 changes: 38 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,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

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.
* @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);
}
}
33 changes: 33 additions & 0 deletions test/Faker/Provider/pt_BR/PersonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?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);
$this->assertRegExp('/\d{8}\d/', $rg);
$rg = $this->faker->rg(true);
$this->assertRegExp('/\d{2}\.\d{3}\.\d{3}-[0-9X]/', $rg);
}
}

0 comments on commit 0ae75f0

Please sign in to comment.