username = 'google'; $this->password = 'P8MUQtNP6TkKMz3E'; $this->channelManagerId = 14;//Google $this->request = $request; $this->currencyService = $currencyService; $this->channelManagerPropertyMappingService = $channelManagerPropertyMappingService; $this->propertyChannelCouponService = $propertyChannelCouponService; $payload = $this->request->getContent(); parse_str(urldecode($payload), $payloadDecode); $this->param = $payloadDecode; $this->authorization = $request->header('authorization'); $this->tax = 10; $this->mealCodeMapping = [ 10 => 'AI', 11 => 'BB', 13 => 'RO', 14 => 'FB', 15 => 'HB', ]; $this->paymentTypeMapping = [ 'CRD' => 'prepaid', 'HTL' => 'postpaid' ]; } public function checkAuthentication($authorization) { $response = ['status' => false, 'message' => '']; $basicAuth = 'Basic ' . base64_encode($this->username . ':' . $this->password); if ($authorization != $basicAuth) { $response['message'] = 'Your username or password is incorrect.'; } else { $response['status'] = true; } return $response; } public function responseError($errorMessage) { $response = [ 'status' => false, 'message' => $errorMessage, ]; //channelManagerLogService if (!is_null($this->channelManagerLogId)) { $updateDataLog = [ 'response' => json_encode($response), 'status' => 0 ]; if (!is_null($this->channelManagerRequestTime)) { $updateDataLog['response_time'] = microtime(true) - $this->channelManagerRequestTime; } $channelManagerLog = $this->channelManagerLogService->update($this->channelManagerLogId, $updateDataLog); } //channelManagerLogService return response()->json($response); } public function requestParamConverter($requestParam = []) { $searchRequestJson = []; $searchRequestJson['date']['checkIn'] = Carbon::parse($requestParam['Checkin'])->toDateString(); $searchRequestJson['date']['checkOut'] = Carbon::parse($requestParam['Checkin'])->addDays($requestParam['Nights'])->toDateString(); $rooms = []; $rooms[0]['adults'] = (integer)$requestParam['Context']['OccupancyDetails']['NumAdults']; $rooms[0]['children'] = (integer)($requestParam['Context']['Occupancy'] - $requestParam['Context']['OccupancyDetails']['NumAdults']); $rooms[0]['age'] = []; if (isset($requestParam['Context']['OccupancyDetails']['Children']['Child'])) { $requestParam['Context']['OccupancyDetails']['Children']['Child'] = singleElementXMLArray($requestParam['Context']['OccupancyDetails']['Children']['Child']); } else { $requestParam['Context']['OccupancyDetails']['Children']['Child'] = []; } foreach ($requestParam['Context']['OccupancyDetails']['Children']['Child'] as $child) { $rooms[0]['age'][] = $child['@attributes']['age']; } $searchRequestJson['rooms'] = $rooms; if (isset($requestParam['PropertyList']['Property'])) { $requestParam['PropertyList']['Property'] = singleElementXMLArray($requestParam['PropertyList']['Property']); } else { $requestParam['PropertyList']['Property'] = []; } $searchRequestJson['property'] = $requestParam['PropertyList']['Property']; return $searchRequestJson; } public function deepLinkGenerator($token, $requestParam = []) { $deepLink = 'https://be.extranetwork.com/' . $token . '/' . fillOnUndefined($requestParam, 'locale', 'en') . '/search/'; $deepLink .= Carbon::parse($requestParam['date']['checkIn'])->format('Ymd') . '/'; $deepLink .= Carbon::parse($requestParam['date']['checkOut'])->format('Ymd') . '/'; $roomOccupancy = $this->roomOccupancy($requestParam['rooms']); $deepLink .= implode(',', $roomOccupancy);; $deepLink .= '?utm_source=google'; return $deepLink; } public function hotel(Request $request) { $response = ['status' => true, 'message' => '']; $listings = new \SimpleXMLElement(''); $listings->addChild('language', 'en'); try { $channelManagerPropertyMappingCriteria['criteria'] = [ ['field' => 'channel_manager_id', 'condition' => '=', 'value' => $this->channelManagerId], ['field' => 'channel_manager_property_id', 'condition' => '=', 'value' => null], ['field' => 'status', 'condition' => '=', 'value' => 1], ]; $channelManagerPropertyMappingCriteria['with'] = [ 'property.propertyType', 'property.propertyContact', 'property.propertyWeb', 'property.country', 'property.propertyRooms', 'property.propertyPhotos', 'property.propertyAdditionalInfos', 'property.propertyBrand' ]; $channelManagerPropertyMapping = $this->channelManagerPropertyMappingService->select($channelManagerPropertyMappingCriteria); if ($channelManagerPropertyMapping['status'] == 'success' && !empty($channelManagerPropertyMapping['data'])) { foreach ($channelManagerPropertyMapping['data'] as $propertyMapping) { if ($propertyMapping['status'] != 1) { continue; } $metaAddress = json_decode($propertyMapping['property']['property_contact']['meta'], 1); $listing = $listings->addChild('listing'); $listing->addChild('id', $propertyMapping['property']['id']); $listing->addChild('name', htmlspecialchars($propertyMapping['property']['name'], ENT_XML1, 'UTF-8')); $address = $listing->addChild('address'); $address->addAttribute('format', 'simple'); $component = $address->addChild('component', htmlspecialchars(fillOnUndefined($metaAddress, 'street'), ENT_XML1, 'UTF-8')); $component->addAttribute('name', 'addr1'); //$component = $address->addChild('component'); //$component->addAttribute('name', 'addr2'); $component = $address->addChild('component', fillOnUndefined($metaAddress, 'city')); $component->addAttribute('name', 'city'); //$component = $address->addChild('component', $propertyMapping['property']['country']['name']); //$component->addAttribute('name','region'); $component = $address->addChild('component', fillOnUndefined($metaAddress, 'zip_code')); $component->addAttribute('name', 'postal_code'); $listing->addChild('country', $propertyMapping['property']['country']['country_code']); $listing->addChild('latitude', $propertyMapping['property']['property_contact']['latitude']); $listing->addChild('longitude', $propertyMapping['property']['property_contact']['longitude']); if (!empty($propertyMapping['property']['property_contact']['view_full_phone'])) { $phone = $listing->addChild('phone'); $phone->addAttribute('number', $propertyMapping['property']['property_contact']['view_full_phone']); } $listing->addChild('category', 'hotel'); if (!empty($propertyMapping['property']['property_brand']['name'])) { $listing->addChild('brand', htmlspecialchars($propertyMapping['property']['property_brand']['name'], ENT_XML1, 'UTF-8')); } if (!empty($propertyMapping['property']['property_web']['webProtocolUrl'])) { $listing->addChild('website', $propertyMapping['property']['property_web']['webProtocolUrl']); } $content = $listing->addChild('content'); $text = $content->addChild('text'); $text->addAttribute('type', 'description'); $text->addChild('body', htmlspecialchars($propertyMapping['property']['name'], ENT_XML1, 'UTF-8')); $attributes = $content->addChild('attributes'); $clientAttrCountry = $attributes->addChild('client_attr', $propertyMapping['property']['country']['country_code']); $clientAttrCountry->addAttribute('name', 'country'); $clientAttrMaxNightStay = $attributes->addChild('client_attr', '0'); $clientAttrMaxNightStay->addAttribute('name', 'max_night_stay'); $clientAttrMinNightStay = $attributes->addChild('client_attr', '1'); $clientAttrMinNightStay->addAttribute('name', 'minimum_night_stay'); $roomCountTotal = 0; if (!empty($propertyMapping['property']['property_additional_infos'])) { foreach ($propertyMapping['property']['property_additional_infos'] as $info) { if ($info['additional_info_key_id'] == 3) { $roomCountTotal = $info['value']; break; } } } $clientAttrRooms = $attributes->addChild('client_attr', $roomCountTotal); $clientAttrRooms->addAttribute('name', 'number_of_rooms'); $clientAttrLatLong = $attributes->addChild('client_attr', $propertyMapping['property']['property_contact']['latitude'] . ', ' . $propertyMapping['property']['property_contact']['longitude']); $clientAttrLatLong->addAttribute('name', 'latlong'); if (!empty($propertyMapping['property']['property_photos'])) { $photos = $propertyMapping['property']['property_photos']; // Filter photos with status 1 $photos = array_filter($photos, function ($p) { return isset($p['status']) && $p['status'] == 1; }); // Sort photos by is_default (desc), photo_order (asc), and created_at (desc) usort($photos, function ($a, $b) { return ($b['is_default'] ?? 0) <=> ($a['is_default'] ?? 0) ?: ($a['photo_order'] ?? 0) <=> ($b['photo_order'] ?? 0) ?: ($b['created_at'] ?? 0) <=> ($a['created_at'] ?? 0); }); // Limit to first 10 photos $photos = array_slice($photos, 0, 10); foreach ($photos as $photo) { $imageUrl = $photo['photoUrl']['default'] ?? $photo['photo_url']['default'] ?? null; if ($imageUrl) { $image = $content->addChild('image'); $image->addAttribute('type', 'ad'); $image->addAttribute('url', $imageUrl); $width = '1440'; $height = '959'; if (!empty($photo['photo_resolution'])) { $resolution = explode('x', $photo['photo_resolution']); if (count($resolution) == 2) { $width = trim($resolution[0]); $height = trim($resolution[1]); } } $image->addAttribute('width', $width); $image->addAttribute('height', $height); $image->addChild('link', $imageUrl); $image->addChild('title', 'Unknown title'); $date = $image->addChild('date'); if (!empty($photo['created_at'])) { $photoCreatedAt = Carbon::createFromTimestamp($photo['created_at']); } else { $photoCreatedAt = Carbon::now(); } $date->addAttribute('day', $photoCreatedAt->day); $date->addAttribute('month', $photoCreatedAt->month); $date->addAttribute('year', $photoCreatedAt->year); } } } } } } catch (ApiErrorException $e) { $response['message'] = implode(', ', $e->getMessageArr()); } catch (Exception $e) { $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage(); Log::error($message); $response['message'] = $e->getMessage(); } header('Content-Type: application/xml; charset=UTF-8'); echo $listings->asXML(); exit; } }