├── .github
└── workflows
│ └── php.yml
├── .gitignore
├── .php_cs
├── .travis.yml
├── LICENSE
├── composer.json
├── config
└── sidebar.php
├── phpunit.xml
├── readme.md
├── resources
└── views
│ ├── adminlte-2
│ ├── append.blade.php
│ ├── badge.blade.php
│ ├── group.blade.php
│ ├── item.blade.php
│ └── menu.blade.php
│ └── adminlte-3
│ ├── append.blade.php
│ ├── badge.blade.php
│ ├── group.blade.php
│ ├── item.blade.php
│ └── menu.blade.php
├── src
├── Append.php
├── Authorizable.php
├── Badge.php
├── Domain
│ ├── DefaultAppend.php
│ ├── DefaultBadge.php
│ ├── DefaultGroup.php
│ ├── DefaultItem.php
│ ├── DefaultMenu.php
│ └── Events
│ │ ├── FlushesSidebarCache.php
│ │ └── ShouldFlushCache.php
├── Exceptions
│ ├── CacheTagsNotSupported.php
│ ├── LogicException.php
│ ├── SidebarFlusherNotSupported.php
│ └── SidebarResolverNotSupported.php
├── Group.php
├── Infrastructure
│ ├── CacheKey.php
│ ├── ContainerResolver.php
│ ├── NullSidebarFlusher.php
│ ├── SidebarFlusher.php
│ ├── SidebarFlusherFactory.php
│ ├── SidebarResolver.php
│ ├── SidebarResolverFactory.php
│ ├── StaticCacheResolver.php
│ ├── StaticSidebarFlusher.php
│ ├── SupportsCacheTags.php
│ ├── UserBasedCacheResolver.php
│ └── UserBasedSidebarFlusher.php
├── Item.php
├── Itemable.php
├── Menu.php
├── Middleware
│ └── ResolveSidebars.php
├── Presentation
│ ├── ActiveStateChecker.php
│ ├── Illuminate
│ │ ├── IlluminateAppendRenderer.php
│ │ ├── IlluminateBadgeRenderer.php
│ │ ├── IlluminateGroupRenderer.php
│ │ ├── IlluminateItemRenderer.php
│ │ └── IlluminateSidebarRenderer.php
│ └── SidebarRenderer.php
├── Routeable.php
├── ShouldCache.php
├── Sidebar.php
├── SidebarExtender.php
├── SidebarManager.php
├── SidebarServiceProvider.php
└── Traits
│ ├── AuthorizableTrait.php
│ ├── CacheableTrait.php
│ ├── CallableTrait.php
│ ├── ItemableTrait.php
│ └── RouteableTrait.php
└── tests
├── Domain
├── DefaultAppendTest.php
├── DefaultBadgeTest.php
├── DefaultGroupTest.php
├── DefaultItemTest.php
└── DefaultMenuTest.php
├── SidebarExtenderTest.php
└── Traits
├── AuthorizableTraitTest.php
├── ItemableTraitTest.php
└── RouteableTraitTest.php
/.github/workflows/php.yml:
--------------------------------------------------------------------------------
1 | name: PHP Pipeline
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | strategy:
11 | max-parallel: 2
12 | matrix:
13 | php-versions: ['8.1', '8.2', '8.3']
14 |
15 | name: PHP ${{ matrix.php-versions }}
16 |
17 | steps:
18 | - uses: actions/checkout@v1
19 |
20 | - name: Setup PHP
21 | uses: shivammathur/setup-php@master
22 | with:
23 | php-version: ${{ matrix.php-versions }}
24 | coverage: xdebug
25 |
26 | - name: Validate composer.json and composer.lock
27 | run: composer validate
28 |
29 | - name: Install dependencies
30 | run: composer install --prefer-dist --no-progress --no-suggest
31 |
32 | - name: Run test suite
33 | run: composer run-script test
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.phar
3 | composer.lock
4 | .DS_Store
5 | .php_cs.cache
6 | /build
7 | coverage
8 | .phpunit.result.cache
9 | /.idea
10 | build/report.junit.xml
11 |
12 |
--------------------------------------------------------------------------------
/.php_cs:
--------------------------------------------------------------------------------
1 | exclude('vendor')
5 | ->in(__DIR__);
6 |
7 | return Symfony\CS\Config\Config::create()
8 | ->setUsingCache(true)
9 | ->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
10 | ->fixers(array(
11 | 'psr0',
12 | 'encoding',
13 | 'short_tag',
14 | 'blankline_after_open_tag',
15 | 'namespace_no_leading_whitespace',
16 | 'no_blank_lines_after_class_opening',
17 | 'single_array_no_trailing_comma',
18 | 'no_empty_lines_after_phpdocs',
19 | 'concat_with_spaces',
20 | 'eof_ending',
21 | 'ordered_use',
22 | 'extra_empty_lines',
23 | 'single_line_after_imports',
24 | 'trailing_spaces',
25 | 'remove_lines_between_uses',
26 | 'return',
27 | 'indentation',
28 | 'linefeed',
29 | 'braces',
30 | 'visibility',
31 | 'unused_use',
32 | 'whitespacy_lines',
33 | 'php_closing_tag',
34 | 'phpdoc_order',
35 | 'phpdoc_params',
36 | 'phpdoc_trim',
37 | 'phpdoc_scalar',
38 | 'short_array_syntax',
39 | 'align_double_arrow',
40 | 'align_equals',
41 | 'lowercase_constants',
42 | 'lowercase_keywords',
43 | 'multiple_use',
44 | 'line_after_namespace',
45 | 'function_call_space',
46 | ))->finder($finder);
47 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.4
5 | - 5.5
6 | - 5.6
7 |
8 | before_script:
9 | - travis_retry composer self-update
10 | - travis_retry composer install --prefer-source --no-interaction
11 |
12 | after_script:
13 | - wget https://scrutinizer-ci.com/ocular.phar
14 | - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
15 |
16 | script: phpunit --coverage-clover=coverage.clover
17 |
18 | matrix:
19 | fast_finish: true
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Maatwebsite
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "maatwebsite/laravel-sidebar",
3 | "description": "A sidebar builder for Laravel",
4 | "license": "MIT",
5 | "keywords": [
6 | "laravel",
7 | "sidebar",
8 | "menu",
9 | "acp"
10 | ],
11 | "authors": [
12 | {
13 | "name": "Maatwebsite.nl",
14 | "email": "patrick@maatwebsite.nl"
15 | }
16 | ],
17 | "require": {
18 | "php": "^8.1",
19 | "illuminate/cache": "~10.0|~11.0",
20 | "illuminate/container": "~10.0|~11.0",
21 | "illuminate/contracts": "~10.0|~11.0",
22 | "illuminate/support": "~10.0|~11.0",
23 | "illuminate/routing": "~10.0|~11.0",
24 | "illuminate/view": "~10.0|~11.0"
25 | },
26 | "require-dev": {
27 | "mockery/mockery": "^1.6",
28 | "phpunit/phpunit": "^10.4"
29 | },
30 | "autoload": {
31 | "psr-4": {
32 | "Maatwebsite\\Sidebar\\": "src/"
33 | }
34 | },
35 | "autoload-dev": {
36 | "psr-4": {
37 | "Maatwebsite\\Sidebar\\Tests\\": "tests/"
38 | }
39 | },
40 | "extra": {
41 | "laravel": {
42 | "providers": [
43 | "Maatwebsite\\Sidebar\\SidebarServiceProvider"
44 | ]
45 | }
46 | },
47 | "config": {
48 | "preferred-install": "dist"
49 | },
50 | "scripts": {
51 | "test": "vendor/bin/phpunit",
52 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage"
53 | },
54 | "minimum-stability": "dev",
55 | }
56 |
--------------------------------------------------------------------------------
/config/sidebar.php:
--------------------------------------------------------------------------------
1 | [
16 | 'method' => null,
17 | 'duration' => 1440
18 | ],
19 |
20 | /*
21 | |--------------------------------------------------------------------------
22 | | View Name
23 | |--------------------------------------------------------------------------
24 | |
25 | | Choose a view to use to render the sidebar.
26 | | Built in templates are:
27 | |
28 | | - 'AdminLTE2' - Bootstrap 3
29 | | - 'AdminLTE3' - Bootstrap 4
30 | | - 'AdminLTE4' - Bootstrap 5 (coming soon)
31 | | Or a custom view, for example 'custom'. [by default AdminLTE2 will be used so you can publish and modify it as you wish ].
32 | |
33 | */
34 | 'view' => 'AdminLTE2',
35 | ];
36 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | ./tests/
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ./src
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # WARNING! Not actively supported or maintained.
2 |
3 | # Laravel Sidebar
4 |
5 | [](https://packagist.org/packages/maatwebsite/laravel-sidebar)
6 | [](https://travis-ci.org/Maatwebsite/Laravel-Sidebar)
7 | [](https://github.com/Maatwebsite/Laravel-Sidebar)
8 | [](https://packagist.org/packages/maatwebsite/laravel-sidebar)
9 | [](https://packagist.org/packages/maatwebsite/laravel-sidebar)
10 | [](https://packagist.org/packages/maatwebsite/laravel-sidebar)
11 |
12 | ## Installation
13 |
14 | Require this package in your `composer.json` and run `composer update`.
15 |
16 | ```php
17 | "maatwebsite/laravel-sidebar": "~2.1"
18 | ```
19 |
20 | After updating composer, add the ServiceProvider to the providers array in `config/app.php`
21 |
22 | ```php
23 | 'Maatwebsite\Sidebar\SidebarServiceProvider',
24 | ```
25 |
26 | Add the package middleware to `App\Http\Kernel`:
27 |
28 | ```php
29 | `'Maatwebsite\Sidebar\Middleware\ResolveSidebars'`
30 | ```
31 |
32 | To publish the default views use:
33 |
34 | ```php
35 | php artisan vendor:publish --tag="views"
36 | ```
37 |
38 | To publish the config use:
39 |
40 | ```php
41 | php artisan vendor:publish --tag="config"
42 | ```
43 |
44 | ## Documentation
45 |
46 | See the wiki: https://github.com/Maatwebsite/Laravel-Sidebar/wiki
47 |
48 | ## Contributing
49 |
50 | **ALL contributions** should be made to appropriate branch (e.g. 2.0 for 2.0.* bug fixes). Bug fixes should never be sent to the master branch.
51 |
52 | We follow PSR-1, PSR-2 and PSR-4 coding styles.
53 |
54 | Added or fixed functionality should be backed with unit tests.
55 |
56 | ## License
57 |
58 | This package is licensed under MIT. You are free to use it in personal and commercial projects.
59 |
--------------------------------------------------------------------------------
/resources/views/adminlte-2/append.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/resources/views/adminlte-2/badge.blade.php:
--------------------------------------------------------------------------------
1 | {{ $badge->getValue() }}
2 |
--------------------------------------------------------------------------------
/resources/views/adminlte-2/group.blade.php:
--------------------------------------------------------------------------------
1 | @if($group->shouldShowHeading())
2 |
3 | @endif
4 |
5 | @foreach($items as $item)
6 | {!! $item !!}
7 | @endforeach
8 |
--------------------------------------------------------------------------------
/resources/views/adminlte-2/item.blade.php:
--------------------------------------------------------------------------------
1 |
2 | getNewTab())target="_blank"@endif>
3 |
4 | {{ $item->getName() }}
5 |
6 | @foreach($badges as $badge)
7 | {!! $badge !!}
8 | @endforeach
9 |
10 | @if($item->hasItems())@endif
11 |
12 |
13 | @foreach($appends as $append)
14 | {!! $append !!}
15 | @endforeach
16 |
17 | @if(count($items) > 0)
18 |
23 | @endif
24 |
25 |
--------------------------------------------------------------------------------
/resources/views/adminlte-2/menu.blade.php:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/resources/views/adminlte-3/append.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/resources/views/adminlte-3/badge.blade.php:
--------------------------------------------------------------------------------
1 | {{ $badge->getValue() }}
2 |
--------------------------------------------------------------------------------
/resources/views/adminlte-3/group.blade.php:
--------------------------------------------------------------------------------
1 | @if($group->shouldShowHeading())
2 |
3 | @endif
4 |
5 | @foreach($items as $item)
6 | {!! $item !!}
7 | @endforeach
8 |
--------------------------------------------------------------------------------
/resources/views/adminlte-3/item.blade.php:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/resources/views/adminlte-3/menu.blade.php:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/Append.php:
--------------------------------------------------------------------------------
1 | container = $container;
47 | }
48 |
49 | /**
50 | * @return null|string
51 | */
52 | public function getName()
53 | {
54 | return $this->name;
55 | }
56 |
57 | /**
58 | * @param null|string $name
59 | *
60 | * @return $this
61 | */
62 | public function name($name)
63 | {
64 | $this->name = $name;
65 |
66 | return $this;
67 | }
68 |
69 | /**
70 | * @return string
71 | */
72 | public function getIcon()
73 | {
74 | return $this->icon;
75 | }
76 |
77 | /**
78 | * @param string $icon
79 | *
80 | * @return $this
81 | */
82 | public function icon($icon)
83 | {
84 | $this->icon = $icon;
85 |
86 | return $this;
87 | }
88 |
89 | public function __serialize():array
90 | {
91 | return [
92 | 'name' => $this->name,
93 | 'url' => $this->url,
94 | 'icon' => $this->icon,
95 | ];
96 | }
97 |
98 | public function __unserialize(array $data): void
99 | {
100 | $this->name = $data['name'];
101 | $this->url = $data['url'];
102 | $this->icon = $data['icon'];
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/Domain/DefaultBadge.php:
--------------------------------------------------------------------------------
1 | container = $container;
45 | }
46 |
47 | /**
48 | * @return mixed
49 | */
50 | public function getValue()
51 | {
52 | return $this->value;
53 | }
54 |
55 | /**
56 | * @param mixed $value
57 | *
58 | * @return Badge
59 | */
60 | public function setValue($value)
61 | {
62 | $this->value = $value;
63 |
64 | return $this;
65 | }
66 |
67 | /**
68 | * @return string
69 | */
70 | public function getClass()
71 | {
72 | return $this->class;
73 | }
74 |
75 | /**
76 | * @param string $class
77 | *
78 | * @return Badge
79 | */
80 | public function setClass($class)
81 | {
82 | $this->class = $class;
83 |
84 | return $this;
85 | }
86 |
87 | public function __serialize():array
88 | {
89 | return [
90 | 'value' => $this->value,
91 | 'class' => $this->class,
92 | ];
93 | }
94 |
95 | public function __unserialize(array $data): void
96 | {
97 | $this->value = $data['value'];
98 | $this->class = $data['class'];
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Domain/DefaultGroup.php:
--------------------------------------------------------------------------------
1 | container = $container;
56 | $this->items = new Collection();
57 | }
58 |
59 | /**
60 | * @param string $name
61 | *
62 | * @return Group
63 | */
64 | public function name($name)
65 | {
66 | $this->name = $name;
67 |
68 | return $this;
69 | }
70 |
71 | /**
72 | * @return string
73 | */
74 | public function getName()
75 | {
76 | return $this->name;
77 | }
78 |
79 | /**
80 | * @param int $weight
81 | *
82 | * @return Group
83 | */
84 | public function weight($weight)
85 | {
86 | if (!is_int($weight)) {
87 | throw new LogicException('Weight should be an integer');
88 | }
89 |
90 | $this->weight = $weight;
91 |
92 | return $this;
93 | }
94 |
95 | /**
96 | * @return int
97 | */
98 | public function getWeight()
99 | {
100 | return $this->weight;
101 | }
102 |
103 | /**
104 | * @param bool $hide
105 | *
106 | * @return Group
107 | */
108 | public function hideHeading($hide = true)
109 | {
110 | $this->heading = !$hide;
111 |
112 | return $this;
113 | }
114 |
115 | /**
116 | * @return bool
117 | */
118 | public function shouldShowHeading()
119 | {
120 | return $this->heading ? true : false;
121 | }
122 |
123 | public function __serialize():array
124 | {
125 | return [
126 | 'name' => $this->name,
127 | 'items' => $this->items,
128 | 'weight' => $this->weight,
129 | 'heading' => $this->heading,
130 | ];
131 | }
132 |
133 | public function __unserialize(array $data): void
134 | {
135 | $this->name = $data['name'];
136 | $this->items = $data['items'];
137 | $this->weight = $data['weight'];
138 | $this->heading = $data['heading'];
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/Domain/DefaultItem.php:
--------------------------------------------------------------------------------
1 | container = $container;
94 | $this->items = new Collection();
95 | $this->badges = new Collection();
96 | $this->appends = new Collection();
97 | }
98 |
99 | /**
100 | * @return string
101 | */
102 | public function getName()
103 | {
104 | return $this->name;
105 | }
106 |
107 | /**
108 | * @param mixed $name
109 | *
110 | * @return Item $item
111 | */
112 | public function name($name)
113 | {
114 | $this->name = $name;
115 |
116 | return $this;
117 | }
118 |
119 | /**
120 | * @param int $weight
121 | *
122 | * @return Item
123 | */
124 | public function weight($weight)
125 | {
126 | if (!is_int($weight)) {
127 | throw new LogicException('Weight should be an integer');
128 | }
129 |
130 | $this->weight = $weight;
131 |
132 | return $this;
133 | }
134 |
135 | /**
136 | * @return int
137 | */
138 | public function getWeight()
139 | {
140 | return $this->weight;
141 | }
142 |
143 | /**
144 | * @return string
145 | */
146 | public function getIcon()
147 | {
148 | return $this->icon;
149 | }
150 |
151 | /**
152 | * @param string $icon
153 | *
154 | * @return Item
155 | */
156 | public function icon($icon)
157 | {
158 | $this->icon = $icon;
159 |
160 | return $this;
161 | }
162 |
163 | /**
164 | * @return string
165 | */
166 | public function getToggleIcon()
167 | {
168 | return $this->toggleIcon;
169 | }
170 |
171 | /**
172 | * @param string $icon
173 | *
174 | * @return Item
175 | */
176 | public function toggleIcon($icon)
177 | {
178 | $this->toggleIcon = $icon;
179 |
180 | return $this;
181 | }
182 |
183 | /**
184 | * @param callable|null|string $callbackOrValue
185 | * @param string|null $className
186 | *
187 | * @return Badge
188 | */
189 | public function badge($callbackOrValue = null, $className = null)
190 | {
191 | $badge = $this->container->make('Maatwebsite\Sidebar\Badge');
192 |
193 | if (is_callable($callbackOrValue)) {
194 | $this->call($callbackOrValue, $badge);
195 | } elseif ($callbackOrValue) {
196 | $badge->setValue($callbackOrValue);
197 | }
198 |
199 | if ($className) {
200 | $badge->setClass($className);
201 | }
202 |
203 | $this->addBadge($badge);
204 |
205 | return $badge;
206 | }
207 |
208 | /**
209 | * @param Badge $badge
210 | *
211 | * @return Badge
212 | */
213 | public function addBadge(Badge $badge)
214 | {
215 | $this->badges->push($badge);
216 |
217 | return $badge;
218 | }
219 |
220 | /**
221 | * @return Collection|Badge[]
222 | */
223 | public function getBadges()
224 | {
225 | return $this->badges;
226 | }
227 |
228 | /**
229 | * @param null $callbackOrRoute
230 | * @param string|null $icon
231 | * @param null $name
232 | *
233 | * @return Append
234 | */
235 | public function append($callbackOrRoute = null, $icon = null, $name = null)
236 | {
237 | $append = $this->container->make('Maatwebsite\Sidebar\Append');
238 |
239 | if (is_callable($callbackOrRoute)) {
240 | $this->call($callbackOrRoute, $append);
241 | } elseif ($callbackOrRoute) {
242 | $append->route($callbackOrRoute);
243 | }
244 |
245 | if ($name) {
246 | $append->name($name);
247 | }
248 |
249 | if ($icon) {
250 | $append->icon($icon);
251 | }
252 |
253 | $this->addAppend($append);
254 |
255 | return $append;
256 | }
257 |
258 | /**
259 | * @param Append $append
260 | *
261 | * @return Append
262 | */
263 | public function addAppend(Append $append)
264 | {
265 | $this->appends->push($append);
266 |
267 | return $append;
268 | }
269 |
270 | /**
271 | * @return Collection|Append[]
272 | */
273 | public function getAppends()
274 | {
275 | return $this->appends;
276 | }
277 |
278 | /**
279 | * @param string $path
280 | *
281 | * @return $this
282 | */
283 | public function isActiveWhen($path)
284 | {
285 | // Remove unwanted chars
286 | $path = ltrim($path, '/');
287 | $path = rtrim($path, '/');
288 | $path = rtrim($path, '?');
289 |
290 | $this->activeWhen = $path;
291 |
292 | return $this;
293 | }
294 |
295 | /**
296 | * @return string
297 | */
298 | public function getActiveWhen()
299 | {
300 | return $this->activeWhen;
301 | }
302 |
303 | /**
304 | * @param bool $newTab
305 | *
306 | * @return $this
307 | */
308 | public function isNewTab($newTab = true)
309 | {
310 | $this->newTab = $newTab;
311 |
312 | return $this;
313 | }
314 |
315 | /**
316 | * @return bool
317 | */
318 | public function getNewTab()
319 | {
320 | return $this->newTab;
321 | }
322 |
323 | /**
324 | * @param string $itemClass
325 | *
326 | * @return $this
327 | */
328 | public function setItemClass($itemClass)
329 | {
330 | $this->itemClass = $itemClass;
331 |
332 | return $this;
333 | }
334 |
335 | /**
336 | * @return string
337 | */
338 | public function getItemClass()
339 | {
340 | return $this->itemClass;
341 | }
342 |
343 | public function __serialize():array
344 | {
345 | return [
346 | 'name' => $this->name,
347 | 'weight' => $this->weight,
348 | 'url' => $this->url,
349 | 'icon' => $this->icon,
350 | 'toggleIcon' => $this->toggleIcon,
351 | 'items' => $this->items,
352 | 'badges' => $this->badges,
353 | 'appends' => $this->appends,
354 | 'authorized' => $this->authorized,
355 | ];
356 | }
357 |
358 | public function __unserialize(array $data): void
359 | {
360 | $this->name = $data['name'];
361 | $this->weight = $data['weight'];
362 | $this->url = $data['url'];
363 | $this->icon = $data['icon'];
364 | $this->toggleIcon = $data['toggleIcon'];
365 | $this->items = $data['items'];
366 | $this->badges = $data['badges'];
367 | $this->appends = $data['appends'];
368 | $this->authorized = $data['authorized'];
369 | }
370 | }
371 |
--------------------------------------------------------------------------------
/src/Domain/DefaultMenu.php:
--------------------------------------------------------------------------------
1 | container = $container;
43 | $this->groups = new Collection();
44 | }
45 |
46 | /**
47 | * Init a new group or call an existing group and add it to the menu
48 | *
49 | * @param $name
50 | * @param callable $callback
51 | *
52 | * @return Group
53 | */
54 | public function group($name, Closure $callback = null)
55 | {
56 | if ($this->groups->has($name)) {
57 | $group = $this->groups->get($name);
58 | } else {
59 | $group = $this->container->make('Maatwebsite\Sidebar\Group');
60 | $group->name($name);
61 | }
62 |
63 | $this->call($callback, $group);
64 |
65 | $this->addGroup($group);
66 |
67 | return $group;
68 | }
69 |
70 | /**
71 | * Add a Group instance to the Menu
72 | *
73 | * @param Group $group
74 | *
75 | * @return $this
76 | */
77 | public function addGroup(Group $group)
78 | {
79 | $this->groups->put($group->getName(), $group);
80 |
81 | return $this;
82 | }
83 |
84 | /**
85 | * Get collection of Group instances sorted by their weight
86 | * @return Collection|Group[]
87 | */
88 | public function getGroups()
89 | {
90 | return $this->groups->sortBy(function (Group $group) {
91 | return $group->getWeight();
92 | });
93 | }
94 |
95 | /**
96 | * Add another Menu instance and combined the two
97 | * Groups with the same name get combined, but
98 | * inherit each other's items
99 | *
100 | * @param Menu $menu
101 | *
102 | * @return Menu $menu
103 | */
104 | public function add(Menu $menu)
105 | {
106 | foreach ($menu->getGroups() as $group) {
107 | if ($this->groups->has($group->getName())) {
108 | $existingGroup = $this->groups->get($group->getName());
109 |
110 | $group->hideHeading(!$group->shouldShowHeading());
111 |
112 | foreach ($group->getItems() as $item) {
113 | $existingGroup->addItem($item);
114 | }
115 | } else {
116 | $this->addGroup($group);
117 | }
118 | }
119 |
120 | return $this;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/Domain/Events/FlushesSidebarCache.php:
--------------------------------------------------------------------------------
1 | manager = $manager;
27 | $this->container = $container;
28 | }
29 |
30 | /**
31 | * Flush the sidebar cache
32 | */
33 | public function handle()
34 | {
35 | $this->container->call([
36 | $this->manager,
37 | 'flush'
38 | ]);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Domain/Events/ShouldFlushCache.php:
--------------------------------------------------------------------------------
1 | container = $container;
22 | }
23 |
24 | /**
25 | * @param $name
26 | *
27 | * @throws LogicException
28 | * @return Sidebar
29 | */
30 | public function resolve($name)
31 | {
32 | $sidebar = $this->container->make($name);
33 |
34 | if (!$sidebar instanceof Sidebar) {
35 | throw new LogicException('Your sidebar should implement the Sidebar interface');
36 | }
37 |
38 | $sidebar->build();
39 |
40 | return $sidebar;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Infrastructure/NullSidebarFlusher.php:
--------------------------------------------------------------------------------
1 | cache = $cache;
33 | $this->resolver = $resolver;
34 | $this->config = $config;
35 | }
36 |
37 | /**
38 | * @param $name
39 | *
40 | * @return Sidebar
41 | */
42 | public function resolve($name)
43 | {
44 | $duration = $this->config->get('sidebar.cache.duration');
45 |
46 | return $this->cache->remember(CacheKey::get($name), $duration, function () use ($name) {
47 | return $this->resolver->resolve($name);
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Infrastructure/StaticSidebarFlusher.php:
--------------------------------------------------------------------------------
1 | cache = $cache;
20 | }
21 |
22 | /**
23 | * Flush
24 | *
25 | * @param $name
26 | */
27 | public function flush($name)
28 | {
29 | $this->cache->forget(CacheKey::get($name));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Infrastructure/SupportsCacheTags.php:
--------------------------------------------------------------------------------
1 | getStore(), 'tags')) {
19 | throw new CacheTagsNotSupported('Cache tags are necessary to use this kind of caching. Consider using a different caching method');
20 | }
21 |
22 | return true;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Infrastructure/UserBasedCacheResolver.php:
--------------------------------------------------------------------------------
1 | cache = $cache;
40 | $this->resolver = $resolver;
41 | $this->guard = $guard;
42 | $this->config = $config;
43 | }
44 |
45 | /**
46 | * @param $name
47 | *
48 | * @return Sidebar
49 | */
50 | public function resolve($name)
51 | {
52 | if ((new SupportsCacheTags())->isSatisfiedBy($this->cache)) {
53 | $userId = $this->guard->check() ? $this->guard->user()->getAuthIdentifier() : null;
54 | $duration = $this->config->get('sidebar.cache.duration');
55 |
56 | return $this->cache->tags(CacheKey::get($name))->remember(CacheKey::get($name, $userId), $duration, function () use ($name) {
57 | return $this->resolver->resolve($name);
58 | });
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Infrastructure/UserBasedSidebarFlusher.php:
--------------------------------------------------------------------------------
1 | cache = $cache;
20 | }
21 |
22 | /**
23 | * Flush
24 | *
25 | * @param $name
26 | */
27 | public function flush($name)
28 | {
29 | if ((new SupportsCacheTags())->isSatisfiedBy($this->cache)) {
30 | $this->cache->tags(CacheKey::get($name))->flush();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Item.php:
--------------------------------------------------------------------------------
1 | manager = $manager;
21 | }
22 |
23 | /**
24 | * Handle an incoming request.
25 | *
26 | * @param \Illuminate\Http\Request $request
27 | * @param \Closure $next
28 | *
29 | * @return mixed
30 | */
31 | public function handle($request, Closure $next)
32 | {
33 | $this->manager->resolve();
34 |
35 | return $next($request);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Presentation/ActiveStateChecker.php:
--------------------------------------------------------------------------------
1 | getItems() as $child) {
19 | if ($this->isActive($child)) {
20 | return true;
21 | }
22 | }
23 |
24 | // Custom set active path
25 | if ($path = $item->getActiveWhen()) {
26 | return Request::is(
27 | $path
28 | );
29 | }
30 |
31 | $path = ltrim(str_replace(url('/'), '', $item->getUrl()), '/');
32 |
33 | return Request::is(
34 | $path,
35 | $path . '/*'
36 | );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Presentation/Illuminate/IlluminateAppendRenderer.php:
--------------------------------------------------------------------------------
1 | factory = $factory;
26 | }
27 |
28 | /**
29 | * @param Append $append
30 | *
31 | * @return \Illuminate\Contracts\View\View
32 | */
33 | public function render(Append $append)
34 | {
35 | if ($append->isAuthorized()) {
36 | return $this->factory->make($this->view, [
37 | 'append' => $append
38 | ])->render();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Presentation/Illuminate/IlluminateBadgeRenderer.php:
--------------------------------------------------------------------------------
1 | factory = $factory;
26 | }
27 |
28 | /**
29 | * @param Badge $badge
30 | *
31 | * @return \Illuminate\Contracts\View\View
32 | */
33 | public function render(Badge $badge)
34 | {
35 | if ($badge->isAuthorized()) {
36 | return $this->factory->make($this->view, [
37 | 'badge' => $badge
38 | ])->render();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Presentation/Illuminate/IlluminateGroupRenderer.php:
--------------------------------------------------------------------------------
1 | factory = $factory;
26 | }
27 |
28 | /**
29 | * @param Group $group
30 | *
31 | * @return \Illuminate\Contracts\View\View
32 | */
33 | public function render(Group $group)
34 | {
35 | if ($group->isAuthorized()) {
36 | $items = [];
37 | foreach ($group->getItems() as $item) {
38 | $items[] = (new IlluminateItemRenderer($this->factory))->render($item);
39 | }
40 |
41 | return $this->factory->make($this->view, [
42 | 'group' => $group,
43 | 'items' => $items
44 | ])->render();
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Presentation/Illuminate/IlluminateItemRenderer.php:
--------------------------------------------------------------------------------
1 | factory = $factory;
27 | }
28 |
29 | /**
30 | * @param Item $item
31 | *
32 | * @return \Illuminate\Contracts\View\View
33 | */
34 | public function render(Item $item)
35 | {
36 | if ($item->isAuthorized()) {
37 | $items = [];
38 | foreach ($item->getItems() as $child) {
39 | $items[] = (new IlluminateItemRenderer($this->factory))->render($child);
40 | }
41 |
42 | $badges = [];
43 | foreach ($item->getBadges() as $badge) {
44 | $badges[] = (new IlluminateBadgeRenderer($this->factory))->render($badge);
45 | }
46 |
47 | $appends = [];
48 | foreach ($item->getAppends() as $append) {
49 | $appends[] = (new IlluminateAppendRenderer($this->factory))->render($append);
50 | }
51 |
52 | return $this->factory->make($this->view, [
53 | 'item' => $item,
54 | 'items' => $items,
55 | 'badges' => $badges,
56 | 'appends' => $appends,
57 | 'active' => (new ActiveStateChecker())->isActive($item),
58 | ])->render();
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Presentation/Illuminate/IlluminateSidebarRenderer.php:
--------------------------------------------------------------------------------
1 | factory = $factory;
27 | }
28 |
29 | /**
30 | * @param Sidebar $sidebar
31 | *
32 | * @return \Illuminate\Contracts\View\View
33 | */
34 | public function render(Sidebar $sidebar)
35 | {
36 | $menu = $sidebar->getMenu();
37 |
38 | if ($menu->isAuthorized()) {
39 | $groups = [];
40 | foreach ($menu->getGroups() as $group) {
41 | $groups[] = (new IlluminateGroupRenderer($this->factory))->render($group);
42 | }
43 |
44 | return $this->factory->make($this->view, [
45 | 'groups' => $groups
46 | ]);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Presentation/SidebarRenderer.php:
--------------------------------------------------------------------------------
1 | container = $container;
34 | $this->resolver = $resolver;
35 | }
36 |
37 | /**
38 | * Register the sidebar
39 | *
40 | * @param $name
41 | *
42 | * @throws LogicException
43 | * @return $this
44 | */
45 | public function register($name)
46 | {
47 | if (class_exists($name)) {
48 | $this->sidebars[] = $name;
49 | } else {
50 | throw new LogicException('Sidebar [' . $name . '] does not exist');
51 | }
52 |
53 | return $this;
54 | }
55 |
56 | /**
57 | * Bind sidebar instances to the ioC
58 | */
59 | public function resolve()
60 | {
61 | foreach ($this->sidebars as $name) {
62 | $sidebar = $this->resolver->resolve($name);
63 |
64 | $this->container->singleton($name, function () use ($sidebar) {
65 | return $sidebar;
66 | });
67 | }
68 | }
69 |
70 | /**
71 | * @param SidebarFlusher $flusher
72 | */
73 | public function flush(SidebarFlusher $flusher)
74 | {
75 | foreach ($this->sidebars as $name) {
76 | $flusher->flush($name);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/SidebarServiceProvider.php:
--------------------------------------------------------------------------------
1 | registerViews();
30 | }
31 |
32 | /**
33 | * Register the service provider.
34 | * @return void
35 | */
36 | public function register()
37 | {
38 | // Register config
39 | $this->registerConfig();
40 |
41 | // Bind SidebarResolver
42 | $this->app->bind('Maatwebsite\Sidebar\Infrastructure\SidebarResolver', function (Application $app) {
43 |
44 | $resolver = SidebarResolverFactory::getClassName(
45 | $app['config']->get('sidebar.cache.method')
46 | );
47 |
48 | return $app->make($resolver);
49 | });
50 |
51 | // Bind SidebarFlusher
52 | $this->app->bind('Maatwebsite\Sidebar\Infrastructure\SidebarFlusher', function (Application $app) {
53 |
54 | $resolver = SidebarFlusherFactory::getClassName(
55 | $app['config']->get('sidebar.cache.method')
56 | );
57 |
58 | return $app->make($resolver);
59 | });
60 |
61 | // Bind manager
62 | $this->app->singleton('Maatwebsite\Sidebar\SidebarManager');
63 |
64 | // Bind Menu
65 | $this->app->bind(
66 | 'Maatwebsite\Sidebar\Menu',
67 | 'Maatwebsite\Sidebar\Domain\DefaultMenu'
68 | );
69 |
70 | // Bind Group
71 | $this->app->bind(
72 | 'Maatwebsite\Sidebar\Group',
73 | 'Maatwebsite\Sidebar\Domain\DefaultGroup'
74 | );
75 |
76 | // Bind Item
77 | $this->app->bind(
78 | 'Maatwebsite\Sidebar\Item',
79 | 'Maatwebsite\Sidebar\Domain\DefaultItem'
80 | );
81 |
82 | // Bind Badge
83 | $this->app->bind(
84 | 'Maatwebsite\Sidebar\Badge',
85 | 'Maatwebsite\Sidebar\Domain\DefaultBadge'
86 | );
87 |
88 | // Bind Append
89 | $this->app->bind(
90 | 'Maatwebsite\Sidebar\Append',
91 | 'Maatwebsite\Sidebar\Domain\DefaultAppend'
92 | );
93 |
94 | // Bind Renderer
95 | $this->app->bind(
96 | 'Maatwebsite\Sidebar\Presentation\SidebarRenderer',
97 | 'Maatwebsite\Sidebar\Presentation\Illuminate\IlluminateSidebarRenderer'
98 | );
99 | }
100 |
101 | /**
102 | * Register views.
103 | * @return void
104 | */
105 | protected function registerViews()
106 | {
107 | $view = match (config('sidebar.view')){
108 | 'AdminLTE3' => 'adminlte-3',
109 | default => 'adminlte-2',
110 | };
111 |
112 | $location = __DIR__ . "/../resources/views/{$view}";
113 |
114 | $this->loadViewsFrom($location, $this->shortName);
115 |
116 | $this->publishes([
117 | $location => base_path('resources/views/vendor/' . $this->shortName),
118 | ], 'sidebar-views');
119 | }
120 |
121 | /**
122 | * Register config
123 | * @return void
124 | */
125 | protected function registerConfig()
126 | {
127 | $location = __DIR__ . '/../config/' . $this->shortName . '.php';
128 |
129 | $this->mergeConfigFrom(
130 | $location, $this->shortName
131 | );
132 |
133 | $this->publishes([
134 | $location => config_path($this->shortName . '.php'),
135 | ], 'sidebar-config');
136 | }
137 |
138 | /**
139 | * Get the services provided by the provider.
140 | * @return array
141 | */
142 | public function provides()
143 | {
144 | return [
145 | 'Maatwebsite\Sidebar\Menu',
146 | 'Maatwebsite\Sidebar\Item',
147 | 'Maatwebsite\Sidebar\Group',
148 | 'Maatwebsite\Sidebar\Badge',
149 | 'Maatwebsite\Sidebar\Append',
150 | 'Maatwebsite\Sidebar\SidebarManager',
151 | 'Maatwebsite\Sidebar\Presentation\SidebarRenderer',
152 | 'Maatwebsite\Sidebar\Infrastructure\SidebarResolver'
153 | ];
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/Traits/AuthorizableTrait.php:
--------------------------------------------------------------------------------
1 | authorized;
19 | }
20 |
21 | /**
22 | * Authorize the group/item
23 | *
24 | * @param bool $state
25 | *
26 | * @return $this
27 | */
28 | public function authorize($state = true)
29 | {
30 | $this->authorized = $state;
31 |
32 | return $this;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Traits/CacheableTrait.php:
--------------------------------------------------------------------------------
1 | getCacheables() as $cacheable) {
16 | $cacheables[$cacheable] = $this->{$cacheable};
17 | }
18 |
19 | return serialize($cacheables);
20 | }
21 |
22 | /**
23 | * Constructs the object
24 | * @link http://php.net/manual/en/serializable.unserialize.php
25 | *
26 | * @param string $serialized The string representation of the object.
27 | *
28 | * @return void
29 | */
30 | public function unserialize($serialized)
31 | {
32 | $data = unserialize($serialized);
33 |
34 | foreach ($data as $key => $value) {
35 | $this->{$key} = $value;
36 | }
37 | }
38 |
39 | /**
40 | * @return array
41 | */
42 | public function getCacheables(): array
43 | {
44 | return $this->cacheables ?? ['menu'];
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/Traits/CallableTrait.php:
--------------------------------------------------------------------------------
1 | resolveMethodDependencies(
26 | [$caller], new ReflectionFunction($callback)
27 | );
28 | call_user_func_array($callback, $parameters);
29 | }
30 |
31 | return $caller;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Traits/ItemableTrait.php:
--------------------------------------------------------------------------------
1 | items->has($name)) {
27 | $item = $this->items->get($name);
28 | } else {
29 | $item = $this->container->make('Maatwebsite\Sidebar\Item');
30 | $item->name($name);
31 | }
32 |
33 | $this->call($callback, $item);
34 |
35 | $this->addItem($item);
36 |
37 | return $item;
38 | }
39 |
40 | /**
41 | * Add Item instance to Group
42 | *
43 | * @param Item $item
44 | *
45 | * @return Item
46 | */
47 | public function addItem(Item $item)
48 | {
49 | $this->items->put($item->getName(), $item);
50 |
51 | return $this;
52 | }
53 |
54 | /**
55 | * @return Collection|Item[]
56 | */
57 | public function getItems()
58 | {
59 | return $this->items->sortBy(function (Item $item) {
60 | return $item->getWeight();
61 | });
62 | }
63 |
64 | /**
65 | * Check if we have items
66 | * @return bool
67 | */
68 | public function hasItems()
69 | {
70 | return count($this->items) > 0 ? true : false;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Traits/RouteableTrait.php:
--------------------------------------------------------------------------------
1 | url;
18 | }
19 |
20 | /**
21 | * @param string $url
22 | *
23 | * @return $this
24 | */
25 | public function url($url)
26 | {
27 | $this->url = $url;
28 |
29 | return $this;
30 | }
31 |
32 | /**
33 | * @param $route
34 | * @param array $params
35 | *
36 | * @return $this
37 | */
38 | public function route($route, $params = [])
39 | {
40 | $this->url(
41 | $this->container->make('url')->route($route, $params)
42 | );
43 |
44 | return $this;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/tests/Domain/DefaultAppendTest.php:
--------------------------------------------------------------------------------
1 | container = m::mock('Illuminate\Contracts\Container\Container');
25 | $this->append = new DefaultAppend($this->container);
26 | }
27 |
28 | public function test_can_instantiate_new_append()
29 | {
30 | $append = new DefaultAppend($this->container);
31 |
32 | $this->assertInstanceOf('Maatwebsite\Sidebar\Append', $append);
33 | }
34 |
35 | public function test_can_have_custom_appends()
36 | {
37 | $append = new StubAppend($this->container);
38 |
39 | $this->assertInstanceOf('Maatwebsite\Sidebar\Append', $append);
40 | }
41 |
42 | public function test_can_set_name()
43 | {
44 | $this->append->name('name');
45 | $this->assertEquals('name', $this->append->getName());
46 | }
47 |
48 | public function test_can_set_url()
49 | {
50 | $this->append->url('url');
51 | $this->assertEquals('url', $this->append->getUrl());
52 | }
53 |
54 | public function test_can_set_icon()
55 | {
56 | $this->append->icon('icon');
57 | $this->assertEquals('icon', $this->append->getIcon());
58 | }
59 |
60 | public function test_append_can_be_cached()
61 | {
62 | $this->append->name('name');
63 | $this->append->url('url');
64 | $this->append->icon('icon');
65 |
66 | $serialized = serialize($this->append);
67 | $unserialized = unserialize($serialized);
68 |
69 | $this->assertInstanceOf('Maatwebsite\Sidebar\Append', $unserialized);
70 | $this->assertEquals('name', $unserialized->getName());
71 | $this->assertEquals('url', $unserialized->getUrl());
72 | $this->assertEquals('icon', $unserialized->getIcon());
73 | }
74 | }
75 |
76 | class StubAppend extends DefaultAppend implements Append
77 | {
78 | }
79 |
--------------------------------------------------------------------------------
/tests/Domain/DefaultBadgeTest.php:
--------------------------------------------------------------------------------
1 | container = m::mock('Illuminate\Contracts\Container\Container');
25 | $this->badge = new DefaultBadge($this->container);
26 | }
27 |
28 | public function test_can_instantiate_new_badge()
29 | {
30 | $badge = new DefaultBadge($this->container);
31 |
32 | $this->assertInstanceOf('Maatwebsite\Sidebar\Badge', $badge);
33 | }
34 |
35 | public function test_can_have_custom_badges()
36 | {
37 | $badge = new StubBadge($this->container);
38 |
39 | $this->assertInstanceOf('Maatwebsite\Sidebar\Badge', $badge);
40 | }
41 |
42 | public function test_can_set_value()
43 | {
44 | $this->badge->setValue('value');
45 | $this->assertEquals('value', $this->badge->getValue());
46 | }
47 |
48 | public function test_can_set_class()
49 | {
50 | $this->badge->setClass('class');
51 | $this->assertEquals('class', $this->badge->getClass());
52 | }
53 |
54 | public function test_badge_can_be_cached()
55 | {
56 | $this->badge->setValue('value');
57 | $this->badge->setClass('class');
58 |
59 | $serialized = serialize($this->badge);
60 | $unserialized = unserialize($serialized);
61 |
62 | $this->assertInstanceOf('Maatwebsite\Sidebar\Badge', $unserialized);
63 | $this->assertEquals('value', $unserialized->getValue());
64 | $this->assertEquals('class', $unserialized->getClass());
65 | }
66 | }
67 |
68 | class StubBadge extends DefaultBadge implements Badge
69 | {
70 | }
71 |
--------------------------------------------------------------------------------
/tests/Domain/DefaultGroupTest.php:
--------------------------------------------------------------------------------
1 | container = m::mock('Illuminate\Contracts\Container\Container');
26 | $this->group = new DefaultGroup($this->container);
27 | }
28 |
29 | public function test_can_instantiate_new_group()
30 | {
31 | $group = new DefaultGroup($this->container);
32 |
33 | $this->assertInstanceOf('Maatwebsite\Sidebar\Group', $group);
34 | }
35 |
36 | public function test_can_have_custom_groups()
37 | {
38 | $group = new StubGroup($this->container);
39 |
40 | $this->assertInstanceOf('Maatwebsite\Sidebar\Group', $group);
41 | }
42 |
43 | public function test_group_can_be_cached()
44 | {
45 | $item = new DefaultItem($this->container);
46 | $this->group->addItem($item);
47 |
48 | $serialized = serialize($this->group);
49 | $unserialized = unserialize($serialized);
50 |
51 | $this->assertInstanceOf('Maatwebsite\Sidebar\Group', $unserialized);
52 | $this->assertInstanceOf('Illuminate\Support\Collection', $unserialized->getItems());
53 |
54 | $this->assertCount(1, $unserialized->getItems());
55 | }
56 | }
57 |
58 | class StubGroup extends DefaultGroup implements Group
59 | {
60 | }
61 |
--------------------------------------------------------------------------------
/tests/Domain/DefaultItemTest.php:
--------------------------------------------------------------------------------
1 | container = m::mock('Illuminate\Contracts\Container\Container');
27 | $this->item = new DefaultItem($this->container);
28 | }
29 |
30 | public function test_can_instantiate_new_item()
31 | {
32 | $item = new DefaultItem($this->container);
33 |
34 | $this->assertInstanceOf('Maatwebsite\Sidebar\Item', $item);
35 | }
36 |
37 | public function test_can_have_custom_items()
38 | {
39 | $item = new StubItem($this->container);
40 |
41 | $this->assertInstanceOf('Maatwebsite\Sidebar\Item', $item);
42 | }
43 |
44 | public function test_can_set_name()
45 | {
46 | $this->item->name('name');
47 | $this->assertEquals('name', $this->item->getName());
48 | }
49 |
50 | public function test_can_set_url()
51 | {
52 | $this->item->url('url');
53 | $this->assertEquals('url', $this->item->getUrl());
54 | }
55 |
56 | public function test_can_set_icon()
57 | {
58 | $this->item->icon('icon');
59 | $this->assertEquals('icon', $this->item->getIcon());
60 | }
61 |
62 | public function test_can_set_weight()
63 | {
64 | $this->item->weight(1);
65 | $this->assertEquals(1, $this->item->getWeight());
66 | }
67 |
68 | public function test_item_can_be_cached()
69 | {
70 | $item = new DefaultItem($this->container);
71 | $this->item->addItem($item);
72 |
73 | $this->item->name('name');
74 | $this->item->icon('icon');
75 | $this->item->weight(1);
76 | $this->item->url('url');
77 |
78 | $serialized = serialize($this->item);
79 | $unserialized = unserialize($serialized);
80 |
81 | $this->assertInstanceOf('Maatwebsite\Sidebar\Item', $unserialized);
82 | $this->assertInstanceOf('Illuminate\Support\Collection', $unserialized->getItems());
83 | $this->assertCount(1, $unserialized->getItems());
84 | $this->assertEquals('name', $unserialized->getName());
85 | $this->assertEquals('icon', $unserialized->getIcon());
86 | $this->assertEquals(1, $unserialized->getWeight());
87 | $this->assertEquals('url', $unserialized->getUrl());
88 | }
89 |
90 | public function test_can_add_a_badge_instance()
91 | {
92 | $badge = new DefaultBadge($this->container);
93 | $badge->setValue(1);
94 | $this->item->addBadge($badge);
95 |
96 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->item->getBadges());
97 | $this->assertCount(1, $this->item->getBadges());
98 | $this->assertEquals('1', $this->item->getBadges()->first()->getValue());
99 | }
100 |
101 | public function test_can_add_a_badge()
102 | {
103 | $mock = $this->mockContainerMakeForBadge();
104 | $mock->shouldReceive('setValue');
105 | $mock->shouldReceive('setClass');
106 | $mock->shouldReceive('getValue')->andReturn(1);
107 | $mock->shouldReceive('getClass')->andReturn('className');
108 |
109 | $this->item->badge(1, 'className');
110 |
111 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->item->getBadges());
112 | $this->assertCount(1, $this->item->getBadges());
113 | $this->assertEquals(1, $this->item->getBadges()->first()->getValue());
114 | $this->assertEquals('className', $this->item->getBadges()->first()->getClass());
115 | }
116 |
117 | public function test_can_add_a_append_instance()
118 | {
119 | $append = new DefaultAppend($this->container);
120 | $append->url('url');
121 | $this->item->addAppend($append);
122 |
123 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->item->getAppends());
124 | $this->assertCount(1, $this->item->getAppends());
125 | $this->assertEquals('url', $this->item->getAppends()->first()->getUrl());
126 | }
127 |
128 | public function test_can_add_a_append()
129 | {
130 | $mock = $this->mockContainerMakeForAppend();
131 | $mock->shouldReceive('route');
132 | $mock->shouldReceive('icon');
133 | $mock->shouldReceive('name');
134 | $mock->shouldReceive('getUrl')->andReturn('url');
135 | $mock->shouldReceive('getIcon')->andReturn('icon');
136 | $mock->shouldReceive('getName')->andReturn('name');
137 |
138 | $this->item->append('route', 'icon', 'name');
139 |
140 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->item->getAppends());
141 | $this->assertCount(1, $this->item->getAppends());
142 | $this->assertEquals('url', $this->item->getAppends()->first()->getUrl());
143 | $this->assertEquals('icon', $this->item->getAppends()->first()->getIcon());
144 | $this->assertEquals('name', $this->item->getAppends()->first()->getName());
145 | }
146 |
147 | protected function mockContainerMakeForBadge()
148 | {
149 | $mock = m::mock('Maatwebsite\Sidebar\Badge');
150 |
151 | $this->container->shouldReceive('make')->with('Maatwebsite\Sidebar\Badge')->andReturn(
152 | $mock
153 | );
154 |
155 | return $mock;
156 | }
157 |
158 | protected function mockContainerMakeForAppend()
159 | {
160 | $mock = m::mock('Maatwebsite\Sidebar\Append');
161 |
162 | $this->container->shouldReceive('make')->with('Maatwebsite\Sidebar\Append')->andReturn(
163 | $mock
164 | );
165 |
166 | return $mock;
167 | }
168 | }
169 |
170 | class StubItem extends DefaultItem implements Item
171 | {
172 | }
173 |
--------------------------------------------------------------------------------
/tests/Domain/DefaultMenuTest.php:
--------------------------------------------------------------------------------
1 | container = m::mock('Illuminate\Contracts\Container\Container');
26 | $this->menu = new DefaultMenu($this->container);
27 | }
28 |
29 | public function test_can_instantiate_new_menu()
30 | {
31 | $menu = new DefaultMenu($this->container);
32 |
33 | $this->assertInstanceOf('Maatwebsite\Sidebar\Menu', $menu);
34 | }
35 |
36 | public function test_can_have_custom_menus()
37 | {
38 | $menu = new StubMenu($this->container);
39 |
40 | $this->assertInstanceOf('Maatwebsite\Sidebar\Menu', $menu);
41 | }
42 |
43 | public function test_menu_can_be_cached()
44 | {
45 | $this->markTestSkipped("'Exception: Serialization of 'ReflectionClass' is not allowed'");
46 | $this->mockContainerMake();
47 | $this->menu->group('test');
48 | $this->menu->group('test2');
49 |
50 | $serialized = serialize($this->menu);
51 | $unserialized = unserialize($serialized);
52 |
53 | $this->assertInstanceOf('Maatwebsite\Sidebar\Menu', $unserialized);
54 | $this->assertInstanceOf('Illuminate\Support\Collection', $unserialized->getGroups());
55 | $this->assertCount(2, $unserialized->getGroups());
56 |
57 | }
58 |
59 | public function test_can_add_group_instance_to_menu()
60 | {
61 | $group = new DefaultGroup($this->container);
62 | $group->name('test');
63 |
64 | $this->menu->addGroup($group);
65 |
66 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->menu->getGroups());
67 | $this->assertCount(1, $this->menu->getGroups());
68 | $this->assertEquals('test', $this->menu->getGroups()->first()->getName());
69 | }
70 |
71 | public function test_can_add_group_to_menu()
72 | {
73 | $this->mockContainerMake();
74 |
75 | $this->menu->group('test');
76 |
77 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->menu->getGroups());
78 | $this->assertCount(1, $this->menu->getGroups());
79 | }
80 |
81 | public function test_can_add_existing_group_to_menu_wont_duplicate()
82 | {
83 | $this->mockContainerMake('test');
84 |
85 | $this->menu->group('test');
86 | $this->menu->group('test');
87 | $this->menu->group('test');
88 |
89 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->menu->getGroups());
90 | $this->assertCount(1, $this->menu->getGroups());
91 | }
92 |
93 | public function test_get_groups_returns_sorted_groups()
94 | {
95 | $group = new DefaultGroup($this->container);
96 | $group->name('secondItem');
97 | $group->weight(2);
98 |
99 | $this->menu->addGroup($group);
100 |
101 | $group = new DefaultGroup($this->container);
102 | $group->name('firstItem');
103 | $group->weight(1);
104 |
105 | $this->menu->addGroup($group);
106 |
107 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->menu->getGroups());
108 | $this->assertCount(2, $this->menu->getGroups());
109 |
110 | $this->assertEquals('firstItem', $this->menu->getGroups()->first()->getName());
111 | }
112 |
113 | public function test_can_combined_menu_instances()
114 | {
115 | // Add group to original menu
116 | $group = new DefaultGroup($this->container);
117 | $group->name('existing');
118 | $group->weight(2);
119 | $this->menu->addGroup($group);
120 |
121 | // Init new menu
122 | $menu = new DefaultMenu($this->container);
123 |
124 | // Add a new one
125 | $group = new DefaultGroup($this->container);
126 | $group->name('new menu group');
127 | $group->weight(1);
128 | $menu->addGroup($group);
129 |
130 | // Append to existing
131 | $group = new DefaultGroup($this->container);
132 | $group->name('existing');
133 | $group->weight(2);
134 | $menu->addGroup($group);
135 |
136 | $this->menu->add($menu);
137 |
138 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->menu->getGroups());
139 | $this->assertCount(2, $this->menu->getGroups());
140 |
141 | $this->assertEquals('new menu group', $this->menu->getGroups()->first()->getName());
142 | }
143 |
144 | protected function mockContainerMake($name = null, $weight = null)
145 | {
146 | $mock = m::mock('Maatwebsite\Sidebar\Group');
147 | $mock->shouldReceive('name');
148 | $mock->shouldReceive('getName')->andReturn($name);
149 | $mock->shouldReceive('getWeight')->andReturn($weight);
150 |
151 | $this->container->shouldReceive('make')->with('Maatwebsite\Sidebar\Group')->andReturn(
152 | $mock
153 | );
154 |
155 | return $mock;
156 | }
157 | }
158 |
159 | class StubMenu extends DefaultMenu implements Menu
160 | {
161 | }
162 |
--------------------------------------------------------------------------------
/tests/SidebarExtenderTest.php:
--------------------------------------------------------------------------------
1 | container = m::mock('Illuminate\Contracts\Container\Container');
27 | $this->menu = new DefaultMenu($this->container);
28 | }
29 |
30 | public function test_a_sidebar_can_be_extended_with_an_extender()
31 | {
32 | $group = new DefaultGroup($this->container);
33 | $group->name('original');
34 | $this->menu->addGroup($group);
35 |
36 | $extender = new StubSidebarExtender();
37 | $extender->extendWith($this->menu);
38 |
39 | $this->menu->add(
40 | $extender->extendWith($this->menu)
41 | );
42 |
43 | $this->assertInstanceOf('Maatwebsite\Sidebar\Menu', $this->menu);
44 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->menu->getGroups());
45 | $this->assertCount(2, $this->menu->getGroups());
46 | }
47 | }
48 |
49 | class StubSidebarExtender implements SidebarExtender
50 | {
51 | /**
52 | * @param Menu $menu
53 | *
54 | * @return Menu
55 | */
56 | public function extendWith(Menu $menu)
57 | {
58 | $container = m::mock('Illuminate\Contracts\Container\Container');
59 |
60 | $group = new DefaultGroup($container);
61 | $group->name('new from extender');
62 | $menu->addGroup($group);
63 |
64 | $group = new DefaultGroup($container);
65 | $group->name('original');
66 | $menu->addGroup($group);
67 |
68 | return $menu;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/tests/Traits/AuthorizableTraitTest.php:
--------------------------------------------------------------------------------
1 | routeable = new StubAuthorizableClass();
18 | }
19 |
20 | public function test_can_authorize()
21 | {
22 | $this->routeable->authorize(true);
23 | $this->assertTrue($this->routeable->isAuthorized());
24 |
25 | $this->routeable->authorize(false);
26 | $this->assertFalse($this->routeable->isAuthorized());
27 | }
28 | }
29 |
30 | class StubAuthorizableClass
31 | {
32 | use AuthorizableTrait;
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Traits/ItemableTraitTest.php:
--------------------------------------------------------------------------------
1 | container = m::mock('Illuminate\Contracts\Container\Container');
29 | $this->itemable = new StubItemableClass($this->container);
30 | }
31 |
32 | public function test_can_add_an_item_instance()
33 | {
34 | $item = new DefaultItem($this->container);
35 | $item->name('itemName');
36 | $this->itemable->addItem($item);
37 |
38 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->itemable->getItems());
39 | $this->assertCount(1, $this->itemable->getItems());
40 | $this->assertEquals('itemName', $this->itemable->getItems()->first()->getName());
41 | }
42 |
43 | public function test_can_add_an_item()
44 | {
45 | $this->mockContainerMake('itemName');
46 | $this->itemable->item('itemName');
47 |
48 | $this->assertInstanceOf('Illuminate\Support\Collection', $this->itemable->getItems());
49 | $this->assertCount(1, $this->itemable->getItems());
50 | $this->assertEquals('itemName', $this->itemable->getItems()->first()->getName());
51 | }
52 |
53 | public function test_can_check_if_has_items()
54 | {
55 | $this->assertFalse($this->itemable->hasItems());
56 |
57 | $item = new DefaultItem($this->container);
58 | $this->itemable->addItem($item);
59 |
60 | $this->assertTrue($this->itemable->hasItems());
61 | }
62 |
63 | public function test_get_items_sorts_items_by_weight()
64 | {
65 | $item = new DefaultItem($this->container);
66 | $item->name('second item');
67 | $item->weight(2);
68 | $this->itemable->addItem($item);
69 |
70 | $item = new DefaultItem($this->container);
71 | $this->itemable->addItem($item);
72 | $item->name('first item');
73 | $item->weight(1);
74 |
75 | $this->assertCount(2, $this->itemable->getItems());
76 | $this->assertEquals('first item', $this->itemable->getItems()->first()->getName());
77 | }
78 |
79 | protected function mockContainerMake($name = null, $weight = null)
80 | {
81 | $mock = m::mock('Maatwebsite\Sidebar\Item');
82 | $mock->shouldReceive('name');
83 | $mock->shouldReceive('getName')->andReturn($name);
84 | $mock->shouldReceive('getWeight')->andReturn($weight);
85 |
86 | $this->container->shouldReceive('make')->with('Maatwebsite\Sidebar\Item')->andReturn(
87 | $mock
88 | );
89 |
90 | return $mock;
91 | }
92 | }
93 |
94 | class StubItemableClass implements Itemable
95 | {
96 | use ItemableTrait, CallableTrait;
97 |
98 | /**
99 | * @var Container
100 | */
101 | private $container;
102 |
103 | /**
104 | * @param Container $container
105 | */
106 | public function __construct(Container $container)
107 | {
108 | $this->container = $container;
109 | $this->items = new Collection();
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/tests/Traits/RouteableTraitTest.php:
--------------------------------------------------------------------------------
1 | container = m::mock('Illuminate\Contracts\Container\Container');
26 | $this->routeable = new StubRouteableClass($this->container);
27 | }
28 |
29 | public function test_can_set_url()
30 | {
31 | $this->routeable->url('url');
32 |
33 | $this->assertEquals('url', $this->routeable->getUrl());
34 | }
35 |
36 | public function test_can_set_route()
37 | {
38 | $urlMock = m::mock('Illuminate\Contracts\Routing\UrlGenerator');
39 | $urlMock->shouldReceive('route')->andReturn('url');
40 |
41 | $this->container->shouldReceive('make')->andReturn($urlMock);
42 |
43 | $this->routeable->route('route');
44 |
45 | $this->assertEquals('url', $this->routeable->getUrl());
46 | }
47 | }
48 |
49 | class StubRouteableClass
50 | {
51 | use RouteableTrait;
52 |
53 | /**
54 | * @var Container
55 | */
56 | private $container;
57 |
58 | /**
59 | * @param Container $container
60 | */
61 | public function __construct(Container $container)
62 | {
63 | $this->container = $container;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------