/** * Saves all allocations to the db. * $mysqli : manual db connection (for transaction handling) * $bookingId : booking id for this allocation * Throws AllocationException if one or more allocations failed due to lack of availability */ function save($mysqli, $bookingId) { // we need to delete any allocations that have been removed since we last saved $oldAllocationRows = AllocationDBO::fetchAllocationRowsForBookingId($bookingId, $this->resourceMap, false); // existing (possibly changed) allocations, keep in a array indexed by id $allocationRowsById = array(); // indexed by id where id > 0; we need to update these rows if they have changed foreach ($this->allocationRows as $ar) { if ($ar->id > 0) { $allocationRowsById[$ar->id] = $ar; } } // diff existing records with the ones we want to save // if it exists in the old but not in the new, delete it error_log("allocation table.save() : " . var_export(array(array_keys($oldAllocationRows), array_keys($allocationRowsById)), true)); $allocationRowsToRemove = array_diff_key($oldAllocationRows, $allocationRowsById); foreach ($allocationRowsToRemove as $allocId => $ar) { AllocationDBO::deleteAllocation($mysqli, $allocId); } $failedAllocation = false; foreach ($this->allocationRows as $alloc) { try { $alloc_id = $alloc->save($mysqli, $bookingId); $alloc->isAvailable = true; } catch (Exception $e) { error_log("Update allocation row failed with exception: " . $e); $alloc->isAvailable = false; $failedMessage = $e->getMessage(); } } // report (the last) error if any of the rows failed to save if ($failedMessage) { throw new AllocationException($failedMessage); } }