]> BookStack Code Mirror - bookstack/blob - app/helpers.php
Added locale and text direction to html templates
[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 {
57     return !auth()->guest() || setting('app-public');
58 }
59
60 /**
61  * Check if the current user has a permission.
62  * If an ownable element is passed in the jointPermissions are checked against
63  * that particular item.
64  * @param string $permission
65  * @param Ownable $ownable
66  * @return mixed
67  */
68 function userCan(string $permission, Ownable $ownable = null)
69 {
70     if ($ownable === null) {
71         return user() && user()->can($permission);
72     }
73
74     // Check permission on ownable item
75     $permissionService = app(PermissionService::class);
76     return $permissionService->checkOwnableUserAccess($ownable, $permission);
77 }
78
79 /**
80  * Check if the current user has the given permission
81  * on any item in the system.
82  * @param string $permission
83  * @param string|null $entityClass
84  * @return bool
85  */
86 function userCanOnAny(string $permission, string $entityClass = null)
87 {
88     $permissionService = app(PermissionService::class);
89     return $permissionService->checkUserHasPermissionOnAnything($permission, $entityClass);
90 }
91
92 /**
93  * Helper to access system settings.
94  * @param $key
95  * @param bool $default
96  * @return bool|string|\BookStack\Settings\SettingService
97  */
98 function setting($key = null, $default = false)
99 {
100     $settingService = resolve(\BookStack\Settings\SettingService::class);
101     if (is_null($key)) {
102         return $settingService;
103     }
104     return $settingService->get($key, $default);
105 }
106
107 /**
108  * Helper to create url's relative to the applications root path.
109  * @param string $path
110  * @param bool $forceAppDomain
111  * @return string
112  */
113 function baseUrl($path, $forceAppDomain = false)
114 {
115     $isFullUrl = strpos($path, 'http') === 0;
116     if ($isFullUrl && !$forceAppDomain) {
117         return $path;
118     }
119
120     $path = trim($path, '/');
121     $base = rtrim(config('app.url'), '/');
122
123     // Remove non-specified domain if forced and we have a domain
124     if ($isFullUrl && $forceAppDomain) {
125         if (!empty($base) && strpos($path, $base) === 0) {
126             $path = mb_substr($path, mb_strlen($base));
127         } else {
128             $explodedPath = explode('/', $path);
129             $path = implode('/', array_splice($explodedPath, 3));
130         }
131     }
132
133     // Return normal url path if not specified in config
134     if (config('app.url') === '') {
135         return url($path);
136     }
137
138     return $base . '/' . ltrim($path, '/');
139 }
140
141 /**
142  * Get an instance of the redirector.
143  * Overrides the default laravel redirect helper.
144  * Ensures it redirects even when the app is in a subdirectory.
145  *
146  * @param  string|null  $to
147  * @param  int     $status
148  * @param  array   $headers
149  * @param  bool    $secure
150  * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
151  */
152 function redirect($to = null, $status = 302, $headers = [], $secure = null)
153 {
154     if (is_null($to)) {
155         return app('redirect');
156     }
157
158     $to = baseUrl($to);
159
160     return app('redirect')->to($to, $status, $headers, $secure);
161 }
162
163 /**
164  * Get a path to a theme resource.
165  * @param string $path
166  * @return string|boolean
167  */
168 function theme_path($path = '')
169 {
170     $theme = config('view.theme');
171     if (!$theme) {
172         return false;
173     }
174
175     return base_path('themes/' . $theme .($path ? DIRECTORY_SEPARATOR.$path : $path));
176 }
177
178 /**
179  * Get fetch an SVG icon as a string.
180  * Checks for icons defined within a custom theme before defaulting back
181  * to the 'resources/assets/icons' folder.
182  *
183  * Returns an empty string if icon file not found.
184  * @param $name
185  * @param array $attrs
186  * @return mixed
187  */
188 function icon($name, $attrs = [])
189 {
190     $attrs = array_merge([
191         'class' => 'svg-icon',
192         'data-icon' => $name
193     ], $attrs);
194     $attrString = ' ';
195     foreach ($attrs as $attrName => $attr) {
196         $attrString .=  $attrName . '="' . $attr . '" ';
197     }
198
199     $iconPath = resource_path('assets/icons/' . $name . '.svg');
200     $themeIconPath = theme_path('icons/' . $name . '.svg');
201     if ($themeIconPath && file_exists($themeIconPath)) {
202         $iconPath = $themeIconPath;
203     } else if (!file_exists($iconPath)) {
204         return '';
205     }
206
207     $fileContents = file_get_contents($iconPath);
208     return  str_replace('<svg', '<svg' . $attrString, $fileContents);
209 }
210
211 /**
212  * Generate a url with multiple parameters for sorting purposes.
213  * Works out the logic to set the correct sorting direction
214  * Discards empty parameters and allows overriding.
215  * @param $path
216  * @param array $data
217  * @param array $overrideData
218  * @return string
219  */
220 function sortUrl($path, $data, $overrideData = [])
221 {
222     $queryStringSections = [];
223     $queryData = array_merge($data, $overrideData);
224
225     // Change sorting direction is already sorted on current attribute
226     if (isset($overrideData['sort']) && $overrideData['sort'] === $data['sort']) {
227         $queryData['order'] = ($data['order'] === 'asc') ? 'desc' : 'asc';
228     } else {
229         $queryData['order'] = 'asc';
230     }
231
232     foreach ($queryData as $name => $value) {
233         $trimmedVal = trim($value);
234         if ($trimmedVal === '') {
235             continue;
236         }
237         $queryStringSections[] = urlencode($name) . '=' . urlencode($trimmedVal);
238     }
239
240     if (count($queryStringSections) === 0) {
241         return $path;
242     }
243
244     return baseUrl($path . '?' . implode('&', $queryStringSections));
245 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.