]> BookStack Code Mirror - bookstack/blob - app/helpers.php
Updated existing image tests to reflect changes
[bookstack] / app / helpers.php
1 <?php
2
3 use BookStack\Auth\Permissions\PermissionService;
4 use BookStack\Entities\Entity;
5 use BookStack\Ownable;
6
7 /**
8  * Get the path to a versioned file.
9  *
10  * @param  string $file
11  * @return string
12  * @throws Exception
13  */
14 function versioned_asset($file = '')
15 {
16     static $version = null;
17
18     if (is_null($version)) {
19         $versionFile = base_path('version');
20         $version = trim(file_get_contents($versionFile));
21     }
22
23     $additional = '';
24     if (config('app.env') === 'development') {
25         $additional = sha1_file(public_path($file));
26     }
27
28     $path = $file . '?version=' . urlencode($version) . $additional;
29     return baseUrl($path);
30 }
31
32 /**
33  * Helper method to get the current User.
34  * Defaults to public 'Guest' user if not logged in.
35  * @return \BookStack\Auth\User
36  */
37 function user()
38 {
39     return auth()->user() ?: \BookStack\Auth\User::getDefault();
40 }
41
42 /**
43  * Check if current user is a signed in user.
44  * @return bool
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  * @return bool
54  */
55 function hasAppAccess() : bool {
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  * @param string $permission
64  * @param Ownable $ownable
65  * @return mixed
66  */
67 function userCan(string $permission, Ownable $ownable = null)
68 {
69     if ($ownable === null) {
70         return user() && user()->can($permission);
71     }
72
73     // Check permission on ownable item
74     $permissionService = app(PermissionService::class);
75     return $permissionService->checkOwnableUserAccess($ownable, $permission);
76 }
77
78 /**
79  * Check if the current user has the given permission
80  * on any item in the system.
81  * @param string $permission
82  * @param string|null $entityClass
83  * @return bool
84  */
85 function userCanOnAny(string $permission, string $entityClass = null)
86 {
87     $permissionService = app(PermissionService::class);
88     return $permissionService->checkUserHasPermissionOnAnything($permission, $entityClass);
89 }
90
91 /**
92  * Helper to access system settings.
93  * @param $key
94  * @param bool $default
95  * @return bool|string|\BookStack\Settings\SettingService
96  */
97 function setting($key = null, $default = false)
98 {
99     $settingService = resolve(\BookStack\Settings\SettingService::class);
100     if (is_null($key)) {
101         return $settingService;
102     }
103     return $settingService->get($key, $default);
104 }
105
106 /**
107  * Helper to create url's relative to the applications root path.
108  * @param string $path
109  * @param bool $forceAppDomain
110  * @return string
111  */
112 function baseUrl($path, $forceAppDomain = false)
113 {
114     $isFullUrl = strpos($path, 'http') === 0;
115     if ($isFullUrl && !$forceAppDomain) {
116         return $path;
117     }
118
119     $path = trim($path, '/');
120     $base = rtrim(config('app.url'), '/');
121
122     // Remove non-specified domain if forced and we have a domain
123     if ($isFullUrl && $forceAppDomain) {
124         if (!empty($base) && strpos($path, $base) === 0) {
125             $path = trim(substr($path, strlen($base) - 1));
126         }
127         $explodedPath = explode('/', $path);
128         $path = implode('/', array_splice($explodedPath, 3));
129     }
130
131     // Return normal url path if not specified in config
132     if (config('app.url') === '') {
133         return url($path);
134     }
135
136     return $base . '/' . $path;
137 }
138
139 /**
140  * Get an instance of the redirector.
141  * Overrides the default laravel redirect helper.
142  * Ensures it redirects even when the app is in a subdirectory.
143  *
144  * @param  string|null  $to
145  * @param  int     $status
146  * @param  array   $headers
147  * @param  bool    $secure
148  * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
149  */
150 function redirect($to = null, $status = 302, $headers = [], $secure = null)
151 {
152     if (is_null($to)) {
153         return app('redirect');
154     }
155
156     $to = baseUrl($to);
157
158     return app('redirect')->to($to, $status, $headers, $secure);
159 }
160
161 /**
162  * Get a path to a theme resource.
163  * @param string $path
164  * @return string|boolean
165  */
166 function theme_path($path = '')
167 {
168     $theme = config('view.theme');
169     if (!$theme) {
170         return false;
171     }
172
173     return base_path('themes/' . $theme .($path ? DIRECTORY_SEPARATOR.$path : $path));
174 }
175
176 /**
177  * Get fetch an SVG icon as a string.
178  * Checks for icons defined within a custom theme before defaulting back
179  * to the 'resources/assets/icons' folder.
180  *
181  * Returns an empty string if icon file not found.
182  * @param $name
183  * @param array $attrs
184  * @return mixed
185  */
186 function icon($name, $attrs = [])
187 {
188     $attrs = array_merge([
189         'class' => 'svg-icon',
190         'data-icon' => $name
191     ], $attrs);
192     $attrString = ' ';
193     foreach ($attrs as $attrName => $attr) {
194         $attrString .=  $attrName . '="' . $attr . '" ';
195     }
196
197     $iconPath = resource_path('assets/icons/' . $name . '.svg');
198     $themeIconPath = theme_path('icons/' . $name . '.svg');
199     if ($themeIconPath && file_exists($themeIconPath)) {
200         $iconPath = $themeIconPath;
201     } else if (!file_exists($iconPath)) {
202         return '';
203     }
204
205     $fileContents = file_get_contents($iconPath);
206     return  str_replace('<svg', '<svg' . $attrString, $fileContents);
207 }
208
209 /**
210  * Generate a url with multiple parameters for sorting purposes.
211  * Works out the logic to set the correct sorting direction
212  * Discards empty parameters and allows overriding.
213  * @param $path
214  * @param array $data
215  * @param array $overrideData
216  * @return string
217  */
218 function sortUrl($path, $data, $overrideData = [])
219 {
220     $queryStringSections = [];
221     $queryData = array_merge($data, $overrideData);
222
223     // Change sorting direction is already sorted on current attribute
224     if (isset($overrideData['sort']) && $overrideData['sort'] === $data['sort']) {
225         $queryData['order'] = ($data['order'] === 'asc') ? 'desc' : 'asc';
226     } else {
227         $queryData['order'] = 'asc';
228     }
229
230     foreach ($queryData as $name => $value) {
231         $trimmedVal = trim($value);
232         if ($trimmedVal === '') {
233             continue;
234         }
235         $queryStringSections[] = urlencode($name) . '=' . urlencode($trimmedVal);
236     }
237
238     if (count($queryStringSections) === 0) {
239         return $path;
240     }
241
242     return baseUrl($path . '?' . implode('&', $queryStringSections));
243 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.