Prepare una funcion para el lado del cliente, esta comprueba los dos primeros digitos el tercero y el digito verificador, el codigo es el siguiente:
codigo javascript:
var EventMethod = (typeof attachEvent === 'undefined' ? 'addEventListener' : 'attachEvent');
Element.prototype.onEvent = function(event, callback, args)
{
if(typeof callback === 'object')
for(var x in callback)
this.onEvent(event, callback[x], args[x]);
else
this[EventMethod]((EventMethod == 'attachEvent' ? 'on' : '') + event, function(){
callback.apply(null, args);
});
};
function validate_ci(input, callback)
{
var value = input.value,
digits = [],
digits_count = 0,
verify_digit = null,
last_digit = null,
result = function()
{
callback.apply(input, arguments);
return false;
};
if(value.match(/([0-9]{9})\-([0-9])/) !== null)
value = value.replace('-', '');
// verificamos la longitud
if(value.length < 10)
return result(null, 'ingresa 10 digitos');
// revizamos el codigo de la provincia
if(parseInt(value.substr(0, 2)) > 24)
return result(false, 'cedula incorrecta.');
// revizamos el 3er digito
if(parseInt(value.substr(2, 1)) > 6)
return result(false, 'cedula incorrecta.');
// definimos como un arreglo los digitos
digits = value.split('');
// obtenemos el ultimo digito
last_digit = digits[digits.length-1];
digits.pop(); // extraemos el ultimo digito ( digito verificador ) de los digitos
// recorremos los digitos
for(var x in digits)
{
var digit = digits[x], // definimos el digito
total = digit * ((parseInt(x) + 1) % 2 == 0 ? 1 : 2); // usamos el algoritmo de Lhun
// si la multiplicacion es mayor a 9 sumamos entre digitos
if( total > 9 )
{
var two_digits = total.toLocaleString().split('');
total = parseInt(two_digits[0]) + parseInt(two_digits[1]);
}
digits_count += total;
}
// usamos el modulo 10
verify_digit = 10 - (digits_count % 10);
// digito verificador erroneo
if(verify_digit !== parseInt(last_digit))
return result(false, 'cedula incorrecta.');
return result(true, null, last_digit);
}
(function(){
console.log('ea?');
var ci_input = document.getElementById('ci');
ci_input.onEvent('keyup', validate_ci, [ci_input, function(is_valid, msg, last_digit){
var input_class = (is_valid === null ? '' : (is_valid ? 'correct' : 'error')),
input_classes = this.className.split(' '),
info_classes = [
input_classes.indexOf('correct'),
input_classes.indexOf('error')
];
for(var x in info_classes)
{
if(info_classes[x] > 0)
input_classes.splice(info_classes[x], 1);
}
input_classes.push(input_class);
this.className = input_classes.join(' ');
}]);
})();
El html:
<form method="POST" action="">
<div class="field">
<label for="ci">Cedula de identidad:</label>
<input class="input-text" id="ci" name="ci" placeholder="000000000-0">
</div>
</form>
esto comprueba tanto para el formato xxxxxxxxx-x
que para xxxxxxxxxx
la funcion funciona asi:
validate_ci(input, callback)
input
: toma el elemento con el campo de la cedula,
callback
: regresa una funcion con argumentos (is_valid, msg, last_digit);
donde solo tendrias que hacer esto:
var validar = validate_ci(input, function(is_valid, msg, last_digit){
// is valid => regresa true o false dependiendo si valido o no
// msg es el error que presenta la validacion
// last_digit es el ultimo digito verificador
});
if( !validar )
{
// si no valido hacemos alguna accion.
}
DEMO:
http://jsfiddle.net/9vq2eaq5/1/embedded/result/
http://jsfiddle.net/9vq2eaq5/1/
Si lo que buscas es validarlo del lado del servidor, no conozco muy bien cakephp pero viendo la documentacion, seria de agregar un validador personalizado, basandome en eso te dejo el siguiente código, no esta probado pero debería funcionar:
http://book.cakephp.org/2.0/en/models/data-validation.html
class Post extends AppModel {
public $validate = array(
'cedula' => array(
'rule' => 'check_ci',
'message' => 'La cedula es incorrecta.'
)
);
public function check_ci($check) {
$value = array_values($check);
$value = $value[0];
if(preg_match('~[0-9]{9}\-[0-9]~', $value))
$value = str_replace('-', '', $value);
if(intval(substr($value, 0, 2)) > 24)
return false;
if(intval(substr($value, 2, 1)) > 6)
return false;
$count_digits = 0;
$digits = str_split($value);
$last_digit = $digits[count($digits)-1];
array_pop($digits);
foreach($digits as $pos => $digit)
{
$total = $digit * (($pos + 1) % 2 == 0 ? 1 : 2);
if($total > 9)
{
$pair_digits = str_split(strval($total));
$total = intval($pair_digits[0]) + intval($pair_digits[1]);
}
$count_digits += $total;
}
$verify_digit = 10 - ($count_digits % 10);
if($verify_digit !== intval($last_digit))
return false;
return true;
}
}