├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── README.md ├── composer.json ├── phpunit.xml.dist ├── src ├── ApiQueryBuilderServiceProvider.php ├── Exceptions │ └── UnknownColumnException.php ├── LumenServiceProvider.php ├── Paginator.php ├── QueryBuilder.php ├── RequestCreator.php ├── UriParser.php └── config.php └── tests ├── BaseTestCase.php └── UriParserTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /build 3 | composer.lock -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | language: php 3 | php: 4 | - 5.6 5 | - 7.0 6 | install: 7 | - travis_retry composer install --no-interaction --prefer-source 8 | script: 9 | - phpunit --coverage-text --coverage-clover=coverage.clover -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## v1.7.0 (13 June 2017) 4 | 5 | ### Added 6 | - Add custom parameters support 7 | ([#15](https://github.com/selahattinunlu/laravel-api-query-builder/issues/15)) 8 | 9 | --- 10 | 11 | ## v1.6.0 (04 Jan 2017) 12 | 13 | ### Added 14 | - Add support for "null" 15 | ([#16](https://github.com/selahattinunlu/laravel-api-query-builder/issues/16)) 16 | 17 | --- 18 | 19 | ## v1.5.1 (21 Dec 2016) 20 | 21 | ### Fixed 22 | - Add support to Laravel 5.0 version for pagination 23 | ([#13](https://github.com/selahattinunlu/laravel-api-query-builder/issues/13)) 24 | 25 | --- 26 | 27 | ## v1.5.0 (27 Nov 2016) 28 | 29 | ### Fixed 30 | - Pagination issue 31 | ([#12](https://github.com/selahattinunlu/laravel-api-query-builder/issues/12)) 32 | ([#9](https://github.com/selahattinunlu/laravel-api-query-builder/issues/9)) 33 | 34 | ### Added 35 | - Dynamic Appends Support 36 | ([#12](https://github.com/selahattinunlu/laravel-api-query-builder/issues/12)) 37 | 38 | --- 39 | 40 | ## v1.4.0 (11 Nov 2016) 41 | 42 | ### Added 43 | - whereIn and whereNotIn support 44 | 45 | --- 46 | 47 | ## v1.3.0 (24 Feb 2016) 48 | 49 | ### Added 50 | - Lumen Compatibility 51 | 52 | --- 53 | 54 | ## v1.2.0 (3 Dec 2015) 55 | 56 | ### Added 57 | - Excluded parameters feature 58 | 59 | --- 60 | 61 | ## v1.1.0 (12 Oct 2015) 62 | 63 | ### Added 64 | - Random sorting feature. (example: ?order_by=random) 65 | 66 | --- 67 | 68 | ## v1.0 (8 Oct 2015) 69 | 70 | First release. 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel & Lumen API Query Builder Package 2 | 3 | [![Build Status](https://travis-ci.org/mahmutbayri/laravel-api-query-builder.svg?branch=master)](https://travis-ci.org/mahmutbayri/laravel-api-query-builder) 4 | 5 | ### English 6 | 7 | [1. Introduction](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Introduction) 8 | 9 | [2. Installation](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Installation) 10 | 11 | [3. Usage](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Usage) 12 | 13 | [4. Other Examples](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Other-Examples) 14 | 15 | [5. Using Custom Request](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Using-Custom-Request) 16 | 17 | [6. Constant Parameters](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Constant-Parameters) 18 | 19 | [7. Methods](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Methods) 20 | 21 | [8. Creating Custom Filter](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Creating-Custom-Filter) 22 | 23 | [9. How do exclude parameters from queries?](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/9.-How-do-exclude-parameters-from-queries%3F) 24 | 25 | ### Türkçe 26 | 27 | [1. Nedir](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Nedir) 28 | 29 | [2. Kurulum](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Kurulum) 30 | 31 | [3. Kullanım](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Kullan%C4%B1m) 32 | 33 | [4. Diğer Kullanım Örnekleri](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Di%C4%9Fer-Kullan%C4%B1m-%C3%96rnekleri) 34 | 35 | [5. Custom Request Kullanımı](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Custom-Request-Kullan%C4%B1m%C4%B1) 36 | 37 | [6. Sabit Parametreler](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Sabit-Parametreler) 38 | 39 | [7. Methodlar](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/Methodlar) 40 | 41 | [8. Özel Filtre Oluşturma](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/%C3%96zel-Filtre-Olu%C5%9Fturma) 42 | 43 | [9. Sorgularda bazı parametreleri hariç tutmak](https://github.com/selahattinunlu/laravel-api-query-builder/wiki/9.-Sorgularda-baz%C4%B1-parametreleri-hari%C3%A7-tutmak) 44 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unlu/laravel-api-query-builder", 3 | "description": "Laravel API Query Builder Package.", 4 | "type": "library", 5 | "license": "MIT", 6 | "keywords": ["laravel", "api"], 7 | "authors": [ 8 | { 9 | "name": "Selahattin Ünlü", 10 | "email": "selahattin.unlu@yandex.com" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=5.4", 15 | "illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*", 16 | "illuminate/database": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*", 17 | "illuminate/http": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*" 18 | }, 19 | "require-dev": { 20 | "phpunit/phpunit": "~4.0|~5.0" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Unlu\\Laravel\\Api\\": "src" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "Tests\\": "tests/" 30 | } 31 | }, 32 | "scripts": { 33 | "phpunit": "./vendor/bin/phpunit" 34 | } 35 | } -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests 14 | 15 | 16 | 17 | 18 | ./src 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/ApiQueryBuilderServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 12 | __DIR__ . '/config.php' => config_path('api-query-builder.php'), 13 | ]); 14 | } 15 | 16 | public function register() 17 | { 18 | $this->mergeConfigFrom(__DIR__ . '/config.php', 'api-query-builder'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Exceptions/UnknownColumnException.php: -------------------------------------------------------------------------------- 1 | queryUri = str_replace( 19 | sprintf('&%s=%d', $this->getPageName(), $this->currentPage()), 20 | '', 21 | $queryUri 22 | ); 23 | 24 | return $this; 25 | } 26 | 27 | public function nextPageUrl() 28 | { 29 | return $this->appendQueryParametersToUrl(parent::nextPageUrl()); 30 | } 31 | 32 | public function previousPageUrl() 33 | { 34 | return $this->appendQueryParametersToUrl(parent::previousPageUrl()); 35 | } 36 | 37 | private function appendQueryParametersToUrl($url = null) 38 | { 39 | if ($url) { 40 | $pageParameter = explode('?', $url)[1]; 41 | $url = str_replace('?' . $pageParameter, '', $url); 42 | $url .= '?' . $this->queryUri . '&' . $pageParameter; 43 | } 44 | 45 | return $url; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/QueryBuilder.php: -------------------------------------------------------------------------------- 1 | orderBy = config('api-query-builder.orderBy'); 50 | 51 | $this->limit = config('api-query-builder.limit'); 52 | 53 | $this->excludedParameters = array_merge($this->excludedParameters, config('api-query-builder.excludedParameters')); 54 | 55 | $this->model = $model; 56 | 57 | $this->uriParser = new UriParser($request); 58 | 59 | $this->query = $this->model->newQuery(); 60 | } 61 | 62 | public function build() 63 | { 64 | $this->prepare(); 65 | 66 | if ($this->hasWheres()) { 67 | array_map([$this, 'addWhereToQuery'], $this->wheres); 68 | } 69 | 70 | if ($this->hasGroupBy()) { 71 | $this->query->groupBy($this->groupBy); 72 | } 73 | 74 | if ($this->hasLimit()) { 75 | $this->query->take($this->limit); 76 | } 77 | 78 | if ($this->hasOffset()) { 79 | $this->query->skip($this->offset); 80 | } 81 | 82 | array_map([$this, 'addOrderByToQuery'], $this->orderBy); 83 | 84 | $this->query->with($this->includes); 85 | 86 | $this->query->select($this->columns); 87 | 88 | return $this; 89 | } 90 | 91 | public function get() 92 | { 93 | $result = $this->query->get(); 94 | 95 | if ($this->hasAppends()) { 96 | $result = $this->addAppendsToModel($result); 97 | } 98 | 99 | return $result; 100 | } 101 | 102 | public function paginate() 103 | { 104 | if (!$this->hasLimit()) { 105 | throw new Exception("You can't use unlimited option for pagination", 1); 106 | } 107 | 108 | $result = $this->basePaginate($this->limit); 109 | 110 | if ($this->hasAppends()) { 111 | $result = $this->addAppendsToModel($result); 112 | } 113 | 114 | return $result; 115 | } 116 | 117 | public function lists($value, $key) 118 | { 119 | return $this->query->lists($value, $key); 120 | } 121 | 122 | protected function prepare() 123 | { 124 | $this->setWheres($this->uriParser->whereParameters()); 125 | 126 | $constantParameters = $this->uriParser->constantParameters(); 127 | 128 | array_map([$this, 'prepareConstant'], $constantParameters); 129 | 130 | if ($this->hasIncludes() && $this->hasRelationColumns()) { 131 | $this->fixRelationColumns(); 132 | } 133 | 134 | return $this; 135 | } 136 | 137 | private function prepareConstant($parameter) 138 | { 139 | if (!$this->uriParser->hasQueryParameter($parameter)) { 140 | return; 141 | } 142 | 143 | $callback = [$this, $this->setterMethodName($parameter)]; 144 | 145 | $callbackParameter = $this->uriParser->queryParameter($parameter); 146 | 147 | call_user_func($callback, $callbackParameter['value']); 148 | } 149 | 150 | private function setIncludes($includes) 151 | { 152 | $this->includes = array_filter(explode(',', $includes)); 153 | } 154 | 155 | private function setPage($page) 156 | { 157 | $this->page = (int)$page; 158 | 159 | $this->offset = ($page - 1) * $this->limit; 160 | } 161 | 162 | private function setColumns($columns) 163 | { 164 | $columns = array_filter(explode(',', $columns)); 165 | 166 | $this->columns = $this->relationColumns = []; 167 | 168 | array_map([$this, 'setColumn'], $columns); 169 | } 170 | 171 | private function setColumn($column) 172 | { 173 | if ($this->isRelationColumn($column)) { 174 | return $this->appendRelationColumn($column); 175 | } 176 | 177 | $this->columns[] = $column; 178 | } 179 | 180 | private function appendRelationColumn($keyAndColumn) 181 | { 182 | list($key, $column) = explode('.', $keyAndColumn); 183 | 184 | $this->relationColumns[$key][] = $column; 185 | } 186 | 187 | private function fixRelationColumns() 188 | { 189 | $keys = array_keys($this->relationColumns); 190 | 191 | $callback = [$this, 'fixRelationColumn']; 192 | 193 | array_map($callback, $keys, $this->relationColumns); 194 | } 195 | 196 | private function fixRelationColumn($key, $columns) 197 | { 198 | $index = array_search($key, $this->includes); 199 | 200 | unset($this->includes[$index]); 201 | 202 | $this->includes[$key] = $this->closureRelationColumns($columns); 203 | } 204 | 205 | private function closureRelationColumns($columns) 206 | { 207 | return function ($q) use ($columns) { 208 | $q->select($columns); 209 | }; 210 | } 211 | 212 | private function setOrderBy($order) 213 | { 214 | $this->orderBy = []; 215 | 216 | $orders = array_filter(explode('|', $order)); 217 | 218 | array_map([$this, 'appendOrderBy'], $orders); 219 | } 220 | 221 | private function appendOrderBy($order) 222 | { 223 | if ($order == 'random') { 224 | $this->orderBy[] = 'random'; 225 | return; 226 | } 227 | 228 | list($column, $direction) = explode(',', $order); 229 | 230 | $this->orderBy[] = [ 231 | 'column' => $column, 232 | 'direction' => $direction 233 | ]; 234 | } 235 | 236 | private function setGroupBy($groups) 237 | { 238 | $this->groupBy = array_filter(explode(',', $groups)); 239 | } 240 | 241 | private function setLimit($limit) 242 | { 243 | $limit = ($limit == 'unlimited') ? null : (int)$limit; 244 | 245 | $this->limit = $limit; 246 | } 247 | 248 | private function setWheres($parameters) 249 | { 250 | $this->wheres = $parameters; 251 | } 252 | 253 | private function setAppends($appends) 254 | { 255 | $this->appends = explode(',', $appends); 256 | } 257 | 258 | private function addWhereToQuery($where) 259 | { 260 | extract($where); 261 | 262 | // For array values (whereIn, whereNotIn) 263 | if (isset($values)) { 264 | $value = $values; 265 | } 266 | if (!isset($operator)) { 267 | $operator = ''; 268 | } 269 | 270 | /** @var mixed $key */ 271 | if ($this->isExcludedParameter($key)) { 272 | return; 273 | } 274 | 275 | if ($this->hasCustomFilter($key)) { 276 | /** @var string $type */ 277 | return $this->applyCustomFilter($key, $operator, $value, $type); 278 | } 279 | 280 | if (!$this->hasTableColumn($key)) { 281 | throw new UnknownColumnException("Unknown column '{$key}'"); 282 | } 283 | 284 | /** @var string $type */ 285 | if ($type == 'In') { 286 | $this->query->whereIn($key, $value); 287 | } else if ($type == 'NotIn') { 288 | $this->query->whereNotIn($key, $value); 289 | } else { 290 | if ($value == '[null]') { 291 | if ($operator == '=') { 292 | $this->query->whereNull($key); 293 | } else { 294 | $this->query->whereNotNull($key); 295 | } 296 | } else { 297 | $this->query->where($key, $operator, $value); 298 | } 299 | } 300 | } 301 | 302 | private function addOrderByToQuery($order) 303 | { 304 | if ($order == 'random') { 305 | return $this->query->orderBy(DB::raw('RAND()')); 306 | } 307 | 308 | extract($order); 309 | 310 | /** @var string $column */ 311 | /** @var string $direction */ 312 | $this->query->orderBy($column, $direction); 313 | } 314 | 315 | private function applyCustomFilter($key, $operator, $value, $type = 'Basic') 316 | { 317 | $callback = [$this, $this->customFilterName($key)]; 318 | 319 | $this->query = call_user_func($callback, $this->query, $value, $operator, $type); 320 | } 321 | 322 | private function isRelationColumn($column) 323 | { 324 | return (count(explode('.', $column)) > 1); 325 | } 326 | 327 | private function isExcludedParameter($key) 328 | { 329 | return in_array($key, $this->excludedParameters); 330 | } 331 | 332 | private function hasWheres() 333 | { 334 | return (count($this->wheres) > 0); 335 | } 336 | 337 | private function hasIncludes() 338 | { 339 | return (count($this->includes) > 0); 340 | } 341 | 342 | private function hasAppends() 343 | { 344 | return (count($this->appends) > 0); 345 | } 346 | 347 | private function hasGroupBy() 348 | { 349 | return (count($this->groupBy) > 0); 350 | } 351 | 352 | private function hasLimit() 353 | { 354 | return ($this->limit); 355 | } 356 | 357 | private function hasOffset() 358 | { 359 | return ($this->offset != 0); 360 | } 361 | 362 | private function hasRelationColumns() 363 | { 364 | return (count($this->relationColumns) > 0); 365 | } 366 | 367 | private function hasTableColumn($column) 368 | { 369 | return (Schema::hasColumn($this->model->getTable(), $column)); 370 | } 371 | 372 | private function hasCustomFilter($key) 373 | { 374 | $methodName = $this->customFilterName($key); 375 | 376 | return (method_exists($this, $methodName)); 377 | } 378 | 379 | private function setterMethodName($key) 380 | { 381 | return 'set' . studly_case($key); 382 | } 383 | 384 | private function customFilterName($key) 385 | { 386 | return 'filterBy' . studly_case($key); 387 | } 388 | 389 | private function addAppendsToModel($result) 390 | { 391 | $result->map(function ($item) { 392 | $item->append($this->appends); 393 | return $item; 394 | }); 395 | 396 | return $result; 397 | } 398 | 399 | /** 400 | * Paginate the given query. 401 | * 402 | * @param int $perPage 403 | * @param array $columns 404 | * @param string $pageName 405 | * @param int|null $page 406 | * @return Paginator 407 | * 408 | * @throws \InvalidArgumentException 409 | */ 410 | private function basePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null) 411 | { 412 | $page = $page ?: BasePaginator::resolveCurrentPage($pageName); 413 | 414 | $perPage = $perPage ?: $this->model->getPerPage(); 415 | 416 | if (method_exists($this->query, 'toBase')) { 417 | $query = $this->query->toBase(); 418 | } else { 419 | $query = $this->query->getQuery(); 420 | } 421 | 422 | $total = $query->getCountForPagination(); 423 | 424 | $results = $total ? $this->query->forPage($page, $perPage)->get($columns) : new Collection; 425 | 426 | return (new Paginator($results, $total, $perPage, $page, [ 427 | 'path' => BasePaginator::resolveCurrentPath(), 428 | 'pageName' => $pageName, 429 | ]))->setQueryUri($this->uriParser->getQueryUri()); 430 | } 431 | } 432 | -------------------------------------------------------------------------------- /src/RequestCreator.php: -------------------------------------------------------------------------------- 1 | 0) { 40 | $requestQueryString .= '?'; 41 | 42 | foreach ($get as $paramKey => $paramValue) { 43 | preg_match(UriParser::getPattern(), $paramValue, $matches); 44 | 45 | if (count($matches) == 0) { 46 | $paramValue = sprintf('=%s', $paramValue); 47 | } 48 | 49 | $requestQueryString .= sprintf('%s%s', $paramKey, $paramValue) . '&'; 50 | } 51 | } 52 | 53 | if (substr($requestQueryString, -1) == '&') { 54 | $requestQueryString = substr($requestQueryString, 0, strlen($requestQueryString) - 1); 55 | } 56 | 57 | $server['REQUEST_URI'] = $requestUri . $requestQueryString; 58 | 59 | return new Request($get, $post, $attrs, $cookies, $files, $server); 60 | } 61 | } -------------------------------------------------------------------------------- /src/UriParser.php: -------------------------------------------------------------------------------- 1 | =|>/'; 10 | 11 | const ARRAY_QUERY_PATTERN = '/(.*)\[\]/'; 12 | 13 | protected $request; 14 | 15 | protected $constantParameters = [ 16 | 'order_by', 17 | 'group_by', 18 | 'limit', 19 | 'page', 20 | 'columns', 21 | 'includes', 22 | 'appends' 23 | ]; 24 | 25 | protected $uri; 26 | 27 | protected $queryUri; 28 | 29 | protected $queryParameters = []; 30 | 31 | public function __construct(Request $request) 32 | { 33 | $this->request = $request; 34 | 35 | $this->uri = $request->getRequestUri(); 36 | 37 | $this->setQueryUri($this->uri); 38 | 39 | if ($this->hasQueryUri()) { 40 | $this->setQueryParameters($this->queryUri); 41 | } 42 | } 43 | 44 | public static function getPattern() 45 | { 46 | return self::PATTERN; 47 | } 48 | 49 | public static function getArrayQueryPattern() 50 | { 51 | return self::ARRAY_QUERY_PATTERN; 52 | } 53 | 54 | public function queryParameter($key) 55 | { 56 | $keys = array_pluck($this->queryParameters, 'key'); 57 | 58 | $queryParameters = array_combine($keys, $this->queryParameters); 59 | 60 | return $queryParameters[$key]; 61 | } 62 | 63 | public function constantParameters() 64 | { 65 | return $this->constantParameters; 66 | } 67 | 68 | public function whereParameters() 69 | { 70 | return array_filter( 71 | $this->queryParameters, 72 | function ($queryParameter) { 73 | $key = $queryParameter['key']; 74 | return (!in_array($key, $this->constantParameters)); 75 | } 76 | ); 77 | } 78 | 79 | private function setQueryUri($uri) 80 | { 81 | $explode = explode('?', $uri); 82 | 83 | $this->queryUri = (isset($explode[1])) ? rawurldecode($explode[1]) : null; 84 | } 85 | 86 | private function setQueryParameters($queryUri) 87 | { 88 | $queryParameters = array_filter(explode('&', $queryUri)); 89 | 90 | array_map([$this, 'appendQueryParameter'], $queryParameters); 91 | } 92 | 93 | private function appendQueryParameter($parameter) 94 | { 95 | // whereIn expression 96 | preg_match(self::ARRAY_QUERY_PATTERN, $parameter, $arrayMatches); 97 | if (count($arrayMatches) > 0) { 98 | $this->appendQueryParameterAsWhereIn($parameter, $arrayMatches[1]); 99 | return; 100 | } 101 | 102 | // basic where expression 103 | $this->appendQueryParameterAsBasicWhere($parameter); 104 | } 105 | 106 | private function appendQueryParameterAsBasicWhere($parameter) 107 | { 108 | preg_match(self::PATTERN, $parameter, $matches); 109 | 110 | $operator = $matches[0]; 111 | 112 | list($key, $value) = explode($operator, $parameter); 113 | 114 | if (!$this->isConstantParameter($key) && $this->isLikeQuery($value)) { 115 | $operator = 'like'; 116 | $value = str_replace('*', '%', $value); 117 | } 118 | 119 | $this->queryParameters[] = [ 120 | 'type' => 'Basic', 121 | 'key' => $key, 122 | 'operator' => $operator, 123 | 'value' => $value 124 | ]; 125 | } 126 | 127 | private function appendQueryParameterAsWhereIn($parameter, $key) 128 | { 129 | if (str_contains($parameter, '!=')) { 130 | $type = 'NotIn'; 131 | $seperator = '!='; 132 | } else { 133 | $type = 'In'; 134 | $seperator = '='; 135 | } 136 | 137 | $index = null; 138 | foreach ($this->queryParameters as $_index => $queryParameter) { 139 | if ($queryParameter['type'] == $type && $queryParameter['key'] == $key) { 140 | $index = $_index; 141 | break; 142 | } 143 | } 144 | 145 | if ($index !== null) { 146 | $this->queryParameters[$index]['values'][] = explode($seperator, $parameter)[1]; 147 | } else { 148 | $this->queryParameters[] = [ 149 | 'type' => $type, 150 | 'key' => $key, 151 | 'values' => [explode($seperator, $parameter)[1]] 152 | ]; 153 | } 154 | } 155 | 156 | public function hasQueryUri() 157 | { 158 | return ($this->queryUri); 159 | } 160 | 161 | public function getQueryUri() 162 | { 163 | return $this->queryUri; 164 | } 165 | 166 | public function hasQueryParameters() 167 | { 168 | return (count($this->queryParameters) > 0); 169 | } 170 | 171 | public function hasQueryParameter($key) 172 | { 173 | $keys = array_pluck($this->queryParameters, 'key'); 174 | 175 | return (in_array($key, $keys)); 176 | } 177 | 178 | private function isLikeQuery($query) 179 | { 180 | $pattern = "/^\*|\*$/"; 181 | 182 | return (preg_match($pattern, $query, $matches)); 183 | } 184 | 185 | private function isConstantParameter($key) 186 | { 187 | return (in_array($key, $this->constantParameters)); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/config.php: -------------------------------------------------------------------------------- 1 | 15, 5 | 'orderBy' => [ 6 | [ 7 | 'column' => 'id', 8 | 'direction' => 'desc' 9 | ] 10 | ], 11 | 'excludedParameters' => [], 12 | ]; 13 | -------------------------------------------------------------------------------- /tests/BaseTestCase.php: -------------------------------------------------------------------------------- 1 | $val) { 10 | $this->assertArrayHasKey($key, $haystack); 11 | 12 | if (is_array($val)) { 13 | $this->assertArrayContainsArray($val, $haystack[$key]); 14 | } else { 15 | $this->assertEquals($val, $haystack[$key]); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/UriParserTest.php: -------------------------------------------------------------------------------- 1 | getUriParser(); 16 | 17 | $expected = [ 18 | 'type' => 'Basic', 19 | 'key' => 'some-param', 20 | 'operator' => '=', 21 | 'value' => 'some-param-value' 22 | ]; 23 | 24 | $this->assertEquals($expected, $uriParser->queryParameter('some-param')); 25 | } 26 | 27 | /** 28 | * @test 29 | */ 30 | public function it_gets_constant_parameters() 31 | { 32 | $uriParser = $this->getUriParser(); 33 | 34 | $constants = [ 35 | 'order_by', 36 | 'group_by', 37 | 'limit', 38 | 'page', 39 | 'columns', 40 | 'includes', 41 | 'appends', 42 | ]; 43 | 44 | $this->assertArrayContainsArray($constants, $uriParser->constantParameters()); 45 | } 46 | 47 | /** 48 | * @test 49 | */ 50 | public function it_gets_where_parameters() 51 | { 52 | $uriParser = $this->getUriParser(); 53 | 54 | $expected = [ 55 | [ 56 | 'type' => 'Basic', 57 | 'key' => 'some-param', 58 | 'operator' => '=', 59 | 'value' => 'some-param-value' 60 | ] 61 | ]; 62 | 63 | $this->assertEquals($expected, $uriParser->whereParameters()); 64 | } 65 | 66 | /** 67 | * @test 68 | */ 69 | public function it_checks_has_query_uri() 70 | { 71 | $uriParser = $this->getUriParser(); 72 | $this->assertEquals('some-param=some-param-value', $uriParser->hasQueryUri()); 73 | } 74 | 75 | /** 76 | * @test 77 | */ 78 | public function it_gets_query_uri() 79 | { 80 | $uriParser = $this->getUriParser(); 81 | $this->assertEquals('some-param=some-param-value', $uriParser->getQueryUri()); 82 | } 83 | 84 | /** 85 | * @test 86 | */ 87 | public function it_checks_has_query_parameters() 88 | { 89 | $uriParser = $this->getUriParser(); 90 | $this->assertTrue($uriParser->hasQueryParameters()); 91 | } 92 | 93 | /** 94 | * @test 95 | */ 96 | public function it_checks_has_query_parameter() 97 | { 98 | $uriParser = $this->getUriParser(); 99 | $this->assertTrue($uriParser->hasQueryParameter('some-param')); 100 | } 101 | 102 | /** 103 | * @param array $params 104 | * @return UriParser 105 | */ 106 | protected function getUriParser($params = null) 107 | { 108 | if(is_null($params)) { 109 | $params = ['some-param' => 'some-param-value']; 110 | } 111 | 112 | $request = Request::create('/some-uri', 'GET', $params); 113 | 114 | return new UriParser($request); 115 | } 116 | } --------------------------------------------------------------------------------