ldc-legaulois/app/Jobs/XmlIncoReader.php
2023-06-26 16:02:23 +02:00

509 lines
19 KiB
PHP

<?php
namespace App\Jobs;
use App\Exceptions\AbortXmlImportException;
use App\Models\XmlInco;
use SimpleXMLElement;
class XmlIncoReader extends XmlJobs
{
protected $disk = 'inco';
protected $imagesPath = 'images';
protected $takeColumns = [
'NO_ART' => 'id',
// primary key on model
'ID_SOCIETE' => 'id_societe',
'NOM_SOCIETE' => 'nom_societe',
'PROD_SAISON' => 'prod_saison',
'NOM' => 'nom',
'NUMERO' => 'numero',
'TAILLE_REF' => 'taille_ref',
'ALLEGATIONS' => 'allegations',
'CONSEIL_PREPA' => 'conseil_prepa',
'ASTUCES' => 'astuces',
'DESCRIPTIF' => 'descriptif',
'ARG_VENTE' => 'arg_vente',
'NB_PORTION' => 'nb_portion',
'TYP_PORTION' => 'typ_portion',
'PDS_MOY_THEO' => 'pds_moy_theo',
'LIB_CONSO' => 'lib_conso',
'LST_ING' => 'lst_ing',
// list alergene
'LIB_ALLERGENE' => 'lib_allergene',
// Allegations
'ALLEGAT_SANTE' => 'allegat_sante',
'ALLEGAT_NUTRIT' => 'allegat_nutrit',
'ALLEGAT_AUTRE' => 'allegat_autre',
'INCO_COMPO' => 'inco_compo',
// Consider this sub array
'INCO_COMPO.VAL_ENERG_KJ_NUT' => 'val_energ_kj_nut',
'INCO_COMPO.VAL_ENERG_KJ_R' => 'val_energ_kj_r',
'INCO_COMPO.VAL_ENERG_KCAL_R' => 'val_energ_kcal_r',
'INCO_COMPO.VAL_ENERG_KCAL_NUT' => 'val_energ_kcal_nut',
'INCO_COMPO.MAT_GRASS_R' => 'mat_grass_r',
'INCO_COMPO.MAT_GRASS_NUT' => 'mat_grass_nut',
'INCO_COMPO.AGS_R' => 'ags_r',
'INCO_COMPO.AGS_NUT' => 'ags_nut',
'INCO_COMPO.GLUCIDES_R' => 'glucides_r',
'INCO_COMPO.GLUCIDES_NUT' => 'glucides_nut',
'INCO_COMPO.SUCRE_NUT' => 'sucre_nut',
'INCO_COMPO.SUCRE_R' => 'sucre_r',
'INCO_COMPO.FIB_ALIM_NUT' => 'fib_alim_nut',
'INCO_COMPO.FIB_ALIM_R' => 'fib_alim_r',
'INCO_COMPO.PROTEINE_R' => 'proteine_r',
'INCO_COMPO.PROTEINE_NUT' => 'proteine_nut',
'INCO_COMPO.SEL_R' => 'sel_r',
'INCO_COMPO.SEL_NUT' => 'sel_nut',
'INCO_COMPO.SODIUM_R' => 'sodium_r',
'INCO_COMPO.ENER_E14_R' => 'ener_e14_r',
'INCO_COMPO.FRUITS_R' => 'fruits_r',
'INCO_COMPO.FRUITS_COQUE_SECH_R' => 'fruits_coque_sech_r',
'INCO_COMPO.POURCENT_APPORT_REF_E14_R' => 'pourcent_apport_ref_e14_r',
'INCO_COMPO.ENER_KJO_R' => 'ener_kjo_r',
'INCO_COMPO.POURCENT_APPORT_REF_KJO_R' => 'pourcent_apport_ref_kjo_r',
'INCO_COMPO.POURCENT_APPORT_REF_FAT_R' => 'pourcent_apport_ref_fat_r',
'INCO_COMPO.FATSAT_R' => 'fatsat_r',
'INCO_COMPO.POURCENT_APPORT_REF_FATSAT_R' => 'pourcent_apport_ref_fatsat_r',
'INCO_COMPO.CHOVAL_R' => 'choval_r',
'INCO_COMPO.POURCENT_APPORT_REF_CHOVAL_R' => 'pourcent_apport_ref_choval_r',
'INCO_COMPO.SUGAR_R' => 'sugar_r',
'INCO_COMPO.POURCENT_APPORT_REF_SUGAR_R' => 'pourcent_apport_ref_sugar_r',
'INCO_COMPO.FIBTG_R' => 'fibtg_r',
'INCO_COMPO.POURCENT_APPORT_REF_FIBTG_R' => 'pourcent_apport_ref_fibtg_r',
'INCO_COMPO.PRO_R' => 'pro_r',
'INCO_COMPO.POURCENT_APPORT_REF_PRO_R' => 'pourcent_apport_ref_pro_r',
'INCO_COMPO.SALTEQ_R' => 'salteq_r',
'INCO_COMPO.POURCENT_APPORT_REF_SALTEQ_R' => 'pourcent_apport_ref_salteq_r',
'INCO_COMPO.APPORT_REF' => 'apport_ref',
'INCO_COMPO.TAILLE_PORT' => 'taille_port',
'INCO_COMPO.VAL_ENERG_KJ_P' => 'val_energ_kj_p',
'INCO_COMPO.VAL_ENERG_KCAL_P' => 'val_energ_kcal_p',
'INCO_COMPO.MAT_GRASS_P' => 'mat_grass_p',
'INCO_COMPO.AGS_P' => 'ags_p',
'INCO_COMPO.GLUCIDES_P' => 'glucides_p',
'INCO_COMPO.SUCRE_P' => 'sucre_p',
'INCO_COMPO.FIB_ALIM_P' => 'fib_alim_p',
'INCO_COMPO.PROTEINE_P' => 'proteine_p',
'INCO_COMPO.SODIUM_P' => 'sodium_p',
'INCO_COMPO.FRUITS_P' => 'fruits_p',
'INCO_COMPO.SEL_P' => 'sel_p',
'INCO_COMPO.FRUITS_COQUE_SECH_P' => 'fruits_coque_sech_p',
'INCO_COMPO.ENER_E14_P' => 'ener_e14_p',
'INCO_COMPO.POURCENT_APPORT_REF_E14_P' => 'pourcent_apport_ref_e14_p',
'INCO_COMPO.ENER_KJO_P' => 'ener_kjo_p',
'INCO_COMPO.POURCENT_APPORT_REF_KJO_P' => 'pourcent_apport_ref_kjo_p',
'INCO_COMPO.FAT_P' => 'fat_p',
'INCO_COMPO.POURCENT_APPORT_REF_FAT_P' => 'pourcent_apport_ref_fat_p',
'INCO_COMPO.FATSAT_P' => 'fatsat_p',
'INCO_COMPO.POURCENT_APPORT_REF_FATSAT_P' => 'pourcent_apport_ref_fatsat_p',
'INCO_COMPO.CHOVAL_P' => 'CHOVAL_P',
'INCO_COMPO.POURCENT_APPORT_REF_CHOVAL_P' => 'pourcent_apport_ref_choval_p',
'INCO_COMPO.SUGAR_P' => 'SUGAR_P',
'INCO_COMPO.POURCENT_APPORT_REF_SUGAR_P' => 'pourcent_apport_ref_sugar_p',
'INCO_COMPO.FIBTG_P' => 'fibtg_p',
'INCO_COMPO.POURCENT_APPORT_REF_FIBTG_P' => 'pourcent_apport_ref_fibtg_p',
'INCO_COMPO.PRO_P' => 'pro_p',
'INCO_COMPO.POURCENT_APPORT_REF_PRO_P' => 'pourcent_apport_ref_pro_p',
'INCO_COMPO.SALTEQ_P' => 'salteq_p',
'INCO_COMPO.POURCENT_APPORT_REF_SALTEQ_P' => 'pourcent_apport_ref_salteq_p',
'INCO_COMPO.APPORT_PORT' => 'apport_port',
'INCO_COMPO.PART_P' => 'part_p',
'INCO_COMPO.PART_G' => 'part_g',
'INCO_COMPO.PART_L' => 'part_l',
'INCO_COMPO.P_SUR_L' => 'p_sur_l',
'INCO_COMPO.POURCENT_AGS' => 'pourcent_ags',
'INCO_COMPO.POURCENT_AGI' => 'pourcent_agi',
'INCO_COMPO.POURCENT_SS' => 'pourcent_ss',
'INCO_COMPO.POURCENT_AMIDON' => 'pourcent_amidon',
'INCO_COMPO.COMPOSANTE_N' => 'composante_n',
'INCO_COMPO.COMPOSANTE_P' => 'composante_p',
'INCO_COMPO.POURCENT_FRUITS' => 'pourcent_fruits',
'INCO_COMPO.SCORE_NUTRI' => 'score_nutri',
'INCO_COMPO.CLASSEMENT' => 'classement',
'INCO_COMPO.MAT_GRASS_R_PREC' => 'mat_grass_r_prec',
'INCO_COMPO.AGS_R_PREC' => 'ags_r_prec',
'INCO_COMPO.GLUCIDES_R_PREC' => 'glucides_r_prec',
'INCO_COMPO.SUCRE_R_PREC' => 'sucre_r_prec',
'INCO_COMPO.FIB_ALIM_R_PREC' => 'fib_alim_r_prec',
'INCO_COMPO.PROTEINE_R_PREC' => 'proteine_r_prec',
'INCO_COMPO.SEL_R_PREC' => 'sel_r_prec',
'INCO_COMPO.SODIUM_R_PREC' => 'sodium_r_prec',
'INCO_COMPO.FRUITS_R_PREC' => 'fruits_r_prec',
'INCO_COMPO.FRUITS_COQUE_SECH_R_PREC' => 'fruits_coque_sech_r_prec',
];
protected $nullableFields = [
'taille_ref',
'conseil_prepa',
'typ_portion',
'nb_portion',
'descriptif',
'prod_saison',
'allegations',
'astuces', 'arg_vente',
'pds_moy_theo',
'lib_conso', 'lst_ing',
'allegat_sante', 'allegat_nutrit', 'allegat_autre',
'inco_compo',
'inco_compo.nom',
'inco_compo.numero',
'inco_compo.taille',
'inco_compo.taille_ref',
'inco_compo.val_energ_kj_nut',
'inco_compo.val_energ_kj_r',
'inco_compo.val_energ_kcal_r',
'inco_compo.val_energ_kcal_nut',
'inco_compo.mat_grass_r',
'inco_compo.mat_grass_nut',
'inco_compo.ags_r',
'inco_compo.ags_nut',
'inco_compo.glucides_r',
'inco_compo.glucides_nut',
'inco_compo.sucre_nut',
'inco_compo.sucre_r',
'inco_compo.fib_alim_nut',
'inco_compo.fib_alim_r',
'inco_compo.proteine_r',
'inco_compo.proteine_nut',
'inco_compo.sel_r',
'inco_compo.sel_nut',
'inco_compo.sodium_r',
'inco_compo.ener_e14_r',
'inco_compo.fruits_r',
'inco_compo.fruits_coque_sech_r',
'inco_compo.pourcent_apport_ref_e14_r',
'inco_compo.ener_kjo_r',
'inco_compo.pourcent_apport_ref_kjo_r',
'inco_compo.pourcent_apport_ref_fat_r',
'inco_compo.fatsat_r',
'inco_compo.pourcent_apport_ref_fatsat_r',
'inco_compo.choval_r',
'inco_compo.pourcent_apport_ref_choval_r',
'inco_compo.sugar_r',
'inco_compo.pourcent_apport_ref_sugar_r',
'inco_compo.fibtg_r',
'inco_compo.pourcent_apport_ref_fibtg_r',
'inco_compo.pro_r',
'inco_compo.pourcent_apport_ref_pro_r',
'inco_compo.salteq_r',
'inco_compo.pourcent_apport_ref_salteq_r',
'inco_compo.apport_ref',
'inco_compo.taille_port',
'inco_compo.val_energ_kj_p',
'inco_compo.val_energ_kcal_p',
'inco_compo.mat_grass_p',
'inco_compo.ags_p',
'inco_compo.glucides_p',
'inco_compo.sucre_p',
'inco_compo.fib_alim_p',
'inco_compo.proteine_p',
'inco_compo.sodium_p',
'inco_compo.fruits_p',
'inco_compo.sel_p',
'inco_compo.fruits_coque_sech_p',
'inco_compo.ener_e14_p',
'inco_compo.pourcent_apport_ref_e14_p',
'inco_compo.ener_kjo_p',
'inco_compo.pourcent_apport_ref_kjo_p',
'inco_compo.fat_p',
'inco_compo.pourcent_apport_ref_fat_p',
'inco_compo.fatsat_p',
'inco_compo.pourcent_apport_ref_fatsat_p',
'inco_compo.choval_p',
'inco_compo.pourcent_apport_ref_choval_p',
'inco_compo.sugar_p',
'inco_compo.pourcent_apport_ref_sugar_p',
'inco_compo.fibtg_p',
'inco_compo.pourcent_apport_ref_fibtg_p',
'inco_compo.pro_p',
'inco_compo.pourcent_apport_ref_pro_p',
'inco_compo.salteq_p',
'inco_compo.pourcent_apport_ref_salteq_p',
'inco_compo.apport_port',
'inco_compo.part_p',
'inco_compo.part_g',
'inco_compo.part_l',
'inco_compo.p_sur_l',
'inco_compo.pourcent_ags',
'inco_compo.pourcent_agi',
'inco_compo.pourcent_ss',
'inco_compo.pourcent_amidon',
'inco_compo.composante_n',
'inco_compo.composante_p',
'inco_compo.pourcent_fruits',
'inco_compo.score_nutri',
'inco_compo.classement',
'inco_compo.mat_grass_r_prec',
'inco_compo.ags_r_prec',
'inco_compo.glucides_r_prec',
'inco_compo.sucre_r_prec',
'inco_compo.fib_alim_r_prec',
'inco_compo.proteine_r_prec',
'inco_compo.sel_r_prec',
'inco_compo.sodium_r_prec',
'inco_compo.fruits_r_prec',
'inco_compo.fruits_coque_sech_r_prec'
];
protected $uniqueKeyField = ['id'];
protected $mergeColumns = [
'allegations' => [
'allegat_sante',
'allegat_nutrit',
'allegat_autre'
],
'nutritional_values' => [
'val_energ_kj_nut',
'val_energ_kj_r',
'val_energ_kcal_r',
'val_energ_kcal_nut',
'mat_grass_r',
'mat_grass_nut',
'ags_r',
'ags_nut',
'glucides_r',
'glucides_nut',
'sucre_nut',
'sucre_r',
'fib_alim_nut',
'fib_alim_r',
'proteine_r',
'proteine_nut',
'sel_r',
'sel_nut',
'sodium_r',
'ener_e14_r',
'fruits_r',
'fruits_coque_sech_r',
'pourcent_apport_ref_e14_r',
'ener_kjo_r',
'pourcent_apport_ref_kjo_r',
'pourcent_apport_ref_fat_r',
'fatsat_r',
'pourcent_apport_ref_fatsat_r',
'choval_r',
'pourcent_apport_ref_choval_r',
'sugar_r',
'pourcent_apport_ref_sugar_r',
'fibtg_r',
'pourcent_apport_ref_fibtg_r',
'pro_r',
'pourcent_apport_ref_pro_r',
'salteq_r',
'pourcent_apport_ref_salteq_r',
'apport_ref',
'taille_port',
'val_energ_kj_p',
'val_energ_kcal_p',
'mat_grass_p',
'ags_p',
'glucides_p',
'sucre_p',
'fib_alim_p',
'proteine_p',
'sodium_p',
'fruits_p',
'sel_p',
'fruits_coque_sech_p',
'ener_e14_p',
'pourcent_apport_ref_e14_p',
'ener_kjo_p',
'pourcent_apport_ref_kjo_p',
'fat_p',
'pourcent_apport_ref_fat_p',
'fatsat_p',
'pourcent_apport_ref_fatsat_p',
'choval_p',
'pourcent_apport_ref_choval_p',
'sugar_p',
'pourcent_apport_ref_sugar_p',
'fibtg_p',
'pourcent_apport_ref_fibtg_p',
'pro_p',
'pourcent_apport_ref_pro_p',
'salteq_p',
'pourcent_apport_ref_salteq_p',
'apport_port',
'part_p',
'part_g',
'part_l',
'p_sur_l',
'pourcent_ags',
'pourcent_agi',
'pourcent_ss',
'pourcent_amidon',
'composante_n',
'composante_p',
'pourcent_fruits',
'score_nutri',
'classement',
'mat_grass_r_prec',
'ags_r_prec',
'glucides_r_prec',
'sucre_r_prec',
'fib_alim_r_prec',
'proteine_r_prec',
'sel_r_prec',
'sodium_r_prec',
'fruits_r_prec',
'fruits_coque_sech_r_prec',
]
];
public function handle()
{
$this->parseData('INCO', XmlInco::class, function (SimpleXMLElement $xmlData, array &$line) {
// merge columns
foreach ($this->mergeColumns as $key => $values) {
$line[$key] = [];
// merge columns and remove merged columns from line
array_map(function ($kValue) use (&$line, $key) {
if (array_key_exists($kValue, $line)) {
$line[$key][$kValue] = $line[$kValue];
unset($line[$kValue]);
}
}, $values);
if ($key == 'allegations') {
$line[$key] = implode(',', array_filter($line[$key]));
$line[$key] = strlen($line[$key]) ? $line[$key] : null;
}
if ($key == 'nutritional_values') {
$line[$key] = json_encode($line[$key], \JSON_FORCE_OBJECT);
}
}
// Boolean cast prod_saison
$line['prod_saison'] = isset($line['prod_saison']) ?
(strtolower($line['prod_saison']) == 'non' ? false : true) : false;
$imageFileName = $this->parseImage($xmlData);
$line['picture'] = '/storage/images/inco_default.png';
// Ajout du chemin de l'image dans les champs a envoyé en base
if ($imageFileName !== null) {
$line['picture'] = sprintf('%s/%s', $this->disk, $imageFileName);
}
});
}
private function parseImage(SimpleXMLElement $xmlData)
{
$imagesArray = $xmlData->INCO->MEDIA_VISUEL_EAI->MEDIA_VISUEL_EAI->img;
$imagesArray = \is_iterable($imagesArray) ? $imagesArray : [$imagesArray];
foreach ($imagesArray as $image) {
$imageData = trim((string)$image);
if (strlen($imageData)) {
$imageData = base64_decode($imageData);
$imgName = strval($xmlData->INCO->NO_ART);
$imgNamePath = sprintf('%s/%s', rtrim($this->imagesPath, '/'), $imgName);
$disk = $this->getDisk();
$info = getimagesizefromstring($imageData);
$mime = $info['mime'];
$imgExtension = null;
switch ($mime) {
case 'image/jpeg':
$imgExtension = 'jpg';
break;
case 'image/png':
$imgExtension = 'png';
break;
case 'image/gif':
$imgExtension = 'gif';
break;
default:
// On va ignorer au lieu de se faire chier a tout réécrire
// pour itérer sur toutes les images
// et juste ne pas prendre l'image, on laissera ça à incollector
// throw new AbortXmlImportException(sprintf(
// 'Unknown image type on %s : raw data %s',
// $imgName,
// \json_encode($info)
// ));
break;
}//end switch
if (!$imgExtension) {
continue;
}
$imgNamePath = sprintf('%s.%s', $imgNamePath, $imgExtension);
if (!$disk->put($imgNamePath, $imageData)) {
throw new AbortXmlImportException(sprintf('The image %s could not be saved', $imgNamePath));
}
return $imgNamePath;
}//end if
}//end foreach
return null;
}
/**
* Recursive extract to array
* introduce sort of Hook to transform
* <TYP_PORTION>
* <code><![CDATA[2]]></code>
* <libelle><![CDATA[Approximatif]]></libelle>
* </TYP_PORTION>
* extracted as "TYP_PORTION" => array:1 [
* 0 => array:2 [
* "code" => "2"
* "libelle" => "Approximatif"
* ]
* ]
* into this
* <TYP_PORTION><![CDATA[Approximatif]]></TYP_PORTION>
* extracted as "TYP_PORTION" => "Approximatif"
*
* @param \SimpleXMLElement|false $sxe
* @return array
*/
protected function extract($sxe = null): array
{
if (!$sxe instanceof SimpleXMLElement) {
return array();
}
$extract = array();
foreach ($sxe->children() as $key => $value) {
if ($value->count()) {
$extraction = $this->extract($value);
if (
count($extraction)
&& array_key_exists("code", $extraction)
&& array_key_exists("libelle", $extraction)
) {
$val = strval($extraction['libelle']);
$extract[$key] = strlen($val) ? $val : null;
continue;
}
$extract[$key][] = $extraction;
// $this->extract($value);
continue;
}
$value = strval($value);
if (array_key_exists($key, $extract) and is_array($extract[$key])) {
$extract[$key][] = strlen($value) ? $value : null;
} else {
$extract[$key] = strlen($value) ? $value : null;
}
}//end foreach
return $extract;
}
}