Issues (16)

Branch: master

src/Collection/Page/Collection.php (2 issues)

1
<?php
2
3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cecil\Collection\Page;
15
16
use Cecil\Collection\Collection as CecilCollection;
17
use Cecil\Exception\RuntimeException;
18
19
/**
20
 * Pages collection class.
21
 *
22
 * Represents a collection of pages, providing methods to filter and sort them.
23
 */
24
class Collection extends CecilCollection
25
{
26
    /**
27
     * Returns all "showable" pages.
28
     */
29 1
    public function showable(): self
30
    {
31 1
        return $this->filter(function (Page $page) {
32
            if (
33 1
                $page->getVariable('published') === true      // page is published
34
                && (
35 1
                    $page->getVariable('excluded') !== true   // page is listed
36 1
                    && $page->getVariable('exclude') !== true // backward compatibility
37
                )
38 1
                && $page->isVirtual() === false               // page is created from a file
39 1
                && $page->getVariable('redirect') === null    // page is not a redirection
40
            ) {
41 1
                return true;
42
            }
43 1
        });
44
    }
45
46
    /**
47
     * Alias of showable().
48
     */
49
    public function all(): self
50
    {
51
        return $this->showable();
52
    }
53
54
    /**
55
     * Sorts pages by.
56
     *
57
     * $options:
58
     * [date|updated|title|weight]
59
     * or
60
     * [
61
     *   variable   => date|updated|title|weight
62
     *   desc_title => false|true
63
     *   reverse    => false|true
64
     * ]
65
     */
66 1
    public function sortBy(string|array|null $options): self
67
    {
68 1
        $sortBy = \is_string($options) ? $options : $options['variable'] ?? 'date';
0 ignored issues
show
The condition is_string($options) is always false.
Loading history...
69 1
        $sortMethod = \sprintf('sortBy%s', ucfirst(str_replace('updated', 'date', $sortBy)));
70 1
        if (!method_exists($this, $sortMethod)) {
71
            throw new RuntimeException(\sprintf('"%s" is not a valid value for `sortby` to sort collection "%s".', $sortBy, $this->getId()));
72
        }
73
74 1
        return $this->$sortMethod($options);
75
    }
76
77
    /**
78
     * Sorts pages by date (or 'updated'): the most recent first.
79
     */
80 1
    public function sortByDate(string|array|null $options = null): self
81
    {
82 1
        $opt = [];
83
        // backward compatibility (i.e. $options = 'updated')
84 1
        if (\is_string($options)) {
0 ignored issues
show
The condition is_string($options) is always false.
Loading history...
85 1
            $opt['variable'] = $options;
86
        }
87
        // options
88 1
        $opt['variable'] = $options['variable'] ?? 'date';
89 1
        $opt['descTitle'] = $options['descTitle'] ?? false;
90 1
        $opt['reverse'] = $options['reverse'] ?? false;
91
        // sort
92 1
        $pages = $this->usort(function ($a, $b) use ($opt) {
93 1
            if ($a[$opt['variable']] == $b[$opt['variable']]) {
94
                // if dates are equal and "descTitle" is true
95 1
                if ($opt['descTitle'] && (isset($a['title']) && isset($b['title']))) {
96
                    return strnatcmp($b['title'], $a['title']);
97
                }
98
99 1
                return 0;
100
            }
101
102 1
            return $a[$opt['variable']] > $b[$opt['variable']] ? -1 : 1;
103 1
        });
104 1
        if ($opt['reverse']) {
105
            $pages = $pages->reverse();
106
        }
107
108 1
        return $pages;
109
    }
110
111
    /**
112
     * Sorts pages by title (natural sort).
113
     */
114 1
    public function sortByTitle(string|array|null $options = null): self
115
    {
116 1
        $opt = [];
117
        // options
118 1
        $opt['reverse'] = $options['reverse'] ?? false;
119
        // sort
120 1
        return $this->usort(function ($a, $b) use ($opt) {
121 1
            return ($opt['reverse'] ? -1 : 1) * strnatcmp($a['title'], $b['title']);
122 1
        });
123
    }
124
125
    /**
126
     * Sorts by weight (the heaviest first).
127
     */
128
    public function sortByWeight(string|array|null $options = null): self
129
    {
130
        $opt = [];
131
        // options
132
        $opt['reverse'] = $options['reverse'] ?? false;
133
        // sort
134
        return $this->usort(function ($a, $b) use ($opt) {
135
            if ($a['weight'] == $b['weight']) {
136
                return 0;
137
            }
138
139
            return ($opt['reverse'] ? -1 : 1) * ($a['weight'] < $b['weight'] ? -1 : 1);
140
        });
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146 1
    public function get(string $id): Page
147
    {
148 1
        return parent::get($id);
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154 1
    public function first(): ?Page
155
    {
156 1
        return parent::first();
157
    }
158
159
    /**
160
     * {@inheritdoc}
161
     */
162 1
    public function filter(\Closure $callback): self
163
    {
164 1
        return parent::filter($callback);
165
    }
166
167
    /**
168
     * {@inheritdoc}
169
     */
170 1
    public function usort(?\Closure $callback = null): self
171
    {
172 1
        return parent::usort($callback);
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178
    public function reverse(): self
179
    {
180
        return parent::reverse();
181
    }
182
}
183