Completed
Push — master ( 9de2ae...02afd8 )
by Ronan
06:45
created

Insee::validate()   D

Complexity

Conditions 14
Paths 55

Size

Total Lines 93
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 2 Features 0
Metric Value
c 4
b 2
f 0
dl 0
loc 93
rs 4.9516
cc 14
eloc 45
nc 55
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace IsoCodes;
4
5
/**
6
 * Class Insee.
7
 */
8
class Insee implements IsoCodeInterface
9
{
10
    /**
11
     * Vérifie le numéro de sécurité sociale. S'il est valide, renvoit true (ou mieux : un tableau des infos)
12
     * sinon renvoie FALSE.
13
     *
14
     * @param string $numero
15
     *
16
     * @author Webu (Dylann Cordel <[email protected]>) corrigé par Ronan
17
     *
18
     * @link   http://www.developpez.net/forums/d677820/php/langage/regex/verification-numero-securite-sociale/
19
     *
20
     * @return bool ou mieux mixed array avec les infos récupérées du num de sécu ou FALSE
21
     */
22
    public static function validate($numero)
23
    {
24
        //Expression de base d'Antoun et SNAFU (http://www.developpez.net/forums/d677820/php/langage/regex/verification-numero-securite-sociale/#post3969560),
25
        //mais corigée par mes soins pour respecter plus scrupuleusement le format
26
        $regexp = '/^                                           # début de chaîne
27
            (?<sexe>[1278])                                             # 1 et 7 pour les hommes ou 2 et 8 pour les femmes
28
            (?<annee>[0-9]{2})                                          # année de naissance
29
            (?<mois>0[1-9]|1[0-2]|20)                                   # mois de naissance (si >= 20, c\'est qu\'on ne connaissait pas le mois de naissance de la personne
30
                    (?<departement>[02][1-9]|2[AB]|[1345678][0-9]|9[012345789]) # le département : 01 à 19, 2A ou 2B, 21 à 95, 99 (attention, cas particulier hors métro traité hors expreg)
31
                    (?<numcommune>[0-9]{3})                                     # numéro d\'ordre de la commune (attention car particuler pour hors métro  traité hors expression régulière)
32
                    (?<numacte>00[1-9]|0[1-9][0-9]|[1-9][0-9]{2})               # numéro d\'ordre d\'acte de naissance dans le mois et la commune ou pays
33
                    (?<clef>0[1-9]|[1-8][1-9]|9[1-7])?                          # numéro de contrôle (facultatif)
34
                    $                                                           # fin de chaîne
35
                    /x';
36
        //références : http://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France#Signification_des_chiffres_du_NIR
37
38
        if (!preg_match($regexp, $numero, $match)) {
39
            return false;
40
        }
41
        /* attention à l'overflow de php :)
42
           i.e :
43
           $test = '1850760057018' ;
44
           $clef = 97 - (substr($test, 0, 13) % 97) ;
45
        // => clef = 32 car l'opérande "%" travaille avec des entiers, et sur une archi 32 bits, 1850760057018 est transformé en 2147483647 ^_^
46
        $clef = 97 - fmod(substr($test, 0, 13), 97) ;
47
        // => clef = 18 (la valeur correcte, car fmod travaille avec des flottants)
48
         */
49
50
        $return = array(
51
            'sexe' => $match['sexe'], //7,8 => homme et femme ayant un num de sécu temporaire
52
            'annee' => $match['annee'], //année de naissance + ou - un siècle uhuh
53
            'mois' => $match['mois'], //20 = inconnu
54
            'departement' => $match['departement'], //99 = étranger
55
            'numcommune' => $match['numcommune'], //990 = inconnu
56
            'numacte' => $match['numacte'], //001 à 999
57
            'clef' => isset($match['clef']) ? $match['clef'] : null, //00 à 97
58
            'pays' => 'fra', //par défaut, on change que pour le cas spécifique
59
        );
60
61
        //base du calcul par défaut pour la clef (est modifié pour la corse)
62
        $aChecker = floatval(substr($numero, 0, 13));
63
64
        /*Traitement des cas des personnes nées hors métropole ou en corse*/
65
        switch (true) {
66
            //départements corses. Le calcul de la cles est différent
67
            case $return['departement'] == '2A':
68
                $aChecker = floatval(str_replace('A', 0, substr($numero, 0, 13)));
69
                $aChecker -= 1000000;
70
                break;
71
72
            case $return['departement'] == '2B':
73
                $aChecker = floatval(str_replace('B', 1, substr($numero, 0, 13)));
74
                $aChecker -= 2000000;
75
                break;
76
77
            case $return['departement'] == 97 || $return['departement'] == 98:
78
                $return['departement'] .= substr($return['numcommun'], 0, 1);
79
                $return['numcommun'] = substr($return['numcommun'], 1, 2);
80
                if ($return['numcommun'] > 90) {
81
                    //90 = commune inconnue
82
                    return false;
83
                }
84
                break;
85
86
            case $return['departement'] == 99:
87
                $return['pays'] = $match['numcommune'];
88
                if ($return['numcommun'] > 990) {
89
                    //990 = pays inconnu
90
                    return false;
91
                }
92
                break;
93
94
            default:
95
                if (isset($return['numcommun'])) {
96
                    if ($return['numcommun'] > 990) {
97
                        //990 = commune inconnue
98
                        return false;
99
                    }
100
                }
101
                break;
102
        }
103
104
        $clef = 97 - fmod($aChecker, 97);
105
106
        if (empty($return['clef'])) {
107
            $return['clef'] = $clef; //la clef est optionnelle, si elle n'est pas spécifiée, le numéro est valide, mais on rajoute la clef
108
        }
109
        if ($clef != $return['clef']) {
110
            return false;
111
        }
112
113
        return true;
114
    }
115
}
116