ldc-dam/app/Lib/ArcadiaLinkUtilities.php
2025-11-17 17:31:56 +01:00

294 lines
11 KiB
PHP

<?php
namespace App\Lib;
use App\Enums\EdiMouvementType;
use App\Models\ArcadiaLink;
use App\Models\Format;
use App\Models\Media;
use App\Scopes\SystemScope;
use DOMDocument;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class ArcadiaLinkUtilities
{
/**
* Create Media
*
* @param \App\Models\Media $media
* @return boolean
*/
public static function create(Media $media): bool
{
return self::sendMediaToArcadia($media, EdiMouvementType::create);
}
/**
* Update Media
*
* @param \App\Models\Media $media
* @return boolean
*/
public static function update(Media $media): bool
{
return self::sendMediaToArcadia($media, EdiMouvementType::update);
}
/**
* Delete Media
*
* @param \App\Models\Media $media
* @return boolean
*/
public static function delete(Media $media): bool
{
return self::sendMediaToArcadia($media, EdiMouvementType::delete);
}
/**
* Reactivate Media
*
* @param \App\Models\Media $media
* @return boolean
*/
public static function reactivate(Media $media): bool
{
return self::sendMediaToArcadia($media, EdiMouvementType::reactivate);
}
/**
* Send Media mouvement to Arcadia
*
* @param \App\Models\Media $media
* @param \App\Enums\EdiMouvementType $ediMouvementType
* @return boolean
*/
private static function sendMediaToArcadia(Media $media, EdiMouvementType $ediMouvementType): bool
{
if (
$ediMouvementType !== EdiMouvementType::create and
$media->arcadia_id === null and
!self::hasRequiredValues($media)
) {
return false;
}
$media->fresh();
$media->isLocked = true;
try {
if (
!($media->saveQuietly() and
self::compress(self::generateXml($media, $ediMouvementType), $media)
)
) {
return false;
}
/** @throws \RuntimeException */
$media->addToElasticSearch();
return true;
} catch (\RuntimeException | \Throwable $e) {
report($e);
return false;
}
}
/**
* Check has required values
*
* @param \App\Models\Media $media
* @return boolean
*/
private static function hasRequiredValues(Media $media): bool
{
$required = ['sujet_id', 'type_media_id', 'type_vue_id', 'variante_id', 'langue_id', 'version'];
foreach ($required as $v) {
if ($media->{$v} === null) {
return false;
}
}
return true;
}
/**
* Compress Xml File into zip
*
* @param string $xml
* @param \App\Models\Media $media
* @return boolean
*/
private static function compress(string $xml, Media $media): bool
{
/** @var \Illuminate\Filesystem\FilesystemAdapter */
$storage = Storage::disk('arcadia_link_s');
$uuid = Str::uuid();
$filename = "{$media->id}-{$uuid}.zip";
$zip = new \ZipArchive();
$success = $zip->open(
$storage->path($filename),
\ZipArchive::CREATE | \ZipArchive::OVERWRITE
);
$success = $zip->addFromString('media.xml', $xml) && $success;
$success = $zip->addFile($media->full_path, $media->basename) && $success;
$success = $zip->close() && $success;
unset($zip);
// On insert dans la table de supervision.
$arcadiaLink = new ArcadiaLink();
$arcadiaLink->media_id = $media->id;
if ($media->arcadia_id !== null) {
$arcadiaLink->arcadia_id = $media->arcadia_id;
}
$arcadiaLink->filename = $filename;
return $success and $arcadiaLink->save();
}
/**
* Generate Xml
*
* @param \App\Models\Media $media
* @param \App\Enums\EdiMouvementType $mouvement
* @return string
* @throws \RuntimeException If Generating XML Fails.
*/
private static function generateXml(Media $media, EdiMouvementType $mouvement): string
{
$refKey = self::getRefKey($media);
$formats = self::getFormats();
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;
try {
$root = $dom->createElement('MEDIA_VISUEL');
$dom->appendChild($root);
$root->appendChild($dom->createElement('codeArcadia'))
->appendChild($dom->createCDATASection("$media->arcadia_id"));
$root->appendChild($dom->createElement('code_DAM'))
->appendChild($dom->createCDATASection("$media->id"));
$root->appendChild($dom->createElement('TypeMouvement'))
->appendChild($dom->createCDATASection("$mouvement->value"));
$cleRef = $root->appendChild($dom->createElement('cle_Referentiel'));
foreach ($refKey as $model) {
if ($media->sujet_id === 1) {
$cleRef->appendChild($dom->createElement('id'))
->appendChild($dom->createCDATASection("$model->noArt"));
} elseif ($media->sujet_id === 2) {
$cleRef->appendChild($dom->createElement('id'))
->appendChild($dom->createCDATASection("$model->codMarq"));
} elseif ($media->sujet_id === 4) {
$cleRef->appendChild($dom->createElement('id'))
->appendChild($dom->createCDATASection("$model->id"));
}
}
$root->appendChild($dom->createElement('libExtension'))
->appendChild($dom->createCDATASection($media->extension->value));
$root->appendChild($dom->createElement('nbPxLargeur'))
->appendChild($dom->createCDATASection("$media->largeur"));
$root->appendChild($dom->createElement('largeurMm'))
->appendChild($dom->createCDATASection("$media->largeur_mm"));
$root->appendChild($dom->createElement('nbPxHauteur'))
->appendChild($dom->createCDATASection("$media->hauteur"));
$root->appendChild($dom->createElement('hauteurMm'))
->appendChild($dom->createCDATASection("$media->hauteur_mm"));
$root->appendChild($dom->createElement('pppLargeur'))
->appendChild($dom->createCDATASection("$media->resolution"));
$root->appendChild($dom->createElement('version'))
->appendChild($dom->createCDATASection("$media->version"));
$root->appendChild($dom->createElement('codeTypeMedia'))
->appendChild($dom->createCDATASection("$media->type_media_id"));
$root->appendChild($dom->createElement('codeTypeVue'))
->appendChild($dom->createCDATASection("$media->type_vue_id"));
$root->appendChild($dom->createElement('commentaire'))
->appendChild($dom->createCDATASection("$media->commentaire"));
$root->appendChild($dom->createElement('codeSujet'))
->appendChild($dom->createCDATASection("$media->sujet_id"));
$root->appendChild($dom->createElement('langue'))
->appendChild($dom->createCDATASection("$media->langue_id"));
$root->appendChild($dom->createElement('copyright'))
->appendChild($dom->createCDATASection("$media->copyright_id"));
$root->appendChild($dom->createElement('codeVariante'))
->appendChild($dom->createCDATASection("$media->variante_id"));
$root->appendChild($dom->createElement('dateCreation'))
->appendChild($dom->createCDATASection("$media->created_at"));
$root->appendChild($dom->createElement('dateModification'))
->appendChild($dom->createCDATASection("$media->updated_at"));
$root->appendChild($dom->createElement('datePublication'))
->appendChild($dom->createCDATASection("$media->published_at"));
$root->appendChild($dom->createElement('libelle'))
->appendChild($dom->createCDATASection("$media->libelle"));
$root->appendChild($dom->createElement('NomFichier'))
->appendChild($dom->createCDATASection("$media->uid.{$media->extension->value}"));
$mediaFormat = $root->appendChild($dom->createElement('formats'));
foreach ($formats as $formatModel) {
$format = $mediaFormat
->appendChild($dom->createElement('format'));
$format->appendChild($dom->createElement('id'))
->appendChild($dom->createCDATASection($formatModel['id']));
$format->appendChild($dom->createElement('libelle'))
->appendChild($dom->createCDATASection($formatModel['libelle']));
$format->appendChild($dom->createElement('extension'))
->appendChild($dom->createCDATASection($media->extension->value));
$format->appendChild($dom->createElement('largeur'))
->appendChild($dom->createCDATASection($formatModel['largeur']));
$format->appendChild($dom->createElement('hauteur'))
->appendChild($dom->createCDATASection($formatModel['hauteur']));
$format->appendChild($dom->createElement('lien'))
->appendChild($dom->createCDATASection(\sprintf(
"%s/{$media->folder}/{$media->uid}_%s.{$media->extension->value}",
config('app.url'),
$formatModel['libelle']
)));
}
} catch (\DOMException | \Exception $e) {
report($e);
throw new \RuntimeException('Failed to generate XML', 0, $e);
} //end try
if (!($xml = $dom->saveXML())) {
throw new \RuntimeException('Failed to generate XML');
}
return $xml;
}
/**
* Get Ref Key
*
* @param \App\Models\Media $media
* @return \Illuminate\Support\Collection<\App\Models\Article|\App\Models\Marque|\App\Models\Societe>
*/
public static function getRefKey(Media $media): Collection
{
switch ($media->sujet_id) {
case 1:
return $media->articles;
case 2:
return $media->marques;
case 4:
return $media->societes;
default:
return collect();
}
}
/**
* Get Formats
*
* @return \Illuminate\Support\Collection<\App\Models\Format>
*/
private static function getFormats(): Collection
{
return Format::withoutGlobalScope(SystemScope::class)
->where('system', true)->get();
}
}