Nuevas Características: • Visualizador de pagos mensuales con gráfica de dona (Chart.js) • Tarjetas estadísticas: clientes activos, pagados y pendientes • Tabla de clientes pendientes con saldos en tiempo real • Microservicio Node.js para metadata de Stripe (acceso directo a BD) Mejoras: • Fix crítico: Sincronización automática de saldo en CallBell al agregar facturas • Categorización mejorada de pagos OXXO y Transferencias Stripe • Normalización de valores: "OXXO" → "OXXO Pay" para evitar errores 422 • Configuración .env para credenciales de base de datos Correcciones: • Saldo y estado ahora se actualizan correctamente en CallBell • Fix networking Docker (ECONNREFUSED resuelto) • Fix validación de atributos en API de UCRM • Actualización automática de userId en pagos Stripe Archivos principales: public.php (visualizador de pagos) AbstractMessageNotifierFacade.php (logging sync) ClientCallBellAPI.php (comparación de campos) AbstractStripeOperationsFacade.php (normalización) manifest.json, README.md, CHANGELOG.md (docs)
235 lines
5.8 KiB
PHP
Executable File
235 lines
5.8 KiB
PHP
Executable File
<?php
|
|
namespace Aws;
|
|
|
|
use Aws\Api\ListShape;
|
|
use Aws\Api\MapShape;
|
|
use Aws\Api\Service;
|
|
use Aws\Api\Shape;
|
|
use Aws\Api\StructureShape;
|
|
use Closure;
|
|
|
|
/**
|
|
* Inspects command input values and casts them to their modeled type.
|
|
* This covers query compatible services which have migrated from query
|
|
* to JSON wire protocols.
|
|
*
|
|
* @internal
|
|
*/
|
|
class QueryCompatibleInputMiddleware
|
|
{
|
|
/** @var callable */
|
|
private $nextHandler;
|
|
|
|
/** @var Service */
|
|
private $service;
|
|
|
|
/** @var CommandInterface */
|
|
private $command;
|
|
|
|
/**
|
|
* Create a middleware wrapper function.
|
|
*
|
|
* @param Service $service
|
|
* @return Closure
|
|
*/
|
|
public static function wrap(Service $service) : Closure
|
|
{
|
|
return static function (callable $handler) use ($service) {
|
|
return new self($handler, $service);
|
|
};
|
|
}
|
|
|
|
public function __construct(callable $nextHandler, Service $service)
|
|
{
|
|
$this->service = $service;
|
|
$this->nextHandler = $nextHandler;
|
|
}
|
|
|
|
public function __invoke(CommandInterface $cmd)
|
|
{
|
|
$this->command = $cmd;
|
|
$nextHandler = $this->nextHandler;
|
|
$op = $this->service->getOperation($cmd->getName());
|
|
$inputMembers = $op->getInput()->getMembers();
|
|
$input = $cmd->toArray();
|
|
|
|
foreach ($input as $param => $value) {
|
|
if (isset($inputMembers[$param])) {
|
|
$shape = $inputMembers[$param];
|
|
$this->processInput($value, $shape, [$param]);
|
|
}
|
|
}
|
|
|
|
return $nextHandler($this->command);
|
|
}
|
|
|
|
/**
|
|
* Recurses a given input shape. if a given scalar input does not match its
|
|
* modeled type, it is cast to its modeled type.
|
|
*
|
|
* @param $input
|
|
* @param $shape
|
|
* @param array $path
|
|
*
|
|
* @return void
|
|
*/
|
|
private function processInput($input, $shape, array $path) : void
|
|
{
|
|
switch ($shape->getType()) {
|
|
case 'structure':
|
|
$this->processStructure($input, $shape, $path);
|
|
break;
|
|
case 'list':
|
|
$this->processList($input, $shape, $path);
|
|
break;
|
|
case 'map':
|
|
$this->processMap($input, $shape, $path);
|
|
break;
|
|
default:
|
|
$this->processScalar($input, $shape, $path);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @param StructureShape $shape
|
|
* @param array $path
|
|
*
|
|
* @return void
|
|
*/
|
|
private function processStructure(
|
|
array $input,
|
|
StructureShape $shape,
|
|
array $path
|
|
) : void
|
|
{
|
|
foreach ($input as $param => $value) {
|
|
if ($shape->hasMember($param)) {
|
|
$memberPath = array_merge($path, [$param]);
|
|
$this->processInput($value, $shape->getMember($param), $memberPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @param ListShape $shape
|
|
* @param array $path
|
|
*
|
|
* @return void
|
|
*/
|
|
private function processList(
|
|
array $input,
|
|
ListShape $shape,
|
|
array $path
|
|
) : void
|
|
{
|
|
foreach ($input as $param => $value) {
|
|
$memberPath = array_merge($path, [$param]);
|
|
$this->processInput($value, $shape->getMember(), $memberPath);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @param MapShape $shape
|
|
* @param array $path
|
|
*
|
|
* @return void
|
|
*/
|
|
private function processMap(array $input, MapShape $shape, array $path) : void
|
|
{
|
|
foreach ($input as $param => $value) {
|
|
$memberPath = array_merge($path, [$param]);
|
|
$this->processInput($value, $shape->getValue(), $memberPath);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $input
|
|
* @param Shape $shape
|
|
* @param array $path
|
|
*
|
|
* @return void
|
|
*/
|
|
private function processScalar($input, Shape $shape, array $path) : void
|
|
{
|
|
$expectedType = $shape->getType();
|
|
|
|
if (!$this->isModeledType($input, $expectedType)) {
|
|
trigger_error(
|
|
"The provided type for `". implode(' -> ', $path) ."` value was `"
|
|
. (gettype($input) === 'double' ? 'float' : gettype($input)) . "`."
|
|
. " The modeled type is `{$expectedType}`.",
|
|
E_USER_WARNING
|
|
);
|
|
$value = $this->castValue($input, $expectedType);
|
|
$this->changeValueAtPath($path, $value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Modifies command in place
|
|
*
|
|
* @param array $path
|
|
* @param $newValue
|
|
*
|
|
* @return void
|
|
*/
|
|
private function changeValueAtPath(array $path, $newValue) : void
|
|
{
|
|
$commandRef = &$this->command;
|
|
|
|
foreach ($path as $segment) {
|
|
if (!isset($commandRef[$segment])) {
|
|
return;
|
|
}
|
|
$commandRef = &$commandRef[$segment];
|
|
}
|
|
$commandRef = $newValue;
|
|
}
|
|
|
|
/**
|
|
* @param $value
|
|
* @param $type
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function isModeledType($value, $type) : bool
|
|
{
|
|
switch ($type) {
|
|
case 'string':
|
|
return is_string($value);
|
|
case 'integer':
|
|
case 'long':
|
|
return is_int($value);
|
|
case 'float':
|
|
return is_float($value);
|
|
default:
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $value
|
|
* @param $type
|
|
*
|
|
* @return float|int|mixed|string
|
|
*/
|
|
private function castValue($value, $type)
|
|
{
|
|
switch ($type) {
|
|
case 'integer':
|
|
return (int) $value;
|
|
case 'long' :
|
|
return $value + 0;
|
|
case 'float':
|
|
return (float) $value;
|
|
case 'string':
|
|
return (string) $value;
|
|
default:
|
|
return $value;
|
|
}
|
|
}
|
|
}
|