Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like FirmaElectronica often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use FirmaElectronica, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
32 | class FirmaElectronica |
||
33 | { |
||
34 | |||
35 | private $config; ///< Configuración de la firma electrónica |
||
36 | private $certs; ///< Certificados digitales de la firma |
||
37 | private $data; ///< Datos del certificado digial |
||
38 | |||
39 | /** |
||
40 | * Constructor para la clase: crea configuración y carga certificado digital |
||
41 | * |
||
42 | * Si se desea pasar una configuración específica para la firma electrónica |
||
43 | * se debe hacer a través de un arreglo con los índices file y pass, donde |
||
44 | * file es la ruta hacia el archivo .p12 que contiene tanto la clave privada |
||
45 | * como la pública y pass es la contraseña para abrir dicho archivo. |
||
46 | * Ejemplo: |
||
47 | * |
||
48 | * \code{.php} |
||
49 | * $firma_config = ['file'=>'/ruta/al/certificado.p12', 'pass'=>'contraseña']; |
||
50 | * $firma = new \sasco\LibreDTE\FirmaElectronica($firma_config); |
||
51 | * \endcode |
||
52 | * |
||
53 | * También se permite que en vez de pasar la ruta al certificado p12 se pase |
||
54 | * el contenido del certificado, esto servirá por ejemplo si los datos del |
||
55 | * archivo están almacenados en una base de datos. Ejemplo: |
||
56 | * |
||
57 | * \code{.php} |
||
58 | * $firma_config = ['data'=>file_get_contents('/ruta/al/certificado.p12'), 'pass'=>'contraseña']; |
||
59 | * $firma = new \sasco\LibreDTE\FirmaElectronica($firma_config); |
||
60 | * \endcode |
||
61 | * |
||
62 | * @param config Configuración para la clase, si no se especifica se tratará de determinar |
||
63 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
64 | * @version 2015-09-15 |
||
65 | */ |
||
66 | public function __construct(array $config = []) |
||
99 | |||
100 | /** |
||
101 | * Método para generar un error usando una excepción de SowerPHP o terminar |
||
102 | * el script si no se está usando el framework |
||
103 | * @param msg Mensaje del error |
||
104 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
105 | * @version 2017-08-04 |
||
106 | */ |
||
107 | private function error($msg) |
||
117 | |||
118 | /** |
||
119 | * Método que agrega el inicio y fin de un certificado (clave pública) |
||
120 | * @param cert Certificado que se desea normalizar |
||
121 | * @return Certificado con el inicio y fin correspondiente |
||
122 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
123 | * @version 2015-08-20 |
||
124 | */ |
||
125 | private function normalizeCert($cert) |
||
135 | |||
136 | /** |
||
137 | * Método que entrega el RUN/RUT asociado al certificado |
||
138 | * @return RUN/RUT asociado al certificado en formato: 11222333-4 |
||
139 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
140 | * @version 2016-02-12 |
||
141 | */ |
||
142 | public function getID() |
||
162 | |||
163 | /** |
||
164 | * Método que entrega el CN del subject |
||
165 | * @return CN del subject |
||
166 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
167 | * @version 2016-02-12 |
||
168 | */ |
||
169 | public function getName() |
||
175 | |||
176 | /** |
||
177 | * Método que entrega el emailAddress del subject |
||
178 | * @return emailAddress del subject |
||
179 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
180 | * @version 2016-02-12 |
||
181 | */ |
||
182 | public function getEmail() |
||
189 | |||
190 | /** |
||
191 | * Método que entrega desde cuando es válida la firma |
||
192 | * @return validFrom_time_t |
||
193 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
194 | * @version 2015-09-22 |
||
195 | */ |
||
196 | public function getFrom() |
||
200 | |||
201 | /** |
||
202 | * Método que entrega hasta cuando es válida la firma |
||
203 | * @return validTo_time_t |
||
204 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
205 | * @version 2015-09-22 |
||
206 | */ |
||
207 | public function getTo() |
||
211 | |||
212 | /** |
||
213 | * Método que entrega los días totales que la firma es válida |
||
214 | * @return int Días totales en que la firma es válida |
||
215 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
216 | * @version 2019-02-12 |
||
217 | */ |
||
218 | public function getTotalDays() |
||
225 | |||
226 | /** |
||
227 | * Método que entrega los días que faltan para que la firma expire |
||
228 | * @return int Días que faltan para que la firma expire |
||
229 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
230 | * @version 2019-02-12 |
||
231 | */ |
||
232 | public function getExpirationDays($desde = null) |
||
242 | |||
243 | /** |
||
244 | * Método que entrega el nombre del emisor de la firma |
||
245 | * @return CN del issuer |
||
246 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
247 | * @version 2015-09-22 |
||
248 | */ |
||
249 | public function getIssuer() |
||
253 | |||
254 | /** |
||
255 | * Método que entrega los datos del certificado |
||
256 | * @return Arreglo con todo los datos del certificado |
||
257 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
258 | * @version 2015-09-11 |
||
259 | */ |
||
260 | public function getData() |
||
264 | |||
265 | /** |
||
266 | * Método que obtiene el módulo de la clave privada |
||
267 | * @return Módulo en base64 |
||
268 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
269 | * @version 2014-12-07 |
||
270 | */ |
||
271 | public function getModulus() |
||
276 | |||
277 | /** |
||
278 | * Método que obtiene el exponente público de la clave privada |
||
279 | * @return Exponente público en base64 |
||
280 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
281 | * @version 2014-12-06 |
||
282 | */ |
||
283 | public function getExponent() |
||
288 | |||
289 | /** |
||
290 | * Método que entrega el certificado de la firma |
||
291 | * @return Contenido del certificado, clave pública del certificado digital, en base64 |
||
292 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
293 | * @version 2015-08-24 |
||
294 | */ |
||
295 | View Code Duplication | public function getCertificate($clean = false) |
|
307 | |||
308 | /** |
||
309 | * Método que entrega la clave privada de la firma |
||
310 | * @return Contenido de la clave privada del certificado digital en base64 |
||
311 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
312 | * @version 2015-08-24 |
||
313 | */ |
||
314 | View Code Duplication | public function getPrivateKey($clean = false) |
|
326 | |||
327 | /** |
||
328 | * Método para realizar la firma de datos |
||
329 | * @param data Datos que se desean firmar |
||
330 | * @param signature_alg Algoritmo que se utilizará para firmar (por defect SHA1) |
||
331 | * @return Firma digital de los datos en base64 o =false si no se pudo firmar |
||
332 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
333 | * @version 2014-12-08 |
||
334 | */ |
||
335 | public function sign($data, $signature_alg = OPENSSL_ALGO_SHA1) |
||
343 | |||
344 | /** |
||
345 | * Método que verifica la firma digital de datos |
||
346 | * @param data Datos que se desean verificar |
||
347 | * @param signature Firma digital de los datos en base64 |
||
348 | * @param pub_key Certificado digital, clave pública, de la firma |
||
349 | * @param signature_alg Algoritmo que se usó para firmar (por defect SHA1) |
||
350 | * @return =true si la firma está ok, =false si está mal o no se pudo determinar |
||
351 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
352 | * @version 2014-12-08 |
||
353 | */ |
||
354 | public function verify($data, $signature, $pub_key = null, $signature_alg = OPENSSL_ALGO_SHA1) |
||
361 | |||
362 | /** |
||
363 | * Método que firma un XML utilizando RSA y SHA1 |
||
364 | * |
||
365 | * Referencia: http://www.di-mgt.com.au/xmldsig2.html |
||
366 | * |
||
367 | * @param xml Datos XML que se desean firmar |
||
368 | * @param reference Referencia a la que hace la firma |
||
369 | * @return XML firmado o =false si no se pudo fimar |
||
370 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
371 | * @version 2017-10-22 |
||
372 | */ |
||
373 | public function signXML($xml, $reference = '', $tag = null, $xmlns_xsi = false) |
||
468 | |||
469 | /** |
||
470 | * Método que verifica la validez de la firma de un XML utilizando RSA y SHA1 |
||
471 | * @param xml_data Archivo XML que se desea validar |
||
472 | * @return =true si la firma del documento XML es válida o =false si no lo es |
||
473 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
474 | * @version 2015-09-02 |
||
475 | */ |
||
476 | public function verifyXML($xml_data, $tag = null) |
||
500 | |||
501 | /** |
||
502 | * Método que obtiene la clave asociada al módulo y exponente entregados |
||
503 | * @param modulus Módulo de la clave |
||
504 | * @param exponent Exponente de la clave |
||
505 | * @return Entrega la clave asociada al módulo y exponente |
||
506 | * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]sasco.cl) |
||
507 | * @version 2015-09-19 |
||
508 | */ |
||
509 | public static function getFromModulusExponent($modulus, $exponent) |
||
518 | |||
519 | } |
||
520 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.