]> BookStack Code Mirror - bookstack/blob - app/helpers.php
Merge branch 'feature/public-login-redirect' of git://github.com/Xiphoseer/BookStack...
[bookstack] / app / helpers.php
1 <?php
2
3 use BookStack\Auth\Permissions\PermissionService;
4 use BookStack\Auth\User;
5 use BookStack\Ownable;
6 use BookStack\Settings\SettingService;
7
8 /**
9  * Get the path to a versioned file.
10  *
11  * @param  string $file
12  * @return string
13  * @throws Exception
14  */
15 function versioned_asset(string $file = ''): string
16 {
17     static $version = null;
18
19     if (is_null($version)) {
20         $versionFile = base_path('version');
21         $version = trim(file_get_contents($versionFile));
22     }
23
24     $additional = '';
25     if (config('app.env') === 'development') {
26         $additional = sha1_file(public_path($file));
27     }
28
29     $path = $file . '?version=' . urlencode($version) . $additional;
30     return url($path);
31 }
32
33 /**
34  * Helper method to get the current User.
35  * Defaults to public 'Guest' user if not logged in.
36  * @return User
37  */
38 function user(): User
39 {
40     return auth()->user() ?: User::getDefault();
41 }
42
43 /**
44  * Check if current user is a signed in user.
45  */
46 function signedInUser(): bool
47 {
48     return auth()->user() && !auth()->user()->isDefault();
49 }
50
51 /**
52  * Check if the current user has general access.
53  */
54 function hasAppAccess(): bool
55 {
56     return !auth()->guest() || setting('app-public');
57 }
58
59 /**
60  * Check if the current user has a permission.
61  * If an ownable element is passed in the jointPermissions are checked against
62  * that particular item.
63  */
64 function userCan(string $permission, Ownable $ownable = null): bool
65 {
66     if ($ownable === null) {
67         return user() && user()->can($permission);
68     }
69
70     // Check permission on ownable item
71     $permissionService = app(PermissionService::class);
72     return $permissionService->checkOwnableUserAccess($ownable, $permission);
73 }
74
75 /**
76  * Check if the current user has the given permission
77  * on any item in the system.
78  * @param string $permission
79  * @param string|null $entityClass
80  * @return bool
81  */
82 function userCanOnAny(string $permission, string $entityClass = null): bool
83 {
84     $permissionService = app(PermissionService::class);
85     return $permissionService->checkUserHasPermissionOnAnything($permission, $entityClass);
86 }
87
88 /**
89  * Helper to access system settings.
90  * @param string $key
91  * @param $default
92  * @return bool|string|SettingService
93  */
94 function setting(string $key = null, $default = false)
95 {
96     $settingService = resolve(SettingService::class);
97     if (is_null($key)) {
98         return $settingService;
99     }
100     return $settingService->get($key, $default);
101 }
102
103 /**
104  * Get a path to a theme resource.
105  * @param string $path
106  * @return string
107  */
108 function theme_path(string $path = ''): string
109 {
110     $theme = config('view.theme');
111     if (!$theme) {
112         return '';
113     }
114
115     return base_path('themes/' . $theme .($path ? DIRECTORY_SEPARATOR.$path : $path));
116 }
117
118 /**
119  * Get fetch an SVG icon as a string.
120  * Checks for icons defined within a custom theme before defaulting back
121  * to the 'resources/assets/icons' folder.
122  *
123  * Returns an empty string if icon file not found.
124  * @param $name
125  * @param array $attrs
126  * @return mixed
127  */
128 function icon(string $name, array $attrs = []): string
129 {
130     $attrs = array_merge([
131         'class'     => 'svg-icon',
132         'data-icon' => $name,
133         'role'      => 'presentation',
134     ], $attrs);
135     $attrString = ' ';
136     foreach ($attrs as $attrName => $attr) {
137         $attrString .=  $attrName . '="' . $attr . '" ';
138     }
139
140     $iconPath = resource_path('icons/' . $name . '.svg');
141     $themeIconPath = theme_path('icons/' . $name . '.svg');
142     if ($themeIconPath && file_exists($themeIconPath)) {
143         $iconPath = $themeIconPath;
144     } else if (!file_exists($iconPath)) {
145         return '';
146     }
147
148     $fileContents = file_get_contents($iconPath);
149     return  str_replace('<svg', '<svg' . $attrString, $fileContents);
150 }
151
152 /**
153  * Generate a url with multiple parameters for sorting purposes.
154  * Works out the logic to set the correct sorting direction
155  * Discards empty parameters and allows overriding.
156  * @param string $path
157  * @param array $data
158  * @param array $overrideData
159  * @return string
160  */
161 function sortUrl(string $path, array $data, array $overrideData = []): string
162 {
163     $queryStringSections = [];
164     $queryData = array_merge($data, $overrideData);
165
166     // Change sorting direction is already sorted on current attribute
167     if (isset($overrideData['sort']) && $overrideData['sort'] === $data['sort']) {
168         $queryData['order'] = ($data['order'] === 'asc') ? 'desc' : 'asc';
169     } else {
170         $queryData['order'] = 'asc';
171     }
172
173     foreach ($queryData as $name => $value) {
174         $trimmedVal = trim($value);
175         if ($trimmedVal === '') {
176             continue;
177         }
178         $queryStringSections[] = urlencode($name) . '=' . urlencode($trimmedVal);
179     }
180
181     if (count($queryStringSections) === 0) {
182         return $path;
183     }
184
185     return url($path . '?' . implode('&', $queryStringSections));
186 }