br_tax_number_fields.module in Brazilian IDs 7
Adds Brazilian Tax Number field widgets to text field type at the Field UI and creates new form element types for use in the Form API.
File
br_tax_number_fields.moduleView source
<?php
/**
* @file
* Adds Brazilian Tax Number field widgets to text field type at the Field UI
* and creates new form element types for use in the Form API.
*/
/**
* Implements hook_field_display_alter().
*/
function br_tax_number_fields_field_display_alter(&$display, $context) {
if ($context['instance']['widget']['module'] == 'br_tax_number_fields') {
$display['type'] = $context['instance']['widget']['type'];
// Change from text module to br_tax_number_fields so
// br_tax_number_fields_field_formatter_view is called.
$display['module'] = 'br_tax_number_fields';
}
}
/**
* Implements hook_field_formatter_view().
*/
function br_tax_number_fields_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
if (in_array($display['type'], array(
'number_cnpj',
'number_cpf',
'number_cnpj_cpf',
))) {
$markup = '';
foreach ($items as $delta => $item) {
$v = $item['value'];
if (strlen($item['value']) == 11) {
// This is a CPF.
$markup = sprintf('%s.%s.%s-%s', $v[0] . $v[1] . $v[2], $v[3] . $v[4] . $v[5], $v[6] . $v[7] . $v[8], $v[9] . $v[10]);
}
elseif (strlen($item['value']) == 14) {
// This is a CNPJ.
$v1 = $v[0] . $v[1];
$v2 = $v[2] . $v[3] . $v[4];
$v3 = $v[5] . $v[6] . $v[7];
$v4 = $v[8] . $v[9] . $v[10] . $v[11];
$v5 = $v[12] . $v[13];
$markup = sprintf('%s.%s.%s/%s-%s', $v1, $v2, $v3, $v4, $v5);
}
$element[$delta]['#markup'] = $markup;
}
}
return $element;
}
/**
* Implements hook_field_widget_info().
*/
function br_tax_number_fields_field_widget_info() {
return array(
'number_cnpj' => array(
'label' => t('CNPJ'),
'field types' => array(
'text',
),
),
'number_cpf' => array(
'label' => t('CPF'),
'field types' => array(
'text',
),
),
'number_cnpj_cpf' => array(
'label' => t('CNPJ / CPF'),
'field types' => array(
'text',
),
),
);
}
/**
* Implements hook_form_alter().
*
* Hide the unnecessary fields from settings page
*/
function br_tax_number_fields_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'field_ui_field_edit_form') {
if (in_array($form['#instance']['widget']['type'], array(
'number_cnpj',
'number_cpf',
'number_cnpj_cpf',
))) {
$form['instance']['settings']['text_processing']['#type'] = 'hidden';
$form['field']['settings']['max_length']['#type'] = 'hidden';
}
}
}
/**
* Implements hook_field_widget_form().
*/
function br_tax_number_fields_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$value = isset($items[$delta]['value']) ? $items[$delta]['value'] : '';
$maxlength = 18;
$size = 18;
switch ($instance['widget']['type']) {
case 'number_cnpj':
$callback_validate = 'br_tax_number_fields_cnpj_validate';
break;
case 'number_cpf':
$maxlength = 14;
$size = 14;
$callback_validate = 'br_tax_number_fields_cpf_validate';
break;
case 'number_cnpj_cpf':
$callback_validate = 'br_tax_number_fields_cnpj_cpf_validate';
break;
}
$element += array(
'#type' => 'textfield',
'#default_value' => $value,
'#maxlength' => $maxlength,
'#size' => $size,
'#element_validate' => array(
$callback_validate,
),
);
return array(
'value' => $element,
);
}
/**
* Validation callback.
*/
function br_tax_number_fields_cnpj_validate($element, &$form_state) {
$value = _br_tax_number_fields_is_number($element, $form_state['values']);
$cnpj_result = br_tax_number_cnpj_validator($value);
if (!$cnpj_result['status']) {
form_error($element, $cnpj_result['msg']);
}
}
/**
* Function to validate if value is a cnpj
* @param string $value
* @return array TRUE or FALSE and MSG error
*/
function br_tax_number_cnpj_validator($value) {
if (!empty($value)) {
$forbidden = array(
'00000000000000',
'11111111111111',
'22222222222222',
'33333333333333',
'44444444444444',
'55555555555555',
'66666666666666',
'77777777777777',
'88888888888888',
'99999999999999',
);
if (in_array($value, $forbidden)) {
return array(
'status' => FALSE,
'msg' => t('CNPJ field does not allow a sequence of the same number.'),
);
}
if (strlen($value) != 14) {
return array(
'status' => FALSE,
'msg' => t('CNPJ must have 14 digits.'),
);
}
else {
//@TODO - Translate variables to english
$cnpj = $value;
$k = 6;
$soma1 = 0;
$soma2 = 0;
for ($i = 0; $i < 13; $i++) {
$k = $k == 1 ? 9 : $k;
$soma2 += $cnpj[$i] * $k;
$k--;
if ($i < 12) {
if ($k == 1) {
$k = 9;
$soma1 += $cnpj[$i] * $k;
$k = 1;
}
else {
$soma1 += $cnpj[$i] * $k;
}
}
}
$digito1 = $soma1 % 11 < 2 ? 0 : 11 - $soma1 % 11;
$digito2 = $soma2 % 11 < 2 ? 0 : 11 - $soma2 % 11;
if ($cnpj[12] != $digito1 && $cnpj[13] != $digito2) {
return array(
'status' => FALSE,
'msg' => t('CNPJ number you have entered is invalid.'),
);
}
}
}
return array(
'status' => TRUE,
);
}
/**
* Validation callback.
*/
function br_tax_number_fields_cpf_validate($element, &$form_state) {
$value = _br_tax_number_fields_is_number($element, $form_state['values']);
$cpf_result = br_tax_number_cpf_validator($value);
if (!$cpf_result['status']) {
form_error($element, $cpf_result['msg']);
}
}
/**
* Function to validate if value is a cpf
* @param string $value
* @return array TRUE or FALSE and MSG error
*/
function br_tax_number_cpf_validator($value) {
if (!empty($value)) {
$forbidden = array(
'00000000000',
'11111111111',
'22222222222',
'33333333333',
'44444444444',
'55555555555',
'66666666666',
'77777777777',
'88888888888',
'99999999999',
);
if (in_array($value, $forbidden)) {
return array(
'status' => FALSE,
'msg' => t('CPF field does not allow a sequence of the same number.'),
);
}
if (strlen($value) != 11) {
return array(
'status' => FALSE,
'msg' => t('CPF must have 11 digits.'),
);
}
else {
// @TODO - Translate variables to english
$cpf_validar = substr($value, 0, 9);
$soma = 0;
$n = 11;
for ($i = 0; $i <= 9; $i++) {
$n = $n - 1;
$soma = $soma + substr($cpf_validar, $i, 1) * $n;
}
$resto = $soma % 11;
if ($resto < 2) {
$cpf_validar .= 0;
}
else {
$cpf_validar = $cpf_validar . (11 - $resto);
}
// Segunda parte da validação do CPF.
$soma = 0;
$n = 12;
for ($i = 0; $i <= 10; $i++) {
$n = $n - 1;
$soma = $soma + substr($cpf_validar, $i, 1) * $n;
}
$resto = $soma % 11;
if ($resto < 2) {
$cpf_validar .= 0;
}
else {
$cpf_validar = $cpf_validar . (11 - $resto);
}
if ($cpf_validar != $value) {
return array(
'status' => FALSE,
'msg' => t('CPF number you have entered is invalid.'),
);
}
}
}
return array(
'status' => TRUE,
);
}
/**
* Validation callback.
*/
function br_tax_number_fields_cnpj_cpf_validate($element, &$form_state) {
$value = _br_tax_number_fields_is_number($element, $form_state['values']);
if (!empty($value)) {
$length = strlen($value);
if (!in_array($length, array(
11,
14,
))) {
form_error($element, t('CPF / CNPJ field must have either 11 or 14 digits.'));
}
else {
if ($length == 11) {
br_tax_number_fields_cpf_validate($element, $form_state);
}
else {
br_tax_number_fields_cnpj_validate($element, $form_state);
}
}
}
}
/**
* Helper function for checking if the entered value contains only numbers.
*
* @param Array $element
* The form element array.
*
* @param Array $form_state_values
* The $form_state['values'] array.
*
* @return String
* The trimmed value entered by the user.
*/
function _br_tax_number_fields_is_number($element, &$form_state_values) {
$value = trim($element['#value']);
$value = str_replace(array(
'.',
'-',
'/',
), '', $value);
// The value of $depth_pointer will end up being, in most cases, something
// like: [group][field_name][un][0][value]
$depth_pointer = '';
foreach ($element['#parents'] as $parent) {
$depth_pointer .= "['{$parent}']";
}
// Set the clean value for $form_state[group][field_name][un][0][value]
// which will be saved into the database.
eval("\$form_state_values" . $depth_pointer . " = \$value;");
if (strlen($value) != strlen(preg_replace('/[^0-9]+/', '', $value))) {
form_error($element, t('%name must have only numbers.', array(
'%name' => $element['#title'],
)));
}
return $value;
}
/**
* Implements hook_field_widget_error().
*/
function br_tax_number_fields_field_widget_error($element, $error, $form, &$form_state) {
form_error($element['value'], $error['message']);
}
/**
* Implements hook_element_info().
*/
function br_tax_number_fields_element_info() {
$types['number_cpf'] = array(
'#input' => TRUE,
'#element_validate' => array(
'br_tax_number_fields_cpf_validate',
),
'#theme' => array(
'textfield',
),
'#autocomplete_path' => FALSE,
'#maxlength' => 14,
'#theme_wrappers' => array(
'form_element',
),
);
$types['number_cnpj'] = array(
'#input' => TRUE,
'#element_validate' => array(
'br_tax_number_fields_cnpj_validate',
),
'#theme' => array(
'textfield',
),
'#autocomplete_path' => FALSE,
'#maxlength' => 18,
'#theme_wrappers' => array(
'form_element',
),
);
$types['number_cnpj_cpf'] = array(
'#input' => TRUE,
'#element_validate' => array(
'br_tax_number_fields_cnpj_cpf_validate',
),
'#theme' => array(
'textfield',
),
'#autocomplete_path' => FALSE,
'#maxlength' => 18,
'#theme_wrappers' => array(
'form_element',
),
);
return $types;
}
Functions
Name | Description |
---|---|
br_tax_number_cnpj_validator | Function to validate if value is a cnpj |
br_tax_number_cpf_validator | Function to validate if value is a cpf |
br_tax_number_fields_cnpj_cpf_validate | Validation callback. |
br_tax_number_fields_cnpj_validate | Validation callback. |
br_tax_number_fields_cpf_validate | Validation callback. |
br_tax_number_fields_element_info | Implements hook_element_info(). |
br_tax_number_fields_field_display_alter | Implements hook_field_display_alter(). |
br_tax_number_fields_field_formatter_view | Implements hook_field_formatter_view(). |
br_tax_number_fields_field_widget_error | Implements hook_field_widget_error(). |
br_tax_number_fields_field_widget_form | Implements hook_field_widget_form(). |
br_tax_number_fields_field_widget_info | Implements hook_field_widget_info(). |
br_tax_number_fields_form_alter | Implements hook_form_alter(). |
_br_tax_number_fields_is_number | Helper function for checking if the entered value contains only numbers. |