ldc-bogt/app/Lib/CafelApi/Models/CafelClientModel.php
Jérémy Munsch 7cb304e967
Full traça poulets
Cafel APi Eat
Xml flux new
Full Models Rework
Refactorize
2022-06-08 11:44:01 +02:00

242 lines
7.3 KiB
PHP

<?php
namespace App\Lib\CafelApi\Models;
use App\Enums\HttpMethods;
use App\Exceptions\CafelApiException;
use App\Lib\CafelApi\Transport\ApiInterface;
use App\Lib\CafelApi\Transport\Request;
use App\Lib\FileHelper;
use App\Lib\ToolboxHelper;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
/**
*
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
*/
abstract class CafelClientModel implements \JsonSerializable
{
/**
* The Api object that will handle requests and responses
*
* @var \App\Lib\CafelApi\Transport\ApiInterface
*/
protected static $apiInterface;
/**
* Validation rules from cafel Api
*
* @var array
*/
protected static $validationRules = [];
/**
* Column translations
*
* @var array
*/
protected static $columnsTranslations = [];
/**
* Create the Api interface
*
* @return void
*/
protected static function setUpApiInterface()
{
self::$apiInterface = self::$apiInterface ?: new ApiInterface();
}
/**
* Generate a Request from the route name
*
* @param string $routeName
* @param array $query Params to pass on to the route.
* @param array $data Http body params.
* @return \App\Lib\CafelApi\Transport\Request
* @throws \ErrorException If the requested route is unknown.
* @throws \ErrorException If a required parameter is missing.
*/
public static function getResquest(string $routeName, array $query = [], array $data = []): Request
{
// Convert bool to integer.
$query = \array_map(function ($v) {
return is_bool($v) ? (int)$v : $v;
}, $query);
$data = \array_map(function ($v) {
return is_bool($v) ? (int)$v : $v;
}, $data);
$routes = config('cafel.routes');
if (!isset($routes[$routeName])) {
throw new \ErrorException("Unknown route $routeName from the crm");
}
$route = $routes[$routeName];
$matches = [];
$matchedIndex = [];
\preg_match_all('/{([\w-]*)}/', $route['uri'], $matches);
if (\count($matches[0])) {
foreach ($matches[0] as $k => $match) {
if (!isset($query[$matches[1][$k]])) {
throw new \ErrorException(sprintf('Missing required parameter %s', $matches[1][$k]));
}
$route['uri'] = str_replace($match, $query[$matches[1][$k]], $route['uri']);
$matchedIndex[$matches[1][$k]] = $query[$matches[1][$k]];
}
}
foreach ($matchedIndex as $key => $value) {
unset($query[$key]);
}
if (count($query)) {
$route['uri'] = sprintf('%s?%s', $route['uri'], \http_build_query($query));
}
return new Request(HttpMethods::make($route['methods'][0]), $route['uri'], [], $data);
}
/**
* Validate data row from api.
*
* @param array $data
* @return void
* @throws \Illuminate\Validation\ValidationException If data does not validate.
*/
public static function validateDataRow(array $data)
{
$validationRules = collect(static::$validationRules)
/** @var string|array $rule */
->mapWithKeys(function ($rules, string $attribute) {
return [
$attribute => is_array($rules) ? collect($rules)
->map(function ($rule) {
// * Handle new rule instance
return \is_array($rule) ? new $rule[0]($rule[1]) : $rule;
})->all() : $rules
];
})->all();
static::validateData($data, $validationRules);
}
/**
* Validate data from api
*
* @param array $data
* @param array $rules
* @return array
* @throws \Illuminate\Validation\ValidationException If data does not validate.
*/
protected function validateData(array $data, array $rules): array
{
return Validator::validate($data, $rules);
}
/**
* Get paginated mises en places
*
* @param string $routeName
* @param integer $page
* @param integer $pageSize
* @param mixed ...$args
* @return array
* @throws \App\Exceptions\CafelApiException If reponse status is KO, or body is not an array.
*/
public static function paginate(string $routeName, int $page, int $pageSize = 100, ...$args): array
{
self::setUpApiInterface();
$request = CafelClientModel::getResquest(
$routeName,
array_merge($args, ['page' => $page, 'pageSize' => $pageSize])
);
$response = self::$apiInterface->call($request);
if (!\is_array($response->body)) {
throw new CafelApiException('Response should have been an array');
}
$out = [];
foreach ($response->body as $row) {
$out[] = static::translateColumns($row);
}
return $out;
}
/**
* Translate row keys
*
* @param array $row
* @return array
*/
protected static function translateColumns(array $row): array
{
foreach (static::$columnsTranslations as $cafelName => $newName) {
$row = static::renameArrKey($row, $cafelName, $newName);
}
return $row;
}
/**
* Rename array key
*
* @param array $arr
* @param string $oldKey
* @param string $newKey
* @return array
*/
protected static function renameArrKey(array $arr, string $oldKey, string $newKey): array
{
// * Failsafe
if (!isset($arr[$oldKey])) {
return $arr;
}
$keys = array_keys($arr);
$keys[array_search($oldKey, $keys)] = $newKey;
$newArr = array_combine($keys, $arr);
return $newArr;
}
/**
* Fetch and store picture to a path
*
* @param string $folder The folder where to put the picture.
* @param string $url The cafel image url.
* @return string The picture path
* @throws \App\Exceptions\CafelApiException If Response is not a valid array.
* @throws \ErrorException If writing to temp file failed.
* @throws \App\Exceptions\CafelApiImageFetchException If invalid image was given or ext could not be confirmed.
* @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
*/
public static function fetchPicture(string $folder, string $url): string
{
/** @var array $query */
parse_str(\parse_url($url, \PHP_URL_QUERY), $query);
$idPhoto = intval($query['idPhoto']);
self::setUpApiInterface();
$request = CafelClientModel::getResquest(
'cafel.ldc.photoeleveur',
['idPhoto' => $idPhoto]
);
$response = self::$apiInterface->call($request);
if (!\is_array($response->body)) {
throw new CafelApiException('Response should have been an array');
}
// * Filter Keys using intersection
\extract(\array_intersect_key($response->body, ['Ext' => '', 'Name' => '', 'Data' => '']));
return ToolboxHelper::storeImage(
$folder,
FileHelper::fromBase64(
Str::lower($Name),
Str::lower($Ext),
$Data
),
false
);
}
}