-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #46 from eclipxe13/version-0.5.5
Mejorar el manejo de registros de SoapCaller (version 0.5.5)
- Loading branch information
Showing
9 changed files
with
297 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -239,31 +239,50 @@ para poder revisar el problema sobre la información enviada. | |
Esta librería genera mensajes utilizando *PSR-3: Logger Interface*, y se utiliza dentro del objeto `SoapFactory` | ||
para crear un `SoapCaller`. Este objeto envía dos tipos de mensajes: `LogLevel::ERROR` cuando ocurre un error al | ||
momento de establecer comunicación con los servicios, y `LogLevel::DEBUG` cuando se ejecutó una llamada SOAP. | ||
Ambos mensajes están representados como una cadena en formato JSON, por lo que, para leerla correctamente | ||
Ambos mensajes están representados como una cadena en formato JSON, por lo que, para leerla fácilmente | ||
es importante decodificarla. | ||
|
||
La clase [`PhpCfdi\Finkok\Tests\LoggerPrinter`](https://github.com/phpcfdi/finkok/blob/main/tests/LoggerPrinter.php) | ||
es un *ejemplo de implementación* de `LoggerInterface` que manda los mensajes recibidos a la salida estándar o | ||
a un archivo. Es importante notar que el objeto `LoggerPrinter` no está disponible en el paquete, sin embargo, | ||
lo puedes descargar y poner dentro de tu proyecto con tu espacio de nombres. | ||
El formato JSON es mejor dado que permite analizar el texto y encontrar caracteres especiales, | ||
mientras que, al convertirlo a un texto más entendible para el humano, estos caracteres especiales | ||
se pueden esconder o interpretar de forma errónea. | ||
|
||
De igual forma, se puede utilizar cualquier objeto que implemente `LoggerInterface`, por ejemplo, en Laravel se | ||
puede usar `$logger = app(Psr\Log\LoggerInterface::class)`. Pero recuerda que, una vez que tengas el mensaje, | ||
deberás decodificarlo de JSON a texto plano. | ||
Se ofrece la clase `PhpCfdi\Finkok\Helpers\FileLogger` como una utilería de `LoggerInterface` | ||
que manda los mensajes recibidos a la salida estándar o a un archivo. | ||
|
||
Para establecer el objeto `Logger` es recomendable hacerlo de la siguiente forma: | ||
También se ofrece la clase `PhpCfdi\Finkok\Helpers\JsonDecoderLogger` como una utilería de `LoggerInterface` | ||
que decodifica el mensaje JSON y luego lo convierte a cadena de caracteres usando la función `print_r()`, | ||
para después mandarlo a otro objeto `LoggerInterface`. | ||
|
||
En el siguiente ejemplo se muestra la forma recomendada para establecer el objeto `Logger`, | ||
también se muestra el uso de `JsonDecoderLogger` para realizar la conversión de JSON a texto plano y | ||
`FileLogger` para enviar el mensaje a un archivo específico. | ||
|
||
La clase `JsonDecoderLogger` puede generar pérdida de información, pero los mensajes son más entendibles, | ||
si deseas también incluir el mensaje JSON puedes usar `JsonDecoderLogger::setAlsoLogJsonMessage(true)`. | ||
|
||
```php | ||
use PhpCfdi\Finkok\FinkokEnvironment; | ||
use PhpCfdi\Finkok\FinkokSettings; | ||
use PhpCfdi\Finkok\Tests\LoggerPrinter; | ||
use PhpCfdi\Finkok\Helpers\FileLogger; | ||
use PhpCfdi\Finkok\Helpers\JsonDecoderLogger; | ||
|
||
$logger = new LoggerPrinter('/tmp/finkok.log'); | ||
$logger = new JsonDecoderLogger(new FileLogger('/tmp/finkok.log')); | ||
$logger->setAlsoLogJsonMessage(true); // enviar en texto simple y también en formato JSON | ||
|
||
$settings = new FinkokSettings('[email protected]', 'secret', FinkokEnvironment::makeProduction()); | ||
$settings->soapFactory()->setLogger($logger); | ||
``` | ||
|
||
Si estás usando Laravel, ya cuentas con una implementación de `LoggerInterface`, por lo que te recomiendo usar: | ||
|
||
```php | ||
/** @var \Psr\Log\LoggerInterface $logger */ | ||
$logger = app(\Psr\Log\LoggerInterface::class); | ||
|
||
// Encapsular el logger en el decodificador JSON: | ||
$logger = new \PhpCfdi\Finkok\Helpers\JsonDecoderLogger($logger); | ||
``` | ||
|
||
## Compatibilidad | ||
|
||
Esta librería se mantendrá compatible con al menos la versión con | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PhpCfdi\Finkok\Helpers; | ||
|
||
use Psr\Log\AbstractLogger; | ||
use Psr\Log\LoggerInterface; | ||
|
||
/** | ||
* Esta clase es un adaptador para convertir un mensaje de registro (log) que está | ||
* en formato Json y es decodificado y convertido en texto a través de la función | ||
* print_r, luego pasa el mensaje al logger con el que fue construido el objeto. | ||
* | ||
* Si el mensaje no es un Json no válido entonces pasa sin convertirse. | ||
* | ||
* Tiene algunas opciones: | ||
* - alsoLogJsonMessage: Envía los dos mensajes, tanto el texto como el json al logger. | ||
* - useJsonValidateIfAvailable: Usa \json_validate() si está disponible. | ||
*/ | ||
final class JsonDecoderLogger extends AbstractLogger implements LoggerInterface | ||
{ | ||
/** @var LoggerInterface */ | ||
private $logger; | ||
|
||
/** @var bool */ | ||
private $useJsonValidateIfAvailable = true; | ||
|
||
/** @var bool */ | ||
private $alsoLogJsonMessage = false; | ||
|
||
/** @var bool */ | ||
private $lastMessageWasJsonValid = false; | ||
|
||
public function __construct(LoggerInterface $logger) | ||
{ | ||
$this->logger = $logger; | ||
} | ||
|
||
/** | ||
* Define si se utilizará la función \json_validate en caso de estar disponible. | ||
* | ||
* @param bool|null $value El nuevo estado, si se establece NULL entonces solo devuelve el espado previo. | ||
* @return bool El estado previo | ||
*/ | ||
public function setUseJsonValidateIfAvailable(bool $value = null): bool | ||
{ | ||
$previous = $this->useJsonValidateIfAvailable; | ||
if (null !== $value) { | ||
$this->useJsonValidateIfAvailable = $value; | ||
} | ||
return $previous; | ||
} | ||
|
||
/** | ||
* Define si también se mandará el mensaje JSON al Logger. | ||
* | ||
* @param bool|null $value El nuevo estado, si se establece NULL entonces solo devuelve el espado previo. | ||
* @return bool El estado previo | ||
*/ | ||
public function setAlsoLogJsonMessage(bool $value = null): bool | ||
{ | ||
$previous = $this->alsoLogJsonMessage; | ||
if (null !== $value) { | ||
$this->alsoLogJsonMessage = $value; | ||
} | ||
return $previous; | ||
} | ||
|
||
public function lastMessageWasJsonValid(): bool | ||
{ | ||
return $this->lastMessageWasJsonValid; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
* @param string|\Stringable $message | ||
* @param mixed[] $context | ||
*/ | ||
public function log($level, $message, array $context = []): void | ||
{ | ||
$this->logger->log($level, $this->jsonDecode($message), $context); | ||
if ($this->lastMessageWasJsonValid && $this->alsoLogJsonMessage) { | ||
$this->logger->log($level, $message, $context); | ||
} | ||
} | ||
|
||
/** @param string|\Stringable $string */ | ||
private function jsonDecode($string): string | ||
{ | ||
$this->lastMessageWasJsonValid = false; | ||
$string = strval($string); | ||
|
||
// json_validate and json_decode | ||
if ($this->useJsonValidateIfAvailable && function_exists('\json_validate')) { | ||
if (\json_validate($string)) { | ||
$this->lastMessageWasJsonValid = true; | ||
return $this->varDump(json_decode($string)); | ||
} | ||
|
||
return $string; | ||
} | ||
|
||
// json_decode only | ||
$decoded = json_decode($string); | ||
if (JSON_ERROR_NONE === json_last_error()) { | ||
$this->lastMessageWasJsonValid = true; | ||
return $this->varDump($decoded); | ||
} | ||
|
||
return $string; | ||
} | ||
|
||
/** @param mixed $var */ | ||
private function varDump($var): string | ||
{ | ||
return print_r($var, true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.