Web service to filter a list of hotels.
An application (console or RESTful API) that allow search in the given inventory by any of the following:
- Hotel Name
- Destination [City]
- Price range [ex: $100:$200]
- Date range [ex: 10-10-2020:15-10-2020]
And allow sorting by:
- Hotel Name
- Price
Using composer :
git clone http://github.com/mohammedibrahim/hotels-filters.git
cd hotels-filters
composer install
php index.php
Lets assume that your installation has http://localhost/hotels-filters as url and it points to the root of our application.
GET http://localhost/hotels-filters
{
"data": [
{
"name": "Concorde Hotel",
"price": 79.4,
"city": "Manila",
"availability": [
{
"from": "10-10-2020",
"to": "19-10-2020"
},
{
"from": "22-10-2020",
"to": "22-11-2020"
},
{
"from": "03-12-2020",
"to": "20-12-2020"
}
]
},
{
"name": "Golden Tulip",
"price": 109.6,
"city": "paris",
"availability": [
{
"from": "04-10-2020",
"to": "17-10-2020"
},
{
"from": "16-10-2020",
"to": "11-11-2020"
},
{
"from": "01-12-2020",
"to": "09-12-2020"
}
]
},
{
"name": "Le Meridien",
"price": 89.6,
"city": "london",
"availability": [
{
"from": "01-10-2020",
"to": "12-10-2020"
},
{
"from": "05-10-2020",
"to": "10-11-2020"
},
{
"from": "05-12-2020",
"to": "28-12-2020"
}
]
},
{
"name": "Media One Hotel",
"price": 102.2,
"city": "dubai",
"availability": [
{
"from": "10-10-2020",
"to": "15-10-2020"
},
{
"from": "25-10-2020",
"to": "15-11-2020"
},
{
"from": "10-12-2020",
"to": "15-12-2020"
}
]
},
{
"name": "Novotel Hotel",
"price": 111,
"city": "Vienna",
"availability": [
{
"from": "20-10-2020",
"to": "28-10-2020"
},
{
"from": "04-11-2020",
"to": "20-11-2020"
},
{
"from": "08-12-2020",
"to": "24-12-2020"
}
]
},
{
"name": "Rotana Hotel",
"price": 80.6,
"city": "cairo",
"availability": [
{
"from": "10-10-2020",
"to": "12-10-2020"
},
{
"from": "25-10-2020",
"to": "10-11-2020"
},
{
"from": "05-12-2020",
"to": "18-12-2020"
}
]
}
]
}
Data can be filtered by one or more filters as follow
Filter Name | Type | Description | Default | Example |
---|---|---|---|---|
hotel_name | String | Filter hotels according to it's name. | Null | filters[hotel_name]=Concorde |
destination | String | Filter hotels with its destination city. | Null | filters[destination]=Cairo |
price_range | String | Filter hotels which has a price between the specified value. | Null | filters[price_range]=100:200 |
date_range | String | Filter hotels which has a availablitiy in the specified date range. | Null | filters[date_range]=10-10-2020:15-10-2020 |
GET http://localhost/hotels-filters?filters[hotel_name]=Concorde
{
"data": [
{
"name": "Concorde Hotel",
"price": 79.4,
"city": "Manila",
"availability": [
{
"from": "10-10-2020",
"to": "19-10-2020"
},
{
"from": "22-10-2020",
"to": "22-11-2020"
},
{
"from": "03-12-2020",
"to": "20-12-2020"
}
]
}
]
}
Data can be ordered by name or value as follow
Order Name | Type | Description | Default | Example |
---|---|---|---|---|
name | String | Order hotels by name. | asc | order_by=name&order_type=asc |
price | String | Order hotels by price. | asc | order_by=price&order_type=desc |
GET http://localhost/hotels-filters?order_by=name&order_type=desc
{
"data": [
{
"name": "Concorde Hotel",
"price": 79.4,
"city": "Manila",
"availability": [
{
"from": "10-10-2020",
"to": "19-10-2020"
},
{
"from": "22-10-2020",
"to": "22-11-2020"
},
{
"from": "03-12-2020",
"to": "20-12-2020"
}
]
},
{
"name": "Golden Tulip",
"price": 109.6,
"city": "paris",
"availability": [
{
"from": "04-10-2020",
"to": "17-10-2020"
},
{
"from": "16-10-2020",
"to": "11-11-2020"
},
{
"from": "01-12-2020",
"to": "09-12-2020"
}
]
},
{
"name": "Le Meridien",
"price": 89.6,
"city": "london",
"availability": [
{
"from": "01-10-2020",
"to": "12-10-2020"
},
{
"from": "05-10-2020",
"to": "10-11-2020"
},
{
"from": "05-12-2020",
"to": "28-12-2020"
}
]
},
{
"name": "Media One Hotel",
"price": 102.2,
"city": "dubai",
"availability": [
{
"from": "10-10-2020",
"to": "15-10-2020"
},
{
"from": "25-10-2020",
"to": "15-11-2020"
},
{
"from": "10-12-2020",
"to": "15-12-2020"
}
]
},
{
"name": "Novotel Hotel",
"price": 111,
"city": "Vienna",
"availability": [
{
"from": "20-10-2020",
"to": "28-10-2020"
},
{
"from": "04-11-2020",
"to": "20-11-2020"
},
{
"from": "08-12-2020",
"to": "24-12-2020"
}
]
},
{
"name": "Rotana Hotel",
"price": 80.6,
"city": "cairo",
"availability": [
{
"from": "10-10-2020",
"to": "12-10-2020"
},
{
"from": "25-10-2020",
"to": "10-11-2020"
},
{
"from": "05-12-2020",
"to": "18-12-2020"
}
]
}
]
}
Output format available for one echoing data
Name | Description | Default | Example |
---|---|---|---|
json | show results in output format. | json | output_format=json |
GET http://localhost/hotels-filters?output_format=json
{
"data": [
{
"name": "Concorde Hotel",
"price": 79.4,
"city": "Manila",
"availability": [
{
"from": "10-10-2020",
"to": "19-10-2020"
},
{
"from": "22-10-2020",
"to": "22-11-2020"
},
{
"from": "03-12-2020",
"to": "20-12-2020"
}
]
},
{
"name": "Golden Tulip",
"price": 109.6,
"city": "paris",
"availability": [
{
"from": "04-10-2020",
"to": "17-10-2020"
},
{
"from": "16-10-2020",
"to": "11-11-2020"
},
{
"from": "01-12-2020",
"to": "09-12-2020"
}
]
},
{
"name": "Le Meridien",
"price": 89.6,
"city": "london",
"availability": [
{
"from": "01-10-2020",
"to": "12-10-2020"
},
{
"from": "05-10-2020",
"to": "10-11-2020"
},
{
"from": "05-12-2020",
"to": "28-12-2020"
}
]
},
{
"name": "Media One Hotel",
"price": 102.2,
"city": "dubai",
"availability": [
{
"from": "10-10-2020",
"to": "15-10-2020"
},
{
"from": "25-10-2020",
"to": "15-11-2020"
},
{
"from": "10-12-2020",
"to": "15-12-2020"
}
]
},
{
"name": "Novotel Hotel",
"price": 111,
"city": "Vienna",
"availability": [
{
"from": "20-10-2020",
"to": "28-10-2020"
},
{
"from": "04-11-2020",
"to": "20-11-2020"
},
{
"from": "08-12-2020",
"to": "24-12-2020"
}
]
},
{
"name": "Rotana Hotel",
"price": 80.6,
"city": "cairo",
"availability": [
{
"from": "10-10-2020",
"to": "12-10-2020"
},
{
"from": "25-10-2020",
"to": "10-11-2020"
},
{
"from": "05-12-2020",
"to": "18-12-2020"
}
]
}
]
}
Under development.
Application allows you to add new filter.
hotels-filters -> app -> Domain -> Filters
<?php
namespace HotelsFilters\Filters;
use HotelsFilters\Domain\Contracts\FiltersContracts\AbstractFilter;
class NewFilterClass extends AbstractFilter
{
/**
* Name of filter
*/
protected $filterName = 'new_filter_name';
/**
* Set Filter Value and apply any validation on it.
*/
public function setFilterValue($value)
{}
/**
* Apply Filter to data.
*/
public function filterData(array $data): bool
{}
}
hotels-filters -> app -> Domain -> Service -> Strategy Factory -> FilterStrategoy
<?php
class FilterStrategy
{
protected $registeredFilters = [
DateRangeFilter::class,
DestinationFilter::class,
HotelNameFilter::class,
PriceRangeFilter::class,
NewFilterClass::class // <-- Add New Filter
];
}
GET http://localhost/hotels-filters?filters[new_filter_name]=value
You may want to order data by new custom field than the defaults.
hotels-filters -> app -> Domain -> Orders
<?php
namespace HotelsFilters\Output;
use HotelsFilters\Domain\Orders\AbstractOrder;
/**
* Order By New Order field.
*
* Class HotelNameOrder
* @package HotelsFilters\Orders
*/
class NewFieldOrder extends AbstractOrder
{
/**
* Order Name.
*
* @var string
*/
protected $orderName = 'new_order_field';
}
hotels-filters -> app -> Domain -> Service -> Strategy Factory -> OrderStrategoy
<?php
class OrderStrategy
{
protected $registeredOrders = [
NameOrder::class,
PriceOrder::class,
NewFieldOrder::class // <-- Add New Order
];
}
GET http://localhost/hotels-filters?order_by=new_order_field&order_type=asc
Create New output format like html format or xml default is json.
hotels-filters -> app -> Domain -> Output
<?php
namespace HotelsFilters\Output;
use HotelsFilters\Domain\Contracts\OutputFormat\AbstractOutputFormat;
class HtmlOutput extends AbstractOutputFormat
{
/**
* Format Name.
*
* @var string
*/
protected $formatName = 'html';
/**
* Implement this method to output the results as html.
*
* @return string
*/
public function output(): string
{}
}
hotels-filters -> app -> Domain -> Service -> Strategy Factory -> OutputFormatStrategoy
<?php
class OutputStrategy
{
protected $registeredOutputFormats = [
JsonOutput::class,
HtmlOutput::class // <-- Add New output format
];
}
GET http://localhost/hotels-filters?output_format=html
At app root directory Run
php vendor/bin/phpdoc -d app/ -t docs --title="Hotels Filters"
To Run test cases. From app root directory
Run
php vendor/bin/phpunit