├── .gitignore
├── src
├── Orderable.php
└── OrderingScope.php
├── phpunit.xml
├── composer.json
├── LICENCE.txt
├── readme.md
└── tests
└── OrderableTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.lock
3 | /.idea
--------------------------------------------------------------------------------
/src/Orderable.php:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | ./tests/
15 |
16 |
17 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "zigastrgar/orderable",
3 | "type": "laravel-package",
4 | "description": "Ordering package for Laravel 5.x",
5 | "homepage": "https://github.com/ZigaStrgar/orderable",
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "ZigaStrgar",
10 | "email": "ziga_strgar@hotmail.com"
11 | }
12 | ],
13 | "minimum-stability": "stable",
14 | "autoload": {
15 | "psr-4": {
16 | "ZigaStrgar\\Orderable\\": "src/"
17 | }
18 | },
19 | "require": {
20 | "illuminate/support": "^5.3"
21 | },
22 | "require-dev": {
23 | "phpunit/phpunit": "^5.5",
24 | "illuminate/database": "^5.3"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/LICENCE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Žiga Strgar
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Orderable Laravel Package
2 |
3 | This is my very first Laravel package. I find it useful for me :) When I work with projects where I need to run a lot of `ORDER BY` queries.
4 |
5 | ## Instalation
6 |
7 | Add the Orderable package to your `composer.json` file.
8 |
9 | ```json
10 | {
11 | "require": {
12 | "zigastrgar/orderable": "^1.0"
13 | }
14 | }
15 | ```
16 |
17 | OR
18 |
19 | Simply run this in command line
20 |
21 | ```bash
22 | composer require zigastrgar/orderable
23 | ```
24 | ## Usage
25 |
26 | Go to any model and add this to the model.
27 |
28 | ```php
29 | use ZigaStrgar\Orderable\Orderable;
30 |
31 | class Article extends Model {
32 | use Orderable;
33 |
34 | public function orderable(){
35 | return [
36 | 'id' => 'DESC',
37 | 'title' => 'ASC',
38 | 'user_id'
39 | ];
40 | }
41 | }
42 | ```
43 |
44 | If you don't use the key like in `user_id` case it will default to `DESC`.
45 |
46 | ### Running "Orderable"
47 |
48 | It's super simple.
49 |
50 | ```php
51 | Article::all();
52 | ```
53 |
54 | #### Apply only specific rule
55 |
56 | From now on, you can also do something like this.
57 |
58 | ```php
59 | Article::order(); //Equals to Article::all();
60 | ```
61 |
62 | or
63 |
64 | ```php
65 | Article::order(['title']);
66 | ```
67 |
68 | and only rule for `title` will bi applied.
69 |
70 |
71 | ### Running without "Orderable"
72 |
73 | Same. Very simple stuff.
74 | ```php
75 | Article::unorderable();
76 | ```
77 |
78 | No scopes applied.
79 |
80 | #### Remove specific rule
81 |
82 | ```php
83 | Article::unorderable(['title']);
84 | ```
85 |
86 | In this case the rule for title won't be applied.
87 |
--------------------------------------------------------------------------------
/tests/OrderableTest.php:
--------------------------------------------------------------------------------
1 | truncate();
9 |
10 | $one = factory(Article::class)->create();
11 | factory(Article::class)->create();
12 | factory(Article::class)->create([ 'reads' => 10 ]);
13 | $two = factory(Article::class)->create([ 'reads' => 20 ]);
14 |
15 | $this->assertEquals($one->id, Article::all()->last()->id);
16 | $this->assertEquals($two->id, Article::all()->first()->id);
17 | }
18 |
19 | /** @test */
20 | function it_tests_the_orderable_call()
21 | {
22 | DB::table('articles')->truncate();
23 |
24 | $one = factory(Article::class)->create([ 'reads' => 20 ]);
25 | factory(Article::class)->create();
26 | factory(Article::class)->create([ 'reads' => 10 ]);
27 | $two = factory(Article::class)->create();
28 |
29 | $this->assertEquals($one->id, Article::order([ 'reads' ])->first()->id);
30 | $this->assertEquals($one->id, Article::order()->first()->id);
31 | $this->assertEquals($two->id, Article::order([ 'id' ])->first()->id);
32 | }
33 |
34 | /** @test */
35 | function it_test_unorderable_without_args()
36 | {
37 | DB::table('articles')->truncate();
38 |
39 | $one = factory(Article::class)->create();
40 | factory(Article::class)->create([ 'reads' => 20 ]);
41 |
42 | $this->assertEquals($one->id, Article::unorderable()->first()->id);
43 | }
44 |
45 | /** @test */
46 | function it_test_unorderable_with_args()
47 | {
48 | DB::table('articles')->truncate();
49 |
50 | factory(Article::class)->create();
51 | $one = factory(Article::class)->create([ 'reads' => 20 ]);
52 | $two = factory(Article::class)->create();
53 |
54 | $this->assertEquals($one->id, Article::unorderable([ 'id' ])->first()->id);
55 | $this->assertEquals($two->id, Article::unorderable([ 'reads' ])->first()->id);
56 | }
57 | }
--------------------------------------------------------------------------------
/src/OrderingScope.php:
--------------------------------------------------------------------------------
1 | getOrderByRules($builder) as $column => $order ) {
30 | if ( !is_int($column) ) {
31 | $builder->orderBy($column, $order);
32 | } else {
33 | $builder->orderBy($order, "DESC");
34 | }
35 | }
36 | }
37 |
38 | /**
39 | * Extend the query builder with the needed functions.
40 | *
41 | * @param \Illuminate\Database\Eloquent\Builder $builder
42 | *
43 | * @return void
44 | */
45 | public function extend(Builder $builder)
46 | {
47 | foreach ( $this->extensions as $extension ) {
48 | $this->{"add{$extension}"}($builder);
49 | }
50 | }
51 |
52 | /**
53 | * Get the "order by" rules for the builder.
54 | *
55 | * @param \Illuminate\Database\Eloquent\Builder $builder
56 | *
57 | * @return string
58 | */
59 | protected function getOrderByRules(Builder $builder)
60 | {
61 | return $builder->getModel()->orderable();
62 | }
63 |
64 | /**
65 | * Add the order extension to the builder.
66 | *
67 | * @param \Illuminate\Database\Eloquent\Builder $builder
68 | */
69 | protected function addOrder(Builder $builder)
70 | {
71 | $builder->macro('order', function(Builder $builder, $things = []) {
72 | if ( count($things) == 0 ) {
73 | return $builder->applyScopes();
74 | }
75 | $builder = $builder->getModel()->newQueryWithoutScopes();
76 | foreach ( $this->getOrderByRules($builder) as $column => $rule ) {
77 | if ( is_numeric($column) ) {
78 | $column = $rule;
79 | $rule = "DESC";
80 | }
81 | if ( in_array($column, $things) ) {
82 | $builder->orderBy($column, $rule);
83 | }
84 | }
85 |
86 | return $builder;
87 | });
88 | }
89 |
90 | /**
91 | * Add the unorderable extension to the builder.
92 | *
93 | * @param \Illuminate\Database\Eloquent\Builder $builder
94 | *
95 | * @internal param array $things
96 | */
97 | protected function addUnorderable(Builder $builder)
98 | {
99 | $builder->macro('unorderable', function(Builder $builder, $things = []) {
100 | if ( count($things) == 0 ) {
101 | return $builder->withoutGlobalScope($this);
102 | }
103 | $builder = $builder->getModel()->newQueryWithoutScopes();
104 | foreach ( $this->getOrderByRules($builder) as $column => $rule ) {
105 | if ( is_numeric($column) ) {
106 | $column = $rule;
107 | $rule = "DESC";
108 | }
109 | if ( in_array($column, $things) ) {
110 | continue;
111 | }
112 | $builder->orderBy($column, $rule);
113 | }
114 |
115 | return $builder;
116 | });
117 | }
118 | }
--------------------------------------------------------------------------------