Skip to content

Commit 5cf4b11

Browse files
committed
Version 2.2.0
- Refactor namespace `\CfdiUtils\CadenaOrigen` (backwards compatible): - Instead of one only xslt builder now it includes: - `DOMBuilder`: Uses the regular PHP based method - `GenkgoXslBuilder`: Uses the library genkgo/xsl xslt version 2 library - `SaxonbCliBuilder`: Uses the command line saxonb-xslt command - Build process implementations must return `XsltBuildException` (before they return `RuntimeException`) - All builders must implement `XsltBuilderInterface` - Add `XsltBuilderPropertyInterface` and `XsltBuilderPropertyTrait`. It does not have `hasXsltBuilderProperty`method. - `DefaultLocations` has been deprecated in favor of `CfdiDefaultLocations` - `CadenaOrigenBuilder` has been deprecated in favor of `DOMBuilder` - `CadenaOrigenLocations` has been deprecated, will not be replaced - Implement `XsltBuilderPropertyInterface` and `XsltBuilderPropertyTrait` in objects that use to create `CadenaOrigenBuilder` objects. - For `CfdiCreator33` and `CfdiValidator33` will create a default DOMBuilder object if none set. - Hydrator also receive and hydrates this by using `RequireXsltBuilderInterface`. - `CertificadoPropertyInterface` and `CertificadoPropertyTrait` has been created. - Improve the tests.
2 parents 7c8d57f + d4e67db commit 5cf4b11

36 files changed

+664
-274
lines changed

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ php:
1010
# See: http://docs.travis-ci.com/user/workers/container-based-infrastructure/
1111
sudo: false
1212

13+
addons:
14+
apt:
15+
packages:
16+
- libsaxonb-java
17+
1318
before_script:
1419
- travis_retry composer install --no-interaction --prefer-dist
1520
- |

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ composer require eclipxe/cfdiutils
3838
```
3939

4040

41+
## Major versions
42+
43+
- Version 1.x **deprecated** was deprecated time ago, that version didn't do much anyway
44+
- Version 2.x **current** has a lot of features and helper objects
45+
- Version 3.x **future** will be released with the following backward compatibility breaks:
46+
- Rename `\CfdiUtils\CadenaOrigen\CadenaOrigenBuilder` to `\CfdiUtils\CadenaOrigen\DOMBuilder`
47+
- Rename `\CfdiUtils\CadenaOrigen\DefaultLocations` to `\CfdiUtils\CadenaOrigen\CfdiDefaultLocations`
48+
- Remove `\CfdiUtils\CadenaOrigen\CadenaOrigenLocations`
49+
50+
4151
## PHP Support
4252

4353
This library is compatible with PHP versions 7.0 and above.

composer.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
"eclipxe/xmlresourceretriever": "^1.2",
2121
"eclipxe/xmlschemavalidator": "^2.0"
2222
},
23+
"suggest": {
24+
"genkgo/xsl": "^0.5.20"
25+
},
2326
"require-dev": {
27+
"genkgo/xsl": "^0.5.20",
2428
"phpunit/phpunit": "^6.2",
2529
"jakub-onderka/php-parallel-lint": "^0.9",
2630
"squizlabs/php_codesniffer": "^3.0",

docs/CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
# Version 2.2.0 2018-01-24
2+
- Refactor namespace `\CfdiUtils\CadenaOrigen` (backwards compatible):
3+
- Instead of one only xslt builder now it includes:
4+
- `DOMBuilder`: Uses the regular PHP based method
5+
- `GenkgoXslBuilder`: Uses the library genkgo/xsl xslt version 2 library
6+
- `SaxonbCliBuilder`: Uses the command line saxonb-xslt command
7+
- Build process implementations must return `XsltBuildException` (before they return `RuntimeException`)
8+
- All builders must implement `XsltBuilderInterface`
9+
- Add `XsltBuilderPropertyInterface` and `XsltBuilderPropertyTrait`.
10+
It does not have `hasXsltBuilderProperty`method.
11+
- `DefaultLocations` has been deprecated in favor of `CfdiDefaultLocations`
12+
- `CadenaOrigenBuilder` has been deprecated in favor of `DOMBuilder`
13+
- `CadenaOrigenLocations` has been deprecated, will not be replaced
14+
- Implement `XsltBuilderPropertyInterface` and `XsltBuilderPropertyTrait` in objects that use
15+
to create `CadenaOrigenBuilder` objects.
16+
- For `CfdiCreator33` and `CfdiValidator33` will create a default DOMBuilder object if none set.
17+
- Hydrator also receive and hydrates this by using `RequireXsltBuilderInterface`.
18+
- `CertificadoPropertyInterface` and `CertificadoPropertyTrait` has been created.
19+
- Improve the tests.
20+
21+
122
# Version 2.1.0 2018-01-17
223
- Fix `SumasConceptos` to work also with "ImpuestosLocales"
324
- Add elements helpers `CfdiUtils\Elements\ImpLocal10\ImpuestosLocales` to work with "ImpuestosLocales"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
namespace CfdiUtils\CadenaOrigen;
3+
4+
abstract class AbstractXsltBuilder implements XsltBuilderInterface
5+
{
6+
protected function assertBuildArguments(string $xmlContent, string $xsltLocation): string
7+
{
8+
if ('' === $xmlContent) {
9+
throw new \UnexpectedValueException('The XML content to transform is empty');
10+
}
11+
if ('' === $xsltLocation) {
12+
throw new \UnexpectedValueException('Xslt location was not set');
13+
}
14+
return '';
15+
}
16+
}
Lines changed: 4 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,11 @@
11
<?php
22
namespace CfdiUtils\CadenaOrigen;
33

4-
use DOMDocument;
5-
use LibXMLError;
6-
use XSLTProcessor;
7-
84
/**
9-
* The class CadenaOrigenLocations create the CadenaOrigenLocations by transforming the XML contents
10-
* using the XSLT utilities provided by SAT.
11-
*
12-
* This class is a helps override or set the location of the clst resource.
5+
* Use some implementation of XsltBuilderInterface
6+
* @see DOMBuilder
7+
* @deprecated Will be removed in release 3.0
138
*/
14-
class CadenaOrigenBuilder
9+
class CadenaOrigenBuilder extends DOMBuilder
1510
{
16-
/**
17-
* Perform the xslt transformation if the xml contents to create the "Cadena de origen"
18-
* for a "Comprobante fiscal digital por internet (cfdi)"
19-
*
20-
* This method will search for the registered xslt location the xlstLocation argument is empty
21-
*
22-
* All errors generated by the process will create a RuntimeException
23-
*
24-
* @param string $cfdiContent
25-
* @param string $xsltLocation
26-
* @return string
27-
* @throws \UnexpectedValueException if the cfdi content is empty
28-
* @throws \RuntimeException on procedural errors
29-
*/
30-
public function build(string $cfdiContent, string $xsltLocation): string
31-
{
32-
if ('' === $cfdiContent) {
33-
throw new \UnexpectedValueException('The XML content to transform is empty');
34-
}
35-
if ('' === $xsltLocation) {
36-
throw new \UnexpectedValueException('Xslt location was not set');
37-
}
38-
$libxmlErrors = libxml_use_internal_errors(true);
39-
try {
40-
// load the cfdi document
41-
$cfdi = new DOMDocument();
42-
if (! $cfdi->loadXML($cfdiContent)) {
43-
throw $this->createLibXmlErrorOrMessage('Error while loading the cfdi content');
44-
}
45-
46-
$xsl = new DOMDocument();
47-
if (! $xsl->load($xsltLocation)) {
48-
throw $this->createLibXmlErrorOrMessage('Error while loading the Xslt location');
49-
}
50-
51-
$xslt = new XSLTProcessor();
52-
if (! $xslt->importStylesheet($xsl)) {
53-
throw $this->createLibXmlErrorOrMessage('Error while importing the style sheet from the Xslt location');
54-
}
55-
56-
// this error silenced call is intentional, avoid transformation errors except when return false
57-
$transform = @$xslt->transformToXml($cfdi);
58-
if (false === $transform || null === $transform) {
59-
throw $this->createLibXmlErrorOrMessage('Error while transforming the xslt content');
60-
}
61-
62-
return $transform;
63-
} finally {
64-
libxml_clear_errors();
65-
libxml_use_internal_errors($libxmlErrors);
66-
}
67-
}
68-
69-
private function createLibXmlErrorOrMessage(string $message): \RuntimeException
70-
{
71-
$error = libxml_get_last_error();
72-
if (($error instanceof LibXMLError) && isset($error->message)) {
73-
$message = $message . ': ' . $error->message;
74-
}
75-
return new \RuntimeException($message);
76-
}
7711
}

src/CfdiUtils/CadenaOrigen/CadenaOrigenLocations.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,23 @@
77
* The class CadenaOrigenLocations create the CadenaOrigenLocations by transforming the XML contents
88
* using the XSLT utilities provided by SAT.
99
*
10-
* This class is a helps override or set the location of the clst resource.
10+
* This class is a helps override or set the location of the xslt resource.
11+
*
12+
* @deprecated Will be removed in release 3.0
1113
*/
1214
class CadenaOrigenLocations
1315
{
1416
/**
15-
* Private array containing urls for xlst versions
17+
* Private array containing urls for xslt versions
1618
* @var string[]
1719
*/
1820
private $xsltLocations = [
19-
'3.2' => DefaultLocations::XSLT_32,
20-
'3.3' => DefaultLocations::XSLT_33,
21+
'3.2' => CfdiDefaultLocations::XSLT_32,
22+
'3.3' => CfdiDefaultLocations::XSLT_33,
2123
];
2224

2325
/**
24-
* Return the registered location of the xlst file to perform the xml transformation
26+
* Return the registered location of the xslt file to perform the xml transformation
2527
* depending on the cfdi version. This value can be changed using setXsltLocation
2628
*
2729
* @see setXsltLocation
@@ -37,7 +39,7 @@ public function getXsltLocation(string $version): string
3739
}
3840

3941
/**
40-
* Override the default location of the xlst for an specified version
42+
* Override the default location of the xslt for an specified version
4143
*
4244
* @param string $version
4345
* @param string $location
@@ -71,7 +73,7 @@ public function getXsltLocationFromXml(string $cfdiContent): string
7173
* Perform the xslt transformation if the xml contents to create the "Cadena de origen"
7274
* for a "Comprobante fiscal digital por internet (cfdi)"
7375
*
74-
* This method will search for the registered xslt location the xlstLocation argument is empty
76+
* This method will search for the registered xslt location the xsltLocation argument is empty
7577
*
7678
* All errors generated by the process will create a RuntimeException
7779
*
@@ -83,7 +85,7 @@ public function getXsltLocationFromXml(string $cfdiContent): string
8385
public function build(string $cfdiContent): string
8486
{
8587
$xsltLocation = $this->getXsltLocationFromXml($cfdiContent);
86-
$builder = new CadenaOrigenBuilder();
88+
$builder = new DOMBuilder();
8789
return $builder->build($cfdiContent, $xsltLocation);
8890
}
8991
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
namespace CfdiUtils\CadenaOrigen;
3+
4+
class CfdiDefaultLocations
5+
{
6+
const XSLT_32 = 'http://www.sat.gob.mx/sitio_internet/cfd/3/cadenaoriginal_3_2/cadenaoriginal_3_2.xslt';
7+
const XSLT_33 = 'http://www.sat.gob.mx/sitio_internet/cfd/3/cadenaoriginal_3_3/cadenaoriginal_3_3.xslt';
8+
9+
public static function location(string $version): string
10+
{
11+
if ('3.3' === $version) {
12+
return static::XSLT_33;
13+
}
14+
if ('3.2' === $version) {
15+
return static::XSLT_32;
16+
}
17+
throw new \UnexpectedValueException("Cannot get the default xslt location for version '$version'");
18+
}
19+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
namespace CfdiUtils\CadenaOrigen;
3+
4+
use DOMDocument;
5+
use LibXMLError;
6+
use XSLTProcessor;
7+
8+
class DOMBuilder extends AbstractXsltBuilder
9+
{
10+
public function build(string $xmlContent, string $xsltLocation): string
11+
{
12+
$this->assertBuildArguments($xmlContent, $xsltLocation);
13+
$libxmlErrors = libxml_use_internal_errors(true);
14+
try {
15+
// load the xml document
16+
$xml = new DOMDocument();
17+
if (! $xml->loadXML($xmlContent)) {
18+
throw $this->createLibXmlErrorOrMessage('Error while loading the xml content');
19+
}
20+
21+
$xsl = new DOMDocument();
22+
if (! $xsl->load($xsltLocation)) {
23+
throw $this->createLibXmlErrorOrMessage('Error while loading the Xslt location');
24+
}
25+
26+
return $this->transform($xml, $xsl);
27+
} finally {
28+
libxml_clear_errors();
29+
libxml_use_internal_errors($libxmlErrors);
30+
}
31+
}
32+
33+
protected function transform(DOMDocument $xml, DOMDocument $xsl): string
34+
{
35+
$xslt = new XSLTProcessor();
36+
if (! $xslt->importStylesheet($xsl)) {
37+
throw $this->createLibXmlErrorOrMessage('Error while importing the style sheet from the Xslt location');
38+
}
39+
40+
// this error silenced call is intentional, avoid transformation errors except when return false
41+
/** @var string|null|false $transform */
42+
$transform = @$xslt->transformToXml($xml);
43+
if (null === $transform || false === $transform) {
44+
throw $this->createLibXmlErrorOrMessage('Error while transforming the xslt content');
45+
}
46+
47+
return $transform;
48+
}
49+
50+
protected function createLibXmlErrorOrMessage(string $message): XsltBuildException
51+
{
52+
$error = libxml_get_last_error();
53+
if (($error instanceof LibXMLError) && isset($error->message)) {
54+
$message = $message . ': ' . $error->message;
55+
}
56+
return new XsltBuildException($message);
57+
}
58+
}
Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
<?php
22
namespace CfdiUtils\CadenaOrigen;
33

4-
class DefaultLocations
4+
/**
5+
* @deprecated Will be removed in release 3.0
6+
* @see CfdiDefaultLocations
7+
*/
8+
class DefaultLocations extends CfdiDefaultLocations
59
{
6-
const XSLT_32 = 'http://www.sat.gob.mx/sitio_internet/cfd/3/cadenaoriginal_3_2/cadenaoriginal_3_2.xslt';
7-
const XSLT_33 = 'http://www.sat.gob.mx/sitio_internet/cfd/3/cadenaoriginal_3_3/cadenaoriginal_3_3.xslt';
8-
9-
public static function location(string $version): string
10-
{
11-
if ('3.3' === $version) {
12-
return static::XSLT_33;
13-
}
14-
if ('3.2' === $version) {
15-
return static::XSLT_32;
16-
}
17-
throw new \UnexpectedValueException("Cannot get the default xslt location for version '$version'");
18-
}
1910
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
namespace CfdiUtils\CadenaOrigen;
3+
4+
use DOMDocument;
5+
use Genkgo\Xsl\XsltProcessor;
6+
7+
class GenkgoXslBuilder extends DOMBuilder
8+
{
9+
public function __construct()
10+
{
11+
if (! class_exists(XsltProcessor::class)) {
12+
throw new \RuntimeException('To use GenkgoXslBuilder you must install genkgo/xsl');
13+
}
14+
}
15+
16+
protected function transform(DOMDocument $xml, DOMDocument $xsl): string
17+
{
18+
$xslt = new XSLTProcessor();
19+
$xslt->importStyleSheet($xsl);
20+
21+
// this error silenced call is intentional, avoid transformation errors except when return false
22+
/** @var string|null|false $transform */
23+
$transform = @$xslt->transformToXML($xml);
24+
if (null === $transform || false === $transform) {
25+
throw $this->createLibXmlErrorOrMessage('Error while transforming the xslt content');
26+
}
27+
28+
return $transform;
29+
}
30+
}

0 commit comments

Comments
 (0)