2022-03-09 17:28:23 +01:00
|
|
|
<?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.
|
|
|
|
|
*/
|
2022-10-27 12:25:05 +02:00
|
|
|
protected static function validateData(array $data, array $rules): array
|
2022-03-09 17:28:23 +01:00
|
|
|
{
|
|
|
|
|
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' => '']));
|
|
|
|
|
|
2022-12-06 10:24:00 +01:00
|
|
|
// * Create temp file and get its absolute path
|
|
|
|
|
if (!($tempFile = tmpfile())) {
|
|
|
|
|
new \RuntimeException('Could not create temp file');
|
|
|
|
|
}
|
2022-03-09 17:28:23 +01:00
|
|
|
|
2022-12-06 10:24:00 +01:00
|
|
|
$filePath = ToolboxHelper::storeImage(
|
2022-03-09 17:28:23 +01:00
|
|
|
$folder,
|
|
|
|
|
FileHelper::fromBase64(
|
2022-12-06 10:24:00 +01:00
|
|
|
$tempFile,
|
2022-03-09 17:28:23 +01:00
|
|
|
Str::lower($Name),
|
|
|
|
|
Str::lower($Ext),
|
|
|
|
|
$Data
|
|
|
|
|
),
|
|
|
|
|
false
|
|
|
|
|
);
|
2022-12-06 10:24:00 +01:00
|
|
|
|
|
|
|
|
// * Closing the file will cause to remove it from temp dir!
|
|
|
|
|
fclose($tempFile);
|
|
|
|
|
|
|
|
|
|
return $filePath;
|
2022-03-09 17:28:23 +01:00
|
|
|
}
|
|
|
|
|
}
|