* Date: 13/06/2019 17:00 */ namespace Beds24\Beds24; use Beds24\Beds24; use Beds24\Model\Beds24BookingOrderProduct; use Doctrine\Common\Cache\Cache; use Doctrine\Common\Cache\FilesystemCache; use Thelia\Log\Tlog; use Thelia\Model\CustomerTitleQuery; use Thelia\Model\Lang; class Beds24Request { /** @var Cache */ protected $cacheDriver; public function __construct() { $cacheDir = THELIA_CACHE_DIR . "beds24"; $this->cacheDriver = new FilesystemCache($cacheDir); } /** * Clear the request cache */ public function clearCache() { $this->cacheDriver->deleteAll(); } /** * @param \DateTime $startDate * @param \DateTime $endDate * @param null $roomId * @param int $numAdults * @param int $numChildren * @param bool $ignoreAvail * @return array * @throws Beds24Exception */ public function getAvailabilities(\DateTime $startDate, \DateTime $endDate, $roomId = null, $numAdults = 2, $numChildren = 0, $ignoreAvail = false) { $requestParameters = [ "checkIn" => $startDate->format("Ymd"), "checkOut" => $endDate->format("Ymd"), "numAdult" => $numAdults, "numChild" => $numChildren, 'ignoreAvail' => $ignoreAvail ]; if (empty($roomId)) { $requestParameters["ownerId"] = $this->getOwnerId(); } else { $requestParameters["roomId"] = $roomId; } $result = $this->send("getAvailabilities", $requestParameters); return $result; } /** * @param $roomId * @return array */ public function getRoomDescription($roomId, $twoLetterslangCode) { $requestParameters = [ "roomId" => $roomId, "lang" => $twoLetterslangCode, ]; $result = $this->send("getDescription", $requestParameters); return $result; } /** * @param Beds24BookingOrderProduct $booking * @return array * @throws Beds24Exception * @throws \Propel\Runtime\Exception\PropelException */ public function setBooking(Beds24BookingOrderProduct $booking) { $customer = $booking->getOrder()->getCustomer(); $address = $customer->getDefaultAddress(); $locale = Lang::getDefaultLanguage()->getLocale(); if (null !== $title = CustomerTitleQuery::create()->findPk($customer->getTitleId())) { $titleStr = $title->setLocale($locale)->getShort(); } else { $titleStr = "NA"; } // The "last night" is thez leaving day minus 1 day /** @var \DateTime $endDate */ $lastNight = $booking->getEndDate(); $lastNight->sub(new \DateInterval("P1D")); $requestParameters = [ "roomId" => $booking->getRoomId(), "roomQty" => 1, "firstNight" => $booking->getStartDate()->format("Ymd"), "lastNight" => $lastNight->format("Ymd"), "numAdult" => $booking->getAdults(), "numChild" => $booking->getChildren(), "guestTitle"=> $titleStr, "guestFirstName"=> $customer->getFirstname(), "guestName"=> $customer->getLastname(), "guestEmail"=> $customer->getEmail(), "guestPhone"=> $address->getPhone(), "guestMobile"=> $address->getCellphone(), "guestAddress"=> $address->getAddress1(), "guestCity"=> $address->getCity(), "guestPostcode"=> $address->getZipcode(), "guestCountry"=> $address->getCountry()->setLocale($locale)->getTitle(), // "notifyGuest" => true, // "notifyHost" => true ]; $result = $this->send("setBooking", $requestParameters, $this->getPropertyId($booking->getRoomId()), false); return $result; } /** * @param Beds24BookingOrderProduct $booking * @return array * @throws Beds24Exception */ public function cancelBooking(Beds24BookingOrderProduct $booking) { $requestParameters = [ "bookId" => $booking->getBeds24BookingId(), "status" => 0 ]; $result = $this->send("setBooking", $requestParameters, $this->getPropertyId($booking->getRoomId()), false); return $result; } /** * @param int $roomId * @return int the room's property ID * @throws Beds24Exception */ public function getPropertyId($roomId) { $properties = $this->send("getProperties"); if (! $this->hasError($properties)) { foreach ($properties['getProperties'] as $property) { $propertyId = $property['propId']; foreach ($property['roomTypes'] as $room) { if ($room['roomId'] == $roomId) { return $propertyId; } } } } throw new Beds24Exception("Failed to find property ID for room ID $roomId"); } /** * @return int * @throws Beds24Exception */ public function getOwnerId() { $properties = $this->send("getProperties"); if (! $this->hasError($properties)) { foreach ($properties['getProperties'] as $property) { return $property['ownerId']; } } throw new Beds24Exception("Failed to find Beds 24 owner ID"); } /** * @return array a list of (name, propeId) couples. * @throws Beds24Exception */ public function getPropertyList() { $result = []; $properties = $this->send("getProperties"); if (! $this->hasError($properties)) { foreach ($properties['getProperties'] as $property) { $result[] = [ 'name' => $property['name'], 'id' => $property['propId'] ]; } } return $result; } public function hasError($result) { return isset($result['error']); } /** * Perform Beds24 query, and cache the result for 2 hours. * * @param $serviceName * @param [] $requestParameters * @param bool $propId * @param bool $usecache * @return array * @throws Beds24Exception */ protected function send($serviceName, $requestParameters = [], $propId = false, $usecache = true) { // Add authentication $requestParameters['authentication'] = [ 'apiKey' => Beds24::getConfigValue('api_key') ]; // Add property key if required if (! empty($propId)) { $propKey = Beds24::getConfigValue('prop_key_' . $propId); if (empty($propKey)) { throw new Beds24Exception("propKey for property ID $propId is not defined. Please check module configuration."); } $requestParameters['authentication']['propKey'] = $propKey; } $json = json_encode($requestParameters); $requestHash = hash("md5", $serviceName . $json); if ((! $usecache) || (false === $result = $this->cacheDriver->fetch($requestHash))) { $url = "https://api.beds24.com/json/$serviceName"; $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); $result = curl_exec($ch); ; if ($usecache) { $this->cacheDriver->save($requestHash, $result, 7200 /* 2 hours */); } curl_close($ch); } else { $ch = false; } if (false !== $result) { $resultArray = json_decode($result, true); } else { $resultArray = [ 'error' => 'Request to Beds24 failed: ' . curl_error($ch), 'errorCode' => curl_errno($ch) ]; } // Log error, if any. if (isset($resultArray['error'])) { Tlog::getInstance()->error("Beds24 request $serviceName failed: " . $resultArray['error'] . ", code: " . $resultArray['errorCode']); } return ($resultArray); } }