File: D:/HostingSpaces/SBogers10/zelfverkopen.komma.pro/app/KommaApp/Realworks/Kms/RealWorksService.php
<?php
namespace App\KommaApp\Realworks\Kms;
use App\KommaApp\Kms\Core\Attributes\Attribute;
use App\KommaApp\Kms\Core\NestedSets\Nodes\EloquentNode;
use App\KommaApp\Kms\Core\Sections\SectionService;
use App\KommaApp\Kms\Core\Sections\SectionTabItem;
use App\KommaApp\Languages\Models\Language;
use App\KommaApp\Pages\Models\Page;
use App\KommaApp\Realworks\Models\Huur;
use App\KommaApp\Realworks\Models\HuurTranslation;
use App\KommaApp\Realworks\Models\Koop;
use App\KommaApp\Realworks\Models\KoopTranslation;
use App\KommaApp\Realworks\Models\RealworkObject;
use App\KommaApp\Realworks\Models\ObjectDetails;
use App\KommaApp\Realworks\Models\ObjectDetailsTranslation;
use App\Mail\RealworksFailMail;
use Carbon\Carbon;
use function GuzzleHttp\Psr7\str;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\Log;
use ZipArchive;
class RealWorksService extends SectionService
{
protected $sortable = true;
protected static $DOWNLOAD_FOLDER_NAME = 'download'; //without trailing slash
protected static $XML_FILE_NAME = 'voorbeeld.wonen'; //without extension
function __construct()
{
$this->forModelName = Page::class; //TODO Change me
parent::__construct();
}
/**
* Downloads the zipped xml from Realworks.
*
* Warning. Strict regulations by Realworks apply. Please check their documentation for the latest info on those
* regulations. At the time of writing they are:
*
* - Only call the api once a day after 08:30 in the morning.
* - The media that is defined in the xml must be downloaded for displaying.
*/
public function DownloadZipWithXML()
{
$storageFolder = $this->createAndGetRealworksStorageFolder(self::$DOWNLOAD_FOLDER_NAME);
$url = $this->getUrl();
try {
$file = file_get_contents($url);
}
catch (\Exception $exception)
{
$this->mailOrShowErrorAndDie('Could not save downloaded realworks zip');
}
$zipPath = $storageFolder.config('realworks.zip_name', 'realworks').'.zip';
if(file_put_contents($zipPath,$file) === false) $this->mailOrShowErrorAndDie('Could not save downloaded realworks zip ("'.$zipPath.'")');
}
/**
* Extracts the realworks zip and deletes the zip file
*/
public function ProcessZip()
{
$storageFolder = $this->createAndGetRealworksStorageFolder(self::$DOWNLOAD_FOLDER_NAME);
$zipPath = $storageFolder.config('realworks.zip_name', 'realworks').'.zip';
$zip = new ZipArchive;
if ($zip->open($zipPath) === true) {
$zip->extractTo($storageFolder);
$zip->close();
if(unlink($zipPath) === false) $this->mailOrShowErrorAndDie('Could delete realworks zip file after extraction: '.$zipPath);
} else {
$this->mailOrShowErrorAndDie('Could not extract realworks zip file: '.$zipPath);
}
}
/**
* Clears the storage folder in which the downloaded zip and its extracted data is placed
*/
public function ClearDownloadFolder()
{
RealWorksService::rrmdir($this->createAndGetRealworksStorageFolder(self::$DOWNLOAD_FOLDER_NAME), false);
}
/**
* MUST be triggered by App\Console\Kernel to update Realworks api stuff.
*/
public function executeSchedule()
{
$this->ClearDownloadFolder();
$this->DownloadZipWithXML(); //WARNING! Only runnable once a day. Else we will get fined!
$this->ProcessZip();
$xml = $this->DownloadedXMLToArray();
$this->DownloadMediaFromXMLToPublicFolders($xml); //WARNING! Only runnable once a day. Else we will get fined!
$this->storeObjectsInDatabase($xml);
$this->deleteObjectsFromDatabaseThatArentListedInXML($xml);
$this->deletePublicFoldersFromNonExistingObjects();
// Only for test purpose this weekend instead of the real
// \Mail::send('site.emails.propertyDataError', [
// 'propertyId' => 0,
// 'dataTail' => 'Schedular test',
// 'errorType' => 0,
// 'errorString' => 'Schedular test',
// 'variable' => 'Schedular test'
// ], function ($message){
// $message->from(\Config::get('mail.from.address'), \Config::get('mail.from.name'));
// $message->to(\Config::get('mail.admin.address'));
//
// // Set subject
// $message->subject('Schedular test');
// });
}
/**
* Stores the properties in the database by using the xml
*
* @param array $xml
*/
public function storeObjectsInDatabase(array $xml)
{
if(!array_key_exists('Object', $xml)) return; //Empty
foreach($xml['Object'] as $objectArray)
{
$object = $this->createObjectFromXML($objectArray);
}
}
/**
* Creates an object model from the input xml data
*
* @param $xml
* @return RealworkObject|null
*/
private function createObjectFromXML(array $xml): ?RealworkObject
{
if(!isset($xml['ObjectSystemID'])) $this->mailOrShowErrorAndDie('An object did not have the required ObjectSystemID key. Stopped processing');
$dutchLanguage = Language::where('native_name', '=', 'Nederlands')->first();
if(!$dutchLanguage) $this->mailOrShowErrorAndDie('The dutch language did not exists. The object details could not be created. Stopped processing');
$object = RealworkObject::where('system_id', '=', $xml['ObjectSystemID'])->first();
if(!$object) $object = new RealworkObject();
$object->raw_json = json_encode($xml);
if(isset($xml['NVMVestigingNR'])) $object->nvm_vestiging_nummer = $xml['NVMVestigingNR'];
if(isset($xml['ObjectCompany'])) $object->company = $xml['ObjectCompany'];
if(isset($xml['ObjectAfdeling'])) $object->afdeling = $xml['ObjectAfdeling'];
if(isset($xml['ObjectTiaraID'])) $object->tiara_id = $xml['ObjectTiaraID'];
if(isset($xml['ObjectSystemID'])) $object->system_id = $xml['ObjectSystemID'];
if(isset($xml['ObjectCode'])) $object->code = $xml['ObjectCode'];
if(!isset($xml['ObjectDetails'])) $this->mailOrShowErrorAndDie('An object did not contain object details. Stopped processing');
$object->save();
/** @var ObjectDetailsTranslation $objectDetailsTranslation */
$objectDetailsTranslation = $this->createObjectDetailsFromXML($xml['ObjectDetails'], $object, $dutchLanguage)->translations->first();
$object->public_path = $this->getPublicFolderPathForObject($object->system_id, $objectDetailsTranslation->woonplaats, $objectDetailsTranslation->straatnaam, $objectDetailsTranslation->huisnummer);
$object->public_path = str_replace(public_path(), '', $object->public_path);
$object->public_path = str_replace('\\', '/', $object->public_path);
$object->save();
return $object;
}
/**
* Creates an object details model from the input xml data
*
* @param array $xml
* @param RealworkObject $object
* @param Language $language
* @return ObjectDetails
*/
private function createObjectDetailsFromXML(array $xml, RealworkObject $object, Language $language): ObjectDetails {
/** @var ObjectDetails $objectDetails */
$objectDetails = $object->objectDetails()->first();
if($objectDetails) {
//Check if the object was updated yesterday. If not we are going to skip it
$updateDate = Carbon::createFromFormat('Y-m-d', $xml['DatumWijziging']);
$now = Carbon::now();
$now = Carbon::create($now->year, $now->month, $now->day);
$needsUpdate = ($updateDate && $now->subDay()->equalTo($updateDate)) ? true: false;
if(!$needsUpdate) return $objectDetails;
}
if(!$objectDetails) {
$objectDetails = new ObjectDetails();
$objectDetails->object()->associate($object);
$objectDetails->save();
}
$objectDetailsTranslation = $objectDetails->translations()->where('language_id', '=', $language->id)->first();
if(!$objectDetailsTranslation) {
$objectDetailsTranslation = new ObjectDetailsTranslation();
$objectDetailsTranslation->translatable()->associate($objectDetails);
$objectDetailsTranslation->language()->associate($language);
}
if(isset($xml['Adres']) && isset($xml['Adres']['Nederlands'])) {
$adresData = $xml['Adres']['Nederlands'];
if (isset($adresData['Straatnaam'])) $objectDetailsTranslation->straatnaam = $adresData['Straatnaam'];
if (isset($adresData['Huisnummer'])) $objectDetailsTranslation->huisnummer = $adresData['Huisnummer'];
if (isset($adresData['HuisnummerToevoeging'])) $objectDetailsTranslation->huisnummer_toevoeging = $adresData['HuisnummerToevoeging'];
if (isset($adresData['Postcode'])) $objectDetailsTranslation->postcode = $adresData['Postcode'];
if (isset($adresData['Woonplaats'])) $objectDetailsTranslation->woonplaats = $adresData['Woonplaats'];
if (isset($adresData['Land'])) $objectDetailsTranslation->land = $adresData['Land'];
}
if (isset($xml['Aanvaarding'])) $objectDetailsTranslation->aanvaarding = $xml['Aanvaarding'];
if (isset($xml['DatumAanvaarding'])) $objectDetailsTranslation->toelichting_aanvaarding = $xml['DatumAanvaarding'];
if (isset($xml['ToelichtingAanvaarding'])) $objectDetailsTranslation->toelichting_aanvaarding = $xml['ToelichtingAanvaarding'];
if (isset($xml['DatumAanvaarding'])) $objectDetailsTranslation->datum_aanvaarding = Carbon::createFromFormat('Y-m-d', $xml['DatumAanvaarding']);
if (isset($xml['ObjectAanmelding'])) $objectDetailsTranslation->object_aanmelding = $xml['ObjectAanmelding'];
if (isset($xml['DatumInvoer'])) $objectDetailsTranslation->datum_invoer = Carbon::createFromFormat('Y-m-d', $xml['DatumInvoer']);
if (isset($xml['DatumWijziging'])) $objectDetailsTranslation->datum_wijziging = Carbon::createFromFormat('Y-m-d', $xml['DatumWijziging']);
if (isset($xml['DatumVeiling'])) $objectDetailsTranslation->datum_veiling = Carbon::createFromFormat('Y-m-d', $xml['DatumVeiling']);
if (isset($xml['StatusBeschikbaarheid'])) {
$statusBeschikbaarheid = $xml['StatusBeschikbaarheid'];
if (isset($statusBeschikbaarheid['Status'])) $objectDetailsTranslation->status_beschikbaarheid = $statusBeschikbaarheid['Status'];
if (isset($statusBeschikbaarheid['VerkochtOnderVoorbehoud'])) {
$verkochtOnderVoorbehoud = $statusBeschikbaarheid['VerkochtOnderVoorbehoud'];
if(isset($verkochtOnderVoorbehoud['Datum'])) $objectDetailsTranslation->status_verkocht_onder_voorbehoud_datum = Carbon::createFromFormat('Y-m-d', $verkochtOnderVoorbehoud['Datum']);
if(isset($verkochtOnderVoorbehoud['DatumVoorbehoudTot'])) $objectDetailsTranslation->status_verkocht_onder_voorbehoud_datum_tot = Carbon::createFromFormat('Y-m-d', $verkochtOnderVoorbehoud['DatumVoorbehoudTot']);
}
if (isset($statusBeschikbaarheid['TransactieDatum'])) $objectDetailsTranslation->status_transactie_datum = Carbon::createFromFormat('Y-m-d', $statusBeschikbaarheid['TransactieDatum']);
}
if (isset($xml['Bouwvorm'])) $objectDetailsTranslation->bouwvorm = $xml['Bouwvorm'];
if (isset($xml['Aanbiedingstekst'])) $objectDetailsTranslation->aanbiedingstekst = $xml['Aanbiedingstekst'];
$objectDetailsTranslation->save();
if(isset($xml['Koop'])) $this->createKoopFromXML($xml['Koop'], $objectDetails, $language);
if(isset($xml['Huur'])) $this->createHuurFromXml($xml['Huur'], $objectDetails, $language);
return $objectDetails;
}
private function createKoopFromXML(array $xml, ObjectDetails $objectDetails, Language $language): Koop
{
$koop = $objectDetails->koop()->first();
if(!$koop) {
$koop = new Koop();
$koop->objectDetails()->associate($objectDetails);
$koop->save();
}
$koopTranslation = $koop->translations()->where('language_id', '=', $language->id)->first();
if(!$koopTranslation) {
$koopTranslation = new KoopTranslation();
$koopTranslation->translatable()->associate($koop);
$koopTranslation->language()->associate($language);
}
if (isset($xml['Prijsvoorvoegsel'])) $koopTranslation->prijs_voorvoegsel = $xml['Prijsvoorvoegsel'];
if (isset($xml['Koopprijs'])) $koopTranslation->koop_prijs = $xml['Koopprijs'];
if (isset($xml['KoopConditie'])) $koopTranslation->koop_conditie = $xml['KoopConditie'];
if (isset($xml['KoopSpecificatie'])) $koopTranslation->koop_specificatie = $xml['KoopSpecificatie'];
if (isset($xml['WOZ'])) {
$woz = $xml['WOZ'];
if (isset($woz['WOZWaarde'])) $koopTranslation->woz_waarde = $woz['WOZWaarde'];
if (isset($woz['WOZWaardePeildatum'])) $koopTranslation->woz_waarde_peildatum = Carbon::createFromFormat('Y-m-d', $woz['WOZWaardePeildatum']);
}
$koopTranslation->save();
return $koop;
}
private function createHuurFromXml(array $xml, ObjectDetails $objectDetails, Language $language): Huur
{
$huur = $objectDetails->huur()->first();
if(!$huur) {
$huur = new Huur();
$huur->objectDetails()->associate($objectDetails);
$huur->save();
}
$huurTranslation = $huur->translations()->where('language_id', '=', $language->id)->first();
if(!$huurTranslation) {
$huurTranslation = new HuurTranslation();
$huurTranslation->translatable()->associate($huur);
$huurTranslation->language()->associate($language);
}
if (isset($xml['Huurprijs'])) $huurTranslation->huur_prijs = $xml['Huurprijs'];
if (isset($xml['HuurConditie'])) $huurTranslation->huur_conditie = $xml['HuurConditie'];
if (isset($xml['HuurSpecificatie'])) $huurTranslation->huur_specificatie = $xml['HuurSpecificatie'];
$huurTranslation->save();
return $huur;
}
/**
* Parses the XML into an PHP array that we can use for further processing
*
* @return array
*/
public function DownloadedXMLToArray():array
{
$storageFolder = $this->createAndGetRealworksStorageFolder(self::$DOWNLOAD_FOLDER_NAME);
$exampleFileName = self::$XML_FILE_NAME.'.xml';
$realFileName = $this->getTodaysXMLFileName();
$fileName = (file_exists($storageFolder.DIRECTORY_SEPARATOR.$realFileName)) ? $realFileName : $exampleFileName;
$xmlFile = file_get_contents($storageFolder.DIRECTORY_SEPARATOR.$fileName);
$xml = simplexml_load_string($xmlFile, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json,true);
// Log::debug($array);
return $array;
}
private function getTodaysXMLFileName():string
{
return 'WONEN_'.date('Y').date('m').date('d').'.xml';
}
/**
* Downloads all media from the given xml and passes it into a public folder
* @param array $xml
*/
private function DownloadMediaFromXMLToPublicFolders(array $xml)
{
$this->createAndGetPublicRealworksFolder();
if(!array_key_exists('Object', $xml)) return; //Empty
foreach($xml['Object'] as $objectArray)
{
$this->downloadMediaListIfNotAlreadyFromObjectAndReturnMediaArray($objectArray);
}
}
/**
* @param string $objectSystemId
* @param string $place
* @param string $street
* @param string $houseNumber
* @return string
*/
public function getPublicFolderPathForObject(string $objectSystemId, string $place, string $street, string $houseNumber)
{
$folder = \Str::slug( $place.'-'.$street.'-'.$houseNumber.'-'.$objectSystemId);
$rootFolder = $this->createAndGetPublicRealworksFolder($folder);
return $rootFolder;
}
/**
* Downloads every file from the MediaLijst array inside the given object and returns the MediaLijst array after that
*
* @param array $object
* @return array|mixed
*/
private function downloadMediaListIfNotAlreadyFromObjectAndReturnMediaArray(array $object)
{
$mediaReturnArray = [];
if(isset($object['MediaLijst']) && isset($object['ObjectSystemID']) && isset($object['ObjectDetails']))
{
//Validation
if(!is_array($object['MediaLijst'])) $this->mailOnError('At least one MediaLijst entry in the Realworks xml wasn\'t an array. Needs direct fix');
if(!is_array($object['ObjectDetails'])) $this->mailOnError('At least one ObjectDetails entry in the Realworks xml wasn\'t an array. Needs direct fix');
if(!is_string($object['ObjectSystemID'])) $this->mailOnError('At least one ObjectSystemID entry in the Realworks xml wasn\'t a string. Needs direct fix');
if(!isset($object['ObjectDetails']['Adres']) || !isset($object['ObjectDetails']['Adres']['Nederlands']))
$this->mailOnError('At least one ObjectDetails entry in the Realworks xml wasn\'t properly formatted. Expecting keys ObjectDetails > Adres > Nederlands. Needs direct fix');
$addressArray = $object['ObjectDetails']['Adres']['Nederlands'];
if(!is_array($addressArray)) $this->mailOnError('At least one ObjectDetails > Adres > Nederlands entry in the Realworks xml wasn\'t an array. Needs direct fix');
// dd(array_keys($addressArray));
if(count(array_diff(['Straatnaam', 'Huisnummer', 'Postcode', 'Woonplaats', 'Land'], array_keys($addressArray))) > 0)
$this->mailOnError("At least one ObjectDetails > Adres > Nederlands entry in the Realworks xml did not contain all keys: 'Straatnaam', 'Huisnummer', 'Postcode', 'Woonplaats', 'Land'. Needs direct fix ".json_encode($addressArray));
// dd($object);
// dd(array_keys($object));
// dd(array_values($object));
foreach($object['MediaLijst'] as $index => $mediaArrays) {
foreach($mediaArrays as $mediaArray)
{
if(!isset($mediaArray['Groep'])) $this->mailOnError("At least one MediaLijst item did not have 'Groep' set. ".json_encode($mediaArray));
$propertyFolder = $this->getPublicFolderPathForObject($object['ObjectSystemID'], $addressArray['Woonplaats'], $addressArray['Straatnaam'], $addressArray['Huisnummer']);
$groupFolder = self::createFolderIfNotExitsOrFail($propertyFolder.DIRECTORY_SEPARATOR.$mediaArray['Groep']);
$url = trim($mediaArray['URL']);
$filenameWithExtension = self::getFilenameFromUrl($url);
$filePath = $groupFolder.DIRECTORY_SEPARATOR.$index.'_'.$filenameWithExtension;
//Check if the media was updated yesterday. If so we also need to refresh the image
$mediaUpdate = Carbon::createFromFormat('Y-m-d', $mediaArray['MediaUpdate']);
$now = Carbon::now();
$now = Carbon::create($now->year, $now->month, $now->day);
$needsUpdate = ($mediaUpdate && $now->subDay()->equalTo($mediaUpdate)) ? true: false;
if($needsUpdate) Log::debug('Going to download the following media item again since it was was updated yesterday: '.$url);
if(!file_exists($filePath) || $needsUpdate) {
try {
$file = file_get_contents($url);
} catch(\Exception $exception) {
Log::debug('Tried to download a media file defined in the realworks xml but failed ('.$exception->getMessage().'): '.$url);
continue;
}
if(file_put_contents($filePath, $file) === false) $this->mailOnError('Could not store downloaded media file to path: '.$filePath);
}
}
}
return $object['MediaLijst'];
}
return [];
}
private function getUrl()
{
$base = config('realworks.api_url');
$queryParameters = [
'koppeling' => 'WEBSITE',
'user' => config('realworks.api_username'),
'password' => config('realworks.api_password'),
'og' => config('realworks.api_og_value'),
];
if(config('realworks.api_documentation') == "true") $queryParameters['documentatie'] = "true";
if(config('realworks.api_connected') == "true") $queryParameters['connected'] = "true";
if(config('realworks.api_version')) $queryParameters['versie'] = config('realworks.api_version');
if(config('realworks.api_office')) $queryParameters['kantoor'] = config('realworks.api_office');
//String "true" or "false" from config is changed into a real true or false. Putting that in the http_build_query causes it to change to 0 or 1. While realworks expects "true" or "false" for boolean
foreach($queryParameters as $index => $parameter)
{
if($parameter === true) $queryParameters[$index] = "true";
else if($parameter === false) $queryParameters[$index] = "false";
}
$url = $base.'?'.http_build_query($queryParameters);
return $url;
}
/**
* @param string $url
* @return mixed
*/
public static function getFilenameFromUrl(string $url)
{
$path = parse_url($url, PHP_URL_PATH);
$exploded = explode('/', $path);
return last($exploded);
}
/**
* Creates a folder for the realworks zip and it's contents in laravels storage folder if needed and returns its absolute path
*
* @param string|null $subFolder
* @return string
*/
private static function createAndGetRealworksStorageFolder(string $subFolder = null):string
{
$folder = storage_path().DIRECTORY_SEPARATOR.config('realworks.storagefolder_name', 'realworks').DIRECTORY_SEPARATOR;
self::createFolderIfNotExitsOrFail($folder);
if($subFolder)
{
$absoluteSubFolder = self::createFolderIfNotExitsOrFail($folder.$subFolder);
return $absoluteSubFolder;
}
return $folder;
}
/**
* Creates a public folder for the frontend
*
* @param string|null $subFolder
* @return string
*/
private static function createAndGetPublicRealworksFolder(string $subFolder = null):string
{
$folder = public_path().DIRECTORY_SEPARATOR.config('realworks.storagefolder_name', 'realworks').DIRECTORY_SEPARATOR;
self::createFolderIfNotExitsOrFail($folder);
if($subFolder)
{
$absoluteSubFolder = $folder.$subFolder.DIRECTORY_SEPARATOR;
self::createFolderIfNotExitsOrFail($absoluteSubFolder);
return $absoluteSubFolder;
}
return $folder;
}
/**
* @param $folder
* @return mixed
*/
private static function createFolderIfNotExitsOrFail($folder)
{
if(!file_exists($folder)) {
if(!mkdir($folder, 0777, true)) throw new \RuntimeException('The realworks folder could not be created. '.$folder);
}
return $folder;
}
/**
* Recursively deletes a the contents in a directory and if you specify the boolean argument to true the directory itself too
*
* @param $dir
* @param bool $deleteDir
*/
private static function rrmdir($dir, $deleteDir = true) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir.DIRECTORY_SEPARATOR.$object) == "dir")
self::rrmdir($dir.DIRECTORY_SEPARATOR.$object);
else {
if(!unlink($dir.DIRECTORY_SEPARATOR.$object)) throw new \RuntimeException('Could not empty the temporary folder to store the exported results in. Please contact your website builder '.$dir."/".$object);
}
}
}
reset($objects);
if($deleteDir) rmdir($dir);
}
}
/**
* @param string $message
*/
private function mailOrShowErrorAndDie(string $message)
{
Log::error($message);
$mail = (new RealworksFailMail( $message));
if(!\App::environment('local')) {
\Mail::send($mail);
// die();
} else {
// echo 'ERROR: '.$message.PHP_EOL;
// die();
}
}
/**
* @param string $message
*/
private function mailOnError(string $message)
{
Log::error($message);
$mail = (new RealworksFailMail( $message));
if(!\App::environment('local')) {
\Mail::send($mail);
}
}
private function deletePublicFoldersFromNonExistingObjects()
{
//Get all realworks data property / object folders in the wwwroot
$publicRealworksFolder = $this->createAndGetPublicRealworksFolder();
$filesAndDirs = scandir($publicRealworksFolder);
$dirs = array_filter($filesAndDirs, function($item) use ($publicRealworksFolder) {
$absolute = $publicRealworksFolder.$item;
return is_dir($absolute) && $item != '.' && $item != '..';
});
//Get the system ids from the property / object folders in the wwwroot
$objectSystemIdsFromStoredFiles = array_map(function($dir) {
return last(explode('-', $dir));
}, $dirs);
//Get all system ids from objects in the database
$systemIdsPresentInDatabase = RealworkObject::get(['id', 'system_id'])->map(function(RealworkObject $object) {
return $object->system_id;
});
//Create al list of system ids which have a folder in wwwroot property / object folder but don't have a database entry
$systemIdsToRemoveFromPublicFolder = array_filter($objectSystemIdsFromStoredFiles, function($systemId) use($systemIdsPresentInDatabase) {
if($systemIdsPresentInDatabase->contains($systemId)) {
return false;
} else {
return true;
}
});
//Delete the wwwroot property / object folders which don't have a databse entry
foreach($systemIdsToRemoveFromPublicFolder as $systemIdToRemoveFromPublicFolder)
{
foreach($dirs as $dir)
{
$systemIdFromFolder = last(explode('-', $dir));
if($systemIdToRemoveFromPublicFolder == $systemIdFromFolder) {
$folderToDelete = $absolute = $publicRealworksFolder.$dir;
// echo $folderToDelete.PHP_EOL;
self::rrmdir($folderToDelete, true);
}
}
}
}
/**
* Delete al Objects that are not in the xml anymore
*
* @param array $xml
*/
private function deleteObjectsFromDatabaseThatArentListedInXML(array $xml)
{
$this->createAndGetPublicRealworksFolder();
if(!array_key_exists('Object', $xml)) return; //Empty
$allObjects = RealworkObject::all(['id', 'system_id']);
$xmlSystemIds = [];
foreach($xml['Object'] as $objectArray)
{
if(!isset($objectArray['ObjectSystemID'])) $this->mailOrShowErrorAndDie('An object in the XML did not have a required ObjectSystemID. Stopped processing.');
$xmlSystemIds[] = $objectArray['ObjectSystemID'];
}
$idsToDelete = $allObjects->map(function(RealworkObject $object) use ($xmlSystemIds) {
if(!in_array((string) $object->system_id, $xmlSystemIds, true)) return $object->id;
return null;
})->filter(function($systemId) { return $systemId !== null; })->toArray();
RealworkObject::destroy($idsToDelete);
}
}