Completed
Pull Request — master (#8051)
by Julius
18:27
created
lib/private/TemplateLayout.php 2 patches
Indentation   +286 added lines, -286 removed lines patch added patch discarded remove patch
@@ -45,290 +45,290 @@
 block discarded – undo
45 45
 
46 46
 class TemplateLayout extends \OC_Template {
47 47
 
48
-	private static $versionHash = '';
49
-
50
-	/**
51
-	 * @var \OCP\IConfig
52
-	 */
53
-	private $config;
54
-
55
-	/**
56
-	 * @param string $renderAs
57
-	 * @param string $appId application id
58
-	 */
59
-	public function __construct( $renderAs, $appId = '' ) {
60
-
61
-		// yes - should be injected ....
62
-		$this->config = \OC::$server->getConfig();
63
-
64
-
65
-		// Decide which page we show
66
-		if($renderAs == 'user') {
67
-			parent::__construct( 'core', 'layout.user' );
68
-			if(in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) {
69
-				$this->assign('bodyid', 'body-settings');
70
-			}else{
71
-				$this->assign('bodyid', 'body-user');
72
-			}
73
-
74
-			// Code integrity notification
75
-			$integrityChecker = \OC::$server->getIntegrityCodeChecker();
76
-			if(\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) {
77
-				\OCP\Util::addScript('core', 'integritycheck-failed-notification');
78
-			}
79
-
80
-			// Add navigation entry
81
-			$this->assign( 'application', '');
82
-			$this->assign( 'appid', $appId );
83
-			$navigation = \OC_App::getNavigation();
84
-			$this->assign( 'navigation', $navigation);
85
-			$settingsNavigation = \OC_App::getSettingsNavigation();
86
-			$this->assign( 'settingsnavigation', $settingsNavigation);
87
-			foreach($navigation as $entry) {
88
-				if ($entry['active']) {
89
-					$this->assign( 'application', $entry['name'] );
90
-					break;
91
-				}
92
-			}
93
-
94
-			foreach($settingsNavigation as $entry) {
95
-				if ($entry['active']) {
96
-					$this->assign( 'application', $entry['name'] );
97
-					break;
98
-				}
99
-			}
100
-			$userDisplayName = \OC_User::getDisplayName();
101
-			$this->assign('user_displayname', $userDisplayName);
102
-			$this->assign('user_uid', \OC_User::getUser());
103
-
104
-			if (\OC_User::getUser() === false) {
105
-				$this->assign('userAvatarSet', false);
106
-			} else {
107
-				$this->assign('userAvatarSet', \OC::$server->getAvatarManager()->getAvatar(\OC_User::getUser())->exists());
108
-				$this->assign('userAvatarVersion', $this->config->getUserValue(\OC_User::getUser(), 'avatar', 'version', 0));
109
-			}
110
-
111
-			// check if app menu icons should be inverted
112
-			try {
113
-				/** @var \OCA\Theming\Util $util */
114
-				$util = \OC::$server->query(\OCA\Theming\Util::class);
115
-				$this->assign('themingInvertMenu', $util->invertTextColor(\OC::$server->getThemingDefaults()->getColorPrimary()));
116
-			} catch (\OCP\AppFramework\QueryException $e) {
117
-				$this->assign('themingInvertMenu', false);
118
-			}
119
-
120
-		} else if ($renderAs == 'error') {
121
-			parent::__construct('core', 'layout.guest', '', false);
122
-			$this->assign('bodyid', 'body-login');
123
-		} else if ($renderAs == 'guest') {
124
-			parent::__construct('core', 'layout.guest');
125
-			$this->assign('bodyid', 'body-login');
126
-		} else if ($renderAs == 'public') {
127
-			parent::__construct('core', 'layout.public');
128
-			$this->assign( 'appid', $appId );
129
-			$this->assign('bodyid', 'body-public');
130
-		} else {
131
-			parent::__construct('core', 'layout.base');
132
-
133
-		}
134
-		// Send the language to our layouts
135
-		$lang = \OC::$server->getL10NFactory()->findLanguage();
136
-		$lang = str_replace('_', '-', $lang);
137
-		$this->assign('language', $lang);
138
-
139
-		if(\OC::$server->getSystemConfig()->getValue('installed', false)) {
140
-			if (empty(self::$versionHash)) {
141
-				$v = \OC_App::getAppVersions();
142
-				$v['core'] = implode('.', \OCP\Util::getVersion());
143
-				self::$versionHash = substr(md5(implode(',', $v)), 0, 8);
144
-			}
145
-		} else {
146
-			self::$versionHash = md5('not installed');
147
-		}
148
-
149
-		// Add the js files
150
-		$jsFiles = self::findJavascriptFiles(\OC_Util::$scripts);
151
-		$this->assign('jsfiles', array());
152
-		if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') {
153
-			if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {
154
-				$jsConfigHelper = new JSConfigHelper(
155
-					\OC::$server->getL10N('lib'),
156
-					\OC::$server->query(Defaults::class),
157
-					\OC::$server->getAppManager(),
158
-					\OC::$server->getSession(),
159
-					\OC::$server->getUserSession()->getUser(),
160
-					$this->config,
161
-					\OC::$server->getGroupManager(),
162
-					\OC::$server->getIniWrapper(),
163
-					\OC::$server->getURLGenerator()
164
-				);
165
-				$this->assign('inline_ocjs', $jsConfigHelper->getConfig());
166
-			} else {
167
-				$this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash]));
168
-			}
169
-		}
170
-		foreach($jsFiles as $info) {
171
-			$web = $info[1];
172
-			$file = $info[2];
173
-			$this->append( 'jsfiles', $web.'/'.$file . $this->getVersionHashSuffix() );
174
-		}
175
-
176
-		try {
177
-			$pathInfo = \OC::$server->getRequest()->getPathInfo();
178
-		} catch (\Exception $e) {
179
-			$pathInfo = '';
180
-		}
181
-
182
-		// Do not initialise scss appdata until we have a fully installed instance
183
-		// Do not load scss for update, errors, installation or login page
184
-		if(\OC::$server->getSystemConfig()->getValue('installed', false)
185
-			&& !\OCP\Util::needUpgrade()
186
-			&& $pathInfo !== ''
187
-			&& !preg_match('/^\/login/', $pathInfo)
188
-			&& $renderAs !== 'error' && $renderAs !== 'guest'
189
-		) {
190
-			$cssFiles = self::findStylesheetFiles(\OC_Util::$styles);
191
-		} else {
192
-			// If we ignore the scss compiler,
193
-			// we need to load the guest css fallback
194
-			\OC_Util::addStyle('guest');
195
-			$cssFiles = self::findStylesheetFiles(\OC_Util::$styles, false);
196
-		}
197
-
198
-		$this->assign('cssfiles', array());
199
-		$this->assign('printcssfiles', []);
200
-		$this->assign('versionHash', self::$versionHash);
201
-		foreach($cssFiles as $info) {
202
-			$web = $info[1];
203
-			$file = $info[2];
204
-
205
-			if (substr($file, -strlen('print.css')) === 'print.css') {
206
-				$this->append( 'printcssfiles', $web.'/'.$file . $this->getVersionHashSuffix() );
207
-			} else {
208
-				$this->append( 'cssfiles', $web.'/'.$file . $this->getVersionHashSuffix($web, $file)  );
209
-			}
210
-		}
211
-	}
212
-
213
-	/**
214
-	 * @param string $path
215
- 	 * @param string $file
216
-	 * @return string
217
-	 */
218
-	protected function getVersionHashSuffix($path = false, $file = false) {
219
-		if ($this->config->getSystemValue('debug', false)) {
220
-			// allows chrome workspace mapping in debug mode
221
-			return "";
222
-		}
223
-		$themingSuffix = '';
224
-		$v = [];
225
-
226
-		if ($this->config->getSystemValue('installed', false)) {
227
-			if (\OC::$server->getAppManager()->isInstalled('theming')) {
228
-				$themingSuffix = '-' . $this->config->getAppValue('theming', 'cachebuster', '0');
229
-			}
230
-			$v = \OC_App::getAppVersions();
231
-		}
232
-
233
-		// Try the webroot path for a match
234
-		if ($path !== false && $path !== '') {
235
-			$appName = $this->getAppNamefromPath($path);
236
-			if(array_key_exists($appName, $v)) {
237
-				$appVersion = $v[$appName];
238
-				return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
239
-			}
240
-		}
241
-		// fallback to the file path instead
242
-		if ($file !== false && $file !== '') {
243
-			$appName = $this->getAppNamefromPath($file);
244
-			if(array_key_exists($appName, $v)) {
245
-				$appVersion = $v[$appName];
246
-				return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
247
-			}
248
-		}
249
-
250
-		return '?v=' . self::$versionHash . $themingSuffix;
251
-	}
252
-
253
-	/**
254
-	 * @param array $styles
255
-	 * @return array
256
-	 */
257
-	static public function findStylesheetFiles($styles, $compileScss = true) {
258
-		// Read the selected theme from the config file
259
-		$theme = \OC_Util::getTheme();
260
-
261
-		if($compileScss) {
262
-			$SCSSCacher = \OC::$server->query(SCSSCacher::class);
263
-		} else {
264
-			$SCSSCacher = null;
265
-		}
266
-
267
-		$locator = new \OC\Template\CSSResourceLocator(
268
-			\OC::$server->getLogger(),
269
-			$theme,
270
-			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
271
-			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
272
-			$SCSSCacher
273
-		);
274
-		$locator->find($styles);
275
-		return $locator->getResources();
276
-	}
277
-
278
-	/**
279
-	 * @param string $path
280
-	 * @return string|boolean
281
-	 */
282
-	public function getAppNamefromPath($path) {
283
-		if ($path !== '' && is_string($path)) {
284
-			$pathParts = explode('/', $path);
285
-			if ($pathParts[0] === 'css') {
286
-				// This is a scss request
287
-				return $pathParts[1];
288
-			}
289
-			return end($pathParts);
290
-		}
291
-		return false;
292
-
293
-	}
294
-
295
-	/**
296
-	 * @param array $scripts
297
-	 * @return array
298
-	 */
299
-	static public function findJavascriptFiles($scripts) {
300
-		// Read the selected theme from the config file
301
-		$theme = \OC_Util::getTheme();
302
-
303
-		$locator = new \OC\Template\JSResourceLocator(
304
-			\OC::$server->getLogger(),
305
-			$theme,
306
-			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
307
-			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
308
-			new JSCombiner(
309
-				\OC::$server->getAppDataDir('js'),
310
-				\OC::$server->getURLGenerator(),
311
-				\OC::$server->getMemCacheFactory()->createDistributed('JS'),
312
-				\OC::$server->getSystemConfig(),
313
-				\OC::$server->getLogger()
314
-			)
315
-			);
316
-		$locator->find($scripts);
317
-		return $locator->getResources();
318
-	}
319
-
320
-	/**
321
-	 * Converts the absolute file path to a relative path from \OC::$SERVERROOT
322
-	 * @param string $filePath Absolute path
323
-	 * @return string Relative path
324
-	 * @throws \Exception If $filePath is not under \OC::$SERVERROOT
325
-	 */
326
-	public static function convertToRelativePath($filePath) {
327
-		$relativePath = explode(\OC::$SERVERROOT, $filePath);
328
-		if(count($relativePath) !== 2) {
329
-			throw new \Exception('$filePath is not under the \OC::$SERVERROOT');
330
-		}
331
-
332
-		return $relativePath[1];
333
-	}
48
+    private static $versionHash = '';
49
+
50
+    /**
51
+     * @var \OCP\IConfig
52
+     */
53
+    private $config;
54
+
55
+    /**
56
+     * @param string $renderAs
57
+     * @param string $appId application id
58
+     */
59
+    public function __construct( $renderAs, $appId = '' ) {
60
+
61
+        // yes - should be injected ....
62
+        $this->config = \OC::$server->getConfig();
63
+
64
+
65
+        // Decide which page we show
66
+        if($renderAs == 'user') {
67
+            parent::__construct( 'core', 'layout.user' );
68
+            if(in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) {
69
+                $this->assign('bodyid', 'body-settings');
70
+            }else{
71
+                $this->assign('bodyid', 'body-user');
72
+            }
73
+
74
+            // Code integrity notification
75
+            $integrityChecker = \OC::$server->getIntegrityCodeChecker();
76
+            if(\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) {
77
+                \OCP\Util::addScript('core', 'integritycheck-failed-notification');
78
+            }
79
+
80
+            // Add navigation entry
81
+            $this->assign( 'application', '');
82
+            $this->assign( 'appid', $appId );
83
+            $navigation = \OC_App::getNavigation();
84
+            $this->assign( 'navigation', $navigation);
85
+            $settingsNavigation = \OC_App::getSettingsNavigation();
86
+            $this->assign( 'settingsnavigation', $settingsNavigation);
87
+            foreach($navigation as $entry) {
88
+                if ($entry['active']) {
89
+                    $this->assign( 'application', $entry['name'] );
90
+                    break;
91
+                }
92
+            }
93
+
94
+            foreach($settingsNavigation as $entry) {
95
+                if ($entry['active']) {
96
+                    $this->assign( 'application', $entry['name'] );
97
+                    break;
98
+                }
99
+            }
100
+            $userDisplayName = \OC_User::getDisplayName();
101
+            $this->assign('user_displayname', $userDisplayName);
102
+            $this->assign('user_uid', \OC_User::getUser());
103
+
104
+            if (\OC_User::getUser() === false) {
105
+                $this->assign('userAvatarSet', false);
106
+            } else {
107
+                $this->assign('userAvatarSet', \OC::$server->getAvatarManager()->getAvatar(\OC_User::getUser())->exists());
108
+                $this->assign('userAvatarVersion', $this->config->getUserValue(\OC_User::getUser(), 'avatar', 'version', 0));
109
+            }
110
+
111
+            // check if app menu icons should be inverted
112
+            try {
113
+                /** @var \OCA\Theming\Util $util */
114
+                $util = \OC::$server->query(\OCA\Theming\Util::class);
115
+                $this->assign('themingInvertMenu', $util->invertTextColor(\OC::$server->getThemingDefaults()->getColorPrimary()));
116
+            } catch (\OCP\AppFramework\QueryException $e) {
117
+                $this->assign('themingInvertMenu', false);
118
+            }
119
+
120
+        } else if ($renderAs == 'error') {
121
+            parent::__construct('core', 'layout.guest', '', false);
122
+            $this->assign('bodyid', 'body-login');
123
+        } else if ($renderAs == 'guest') {
124
+            parent::__construct('core', 'layout.guest');
125
+            $this->assign('bodyid', 'body-login');
126
+        } else if ($renderAs == 'public') {
127
+            parent::__construct('core', 'layout.public');
128
+            $this->assign( 'appid', $appId );
129
+            $this->assign('bodyid', 'body-public');
130
+        } else {
131
+            parent::__construct('core', 'layout.base');
132
+
133
+        }
134
+        // Send the language to our layouts
135
+        $lang = \OC::$server->getL10NFactory()->findLanguage();
136
+        $lang = str_replace('_', '-', $lang);
137
+        $this->assign('language', $lang);
138
+
139
+        if(\OC::$server->getSystemConfig()->getValue('installed', false)) {
140
+            if (empty(self::$versionHash)) {
141
+                $v = \OC_App::getAppVersions();
142
+                $v['core'] = implode('.', \OCP\Util::getVersion());
143
+                self::$versionHash = substr(md5(implode(',', $v)), 0, 8);
144
+            }
145
+        } else {
146
+            self::$versionHash = md5('not installed');
147
+        }
148
+
149
+        // Add the js files
150
+        $jsFiles = self::findJavascriptFiles(\OC_Util::$scripts);
151
+        $this->assign('jsfiles', array());
152
+        if ($this->config->getSystemValue('installed', false) && $renderAs != 'error') {
153
+            if (\OC::$server->getContentSecurityPolicyNonceManager()->browserSupportsCspV3()) {
154
+                $jsConfigHelper = new JSConfigHelper(
155
+                    \OC::$server->getL10N('lib'),
156
+                    \OC::$server->query(Defaults::class),
157
+                    \OC::$server->getAppManager(),
158
+                    \OC::$server->getSession(),
159
+                    \OC::$server->getUserSession()->getUser(),
160
+                    $this->config,
161
+                    \OC::$server->getGroupManager(),
162
+                    \OC::$server->getIniWrapper(),
163
+                    \OC::$server->getURLGenerator()
164
+                );
165
+                $this->assign('inline_ocjs', $jsConfigHelper->getConfig());
166
+            } else {
167
+                $this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash]));
168
+            }
169
+        }
170
+        foreach($jsFiles as $info) {
171
+            $web = $info[1];
172
+            $file = $info[2];
173
+            $this->append( 'jsfiles', $web.'/'.$file . $this->getVersionHashSuffix() );
174
+        }
175
+
176
+        try {
177
+            $pathInfo = \OC::$server->getRequest()->getPathInfo();
178
+        } catch (\Exception $e) {
179
+            $pathInfo = '';
180
+        }
181
+
182
+        // Do not initialise scss appdata until we have a fully installed instance
183
+        // Do not load scss for update, errors, installation or login page
184
+        if(\OC::$server->getSystemConfig()->getValue('installed', false)
185
+            && !\OCP\Util::needUpgrade()
186
+            && $pathInfo !== ''
187
+            && !preg_match('/^\/login/', $pathInfo)
188
+            && $renderAs !== 'error' && $renderAs !== 'guest'
189
+        ) {
190
+            $cssFiles = self::findStylesheetFiles(\OC_Util::$styles);
191
+        } else {
192
+            // If we ignore the scss compiler,
193
+            // we need to load the guest css fallback
194
+            \OC_Util::addStyle('guest');
195
+            $cssFiles = self::findStylesheetFiles(\OC_Util::$styles, false);
196
+        }
197
+
198
+        $this->assign('cssfiles', array());
199
+        $this->assign('printcssfiles', []);
200
+        $this->assign('versionHash', self::$versionHash);
201
+        foreach($cssFiles as $info) {
202
+            $web = $info[1];
203
+            $file = $info[2];
204
+
205
+            if (substr($file, -strlen('print.css')) === 'print.css') {
206
+                $this->append( 'printcssfiles', $web.'/'.$file . $this->getVersionHashSuffix() );
207
+            } else {
208
+                $this->append( 'cssfiles', $web.'/'.$file . $this->getVersionHashSuffix($web, $file)  );
209
+            }
210
+        }
211
+    }
212
+
213
+    /**
214
+     * @param string $path
215
+     * @param string $file
216
+     * @return string
217
+     */
218
+    protected function getVersionHashSuffix($path = false, $file = false) {
219
+        if ($this->config->getSystemValue('debug', false)) {
220
+            // allows chrome workspace mapping in debug mode
221
+            return "";
222
+        }
223
+        $themingSuffix = '';
224
+        $v = [];
225
+
226
+        if ($this->config->getSystemValue('installed', false)) {
227
+            if (\OC::$server->getAppManager()->isInstalled('theming')) {
228
+                $themingSuffix = '-' . $this->config->getAppValue('theming', 'cachebuster', '0');
229
+            }
230
+            $v = \OC_App::getAppVersions();
231
+        }
232
+
233
+        // Try the webroot path for a match
234
+        if ($path !== false && $path !== '') {
235
+            $appName = $this->getAppNamefromPath($path);
236
+            if(array_key_exists($appName, $v)) {
237
+                $appVersion = $v[$appName];
238
+                return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
239
+            }
240
+        }
241
+        // fallback to the file path instead
242
+        if ($file !== false && $file !== '') {
243
+            $appName = $this->getAppNamefromPath($file);
244
+            if(array_key_exists($appName, $v)) {
245
+                $appVersion = $v[$appName];
246
+                return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
247
+            }
248
+        }
249
+
250
+        return '?v=' . self::$versionHash . $themingSuffix;
251
+    }
252
+
253
+    /**
254
+     * @param array $styles
255
+     * @return array
256
+     */
257
+    static public function findStylesheetFiles($styles, $compileScss = true) {
258
+        // Read the selected theme from the config file
259
+        $theme = \OC_Util::getTheme();
260
+
261
+        if($compileScss) {
262
+            $SCSSCacher = \OC::$server->query(SCSSCacher::class);
263
+        } else {
264
+            $SCSSCacher = null;
265
+        }
266
+
267
+        $locator = new \OC\Template\CSSResourceLocator(
268
+            \OC::$server->getLogger(),
269
+            $theme,
270
+            array( \OC::$SERVERROOT => \OC::$WEBROOT ),
271
+            array( \OC::$SERVERROOT => \OC::$WEBROOT ),
272
+            $SCSSCacher
273
+        );
274
+        $locator->find($styles);
275
+        return $locator->getResources();
276
+    }
277
+
278
+    /**
279
+     * @param string $path
280
+     * @return string|boolean
281
+     */
282
+    public function getAppNamefromPath($path) {
283
+        if ($path !== '' && is_string($path)) {
284
+            $pathParts = explode('/', $path);
285
+            if ($pathParts[0] === 'css') {
286
+                // This is a scss request
287
+                return $pathParts[1];
288
+            }
289
+            return end($pathParts);
290
+        }
291
+        return false;
292
+
293
+    }
294
+
295
+    /**
296
+     * @param array $scripts
297
+     * @return array
298
+     */
299
+    static public function findJavascriptFiles($scripts) {
300
+        // Read the selected theme from the config file
301
+        $theme = \OC_Util::getTheme();
302
+
303
+        $locator = new \OC\Template\JSResourceLocator(
304
+            \OC::$server->getLogger(),
305
+            $theme,
306
+            array( \OC::$SERVERROOT => \OC::$WEBROOT ),
307
+            array( \OC::$SERVERROOT => \OC::$WEBROOT ),
308
+            new JSCombiner(
309
+                \OC::$server->getAppDataDir('js'),
310
+                \OC::$server->getURLGenerator(),
311
+                \OC::$server->getMemCacheFactory()->createDistributed('JS'),
312
+                \OC::$server->getSystemConfig(),
313
+                \OC::$server->getLogger()
314
+            )
315
+            );
316
+        $locator->find($scripts);
317
+        return $locator->getResources();
318
+    }
319
+
320
+    /**
321
+     * Converts the absolute file path to a relative path from \OC::$SERVERROOT
322
+     * @param string $filePath Absolute path
323
+     * @return string Relative path
324
+     * @throws \Exception If $filePath is not under \OC::$SERVERROOT
325
+     */
326
+    public static function convertToRelativePath($filePath) {
327
+        $relativePath = explode(\OC::$SERVERROOT, $filePath);
328
+        if(count($relativePath) !== 2) {
329
+            throw new \Exception('$filePath is not under the \OC::$SERVERROOT');
330
+        }
331
+
332
+        return $relativePath[1];
333
+    }
334 334
 }
Please login to merge, or discard this patch.
Spacing   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -56,44 +56,44 @@  discard block
 block discarded – undo
56 56
 	 * @param string $renderAs
57 57
 	 * @param string $appId application id
58 58
 	 */
59
-	public function __construct( $renderAs, $appId = '' ) {
59
+	public function __construct($renderAs, $appId = '') {
60 60
 
61 61
 		// yes - should be injected ....
62 62
 		$this->config = \OC::$server->getConfig();
63 63
 
64 64
 
65 65
 		// Decide which page we show
66
-		if($renderAs == 'user') {
67
-			parent::__construct( 'core', 'layout.user' );
68
-			if(in_array(\OC_App::getCurrentApp(), ['settings','admin', 'help']) !== false) {
66
+		if ($renderAs == 'user') {
67
+			parent::__construct('core', 'layout.user');
68
+			if (in_array(\OC_App::getCurrentApp(), ['settings', 'admin', 'help']) !== false) {
69 69
 				$this->assign('bodyid', 'body-settings');
70
-			}else{
70
+			} else {
71 71
 				$this->assign('bodyid', 'body-user');
72 72
 			}
73 73
 
74 74
 			// Code integrity notification
75 75
 			$integrityChecker = \OC::$server->getIntegrityCodeChecker();
76
-			if(\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) {
76
+			if (\OC_User::isAdminUser(\OC_User::getUser()) && $integrityChecker->isCodeCheckEnforced() && !$integrityChecker->hasPassedCheck()) {
77 77
 				\OCP\Util::addScript('core', 'integritycheck-failed-notification');
78 78
 			}
79 79
 
80 80
 			// Add navigation entry
81
-			$this->assign( 'application', '');
82
-			$this->assign( 'appid', $appId );
81
+			$this->assign('application', '');
82
+			$this->assign('appid', $appId);
83 83
 			$navigation = \OC_App::getNavigation();
84
-			$this->assign( 'navigation', $navigation);
84
+			$this->assign('navigation', $navigation);
85 85
 			$settingsNavigation = \OC_App::getSettingsNavigation();
86
-			$this->assign( 'settingsnavigation', $settingsNavigation);
87
-			foreach($navigation as $entry) {
86
+			$this->assign('settingsnavigation', $settingsNavigation);
87
+			foreach ($navigation as $entry) {
88 88
 				if ($entry['active']) {
89
-					$this->assign( 'application', $entry['name'] );
89
+					$this->assign('application', $entry['name']);
90 90
 					break;
91 91
 				}
92 92
 			}
93 93
 
94
-			foreach($settingsNavigation as $entry) {
94
+			foreach ($settingsNavigation as $entry) {
95 95
 				if ($entry['active']) {
96
-					$this->assign( 'application', $entry['name'] );
96
+					$this->assign('application', $entry['name']);
97 97
 					break;
98 98
 				}
99 99
 			}
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
 			$this->assign('bodyid', 'body-login');
126 126
 		} else if ($renderAs == 'public') {
127 127
 			parent::__construct('core', 'layout.public');
128
-			$this->assign( 'appid', $appId );
128
+			$this->assign('appid', $appId);
129 129
 			$this->assign('bodyid', 'body-public');
130 130
 		} else {
131 131
 			parent::__construct('core', 'layout.base');
@@ -136,7 +136,7 @@  discard block
 block discarded – undo
136 136
 		$lang = str_replace('_', '-', $lang);
137 137
 		$this->assign('language', $lang);
138 138
 
139
-		if(\OC::$server->getSystemConfig()->getValue('installed', false)) {
139
+		if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
140 140
 			if (empty(self::$versionHash)) {
141 141
 				$v = \OC_App::getAppVersions();
142 142
 				$v['core'] = implode('.', \OCP\Util::getVersion());
@@ -167,10 +167,10 @@  discard block
 block discarded – undo
167 167
 				$this->append('jsfiles', \OC::$server->getURLGenerator()->linkToRoute('core.OCJS.getConfig', ['v' => self::$versionHash]));
168 168
 			}
169 169
 		}
170
-		foreach($jsFiles as $info) {
170
+		foreach ($jsFiles as $info) {
171 171
 			$web = $info[1];
172 172
 			$file = $info[2];
173
-			$this->append( 'jsfiles', $web.'/'.$file . $this->getVersionHashSuffix() );
173
+			$this->append('jsfiles', $web.'/'.$file.$this->getVersionHashSuffix());
174 174
 		}
175 175
 
176 176
 		try {
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
 
182 182
 		// Do not initialise scss appdata until we have a fully installed instance
183 183
 		// Do not load scss for update, errors, installation or login page
184
-		if(\OC::$server->getSystemConfig()->getValue('installed', false)
184
+		if (\OC::$server->getSystemConfig()->getValue('installed', false)
185 185
 			&& !\OCP\Util::needUpgrade()
186 186
 			&& $pathInfo !== ''
187 187
 			&& !preg_match('/^\/login/', $pathInfo)
@@ -198,14 +198,14 @@  discard block
 block discarded – undo
198 198
 		$this->assign('cssfiles', array());
199 199
 		$this->assign('printcssfiles', []);
200 200
 		$this->assign('versionHash', self::$versionHash);
201
-		foreach($cssFiles as $info) {
201
+		foreach ($cssFiles as $info) {
202 202
 			$web = $info[1];
203 203
 			$file = $info[2];
204 204
 
205 205
 			if (substr($file, -strlen('print.css')) === 'print.css') {
206
-				$this->append( 'printcssfiles', $web.'/'.$file . $this->getVersionHashSuffix() );
206
+				$this->append('printcssfiles', $web.'/'.$file.$this->getVersionHashSuffix());
207 207
 			} else {
208
-				$this->append( 'cssfiles', $web.'/'.$file . $this->getVersionHashSuffix($web, $file)  );
208
+				$this->append('cssfiles', $web.'/'.$file.$this->getVersionHashSuffix($web, $file));
209 209
 			}
210 210
 		}
211 211
 	}
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
 
226 226
 		if ($this->config->getSystemValue('installed', false)) {
227 227
 			if (\OC::$server->getAppManager()->isInstalled('theming')) {
228
-				$themingSuffix = '-' . $this->config->getAppValue('theming', 'cachebuster', '0');
228
+				$themingSuffix = '-'.$this->config->getAppValue('theming', 'cachebuster', '0');
229 229
 			}
230 230
 			$v = \OC_App::getAppVersions();
231 231
 		}
@@ -233,21 +233,21 @@  discard block
 block discarded – undo
233 233
 		// Try the webroot path for a match
234 234
 		if ($path !== false && $path !== '') {
235 235
 			$appName = $this->getAppNamefromPath($path);
236
-			if(array_key_exists($appName, $v)) {
236
+			if (array_key_exists($appName, $v)) {
237 237
 				$appVersion = $v[$appName];
238
-				return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
238
+				return '?v='.substr(md5($appVersion), 0, 8).$themingSuffix;
239 239
 			}
240 240
 		}
241 241
 		// fallback to the file path instead
242 242
 		if ($file !== false && $file !== '') {
243 243
 			$appName = $this->getAppNamefromPath($file);
244
-			if(array_key_exists($appName, $v)) {
244
+			if (array_key_exists($appName, $v)) {
245 245
 				$appVersion = $v[$appName];
246
-				return '?v=' . substr(md5($appVersion), 0, 8) . $themingSuffix;
246
+				return '?v='.substr(md5($appVersion), 0, 8).$themingSuffix;
247 247
 			}
248 248
 		}
249 249
 
250
-		return '?v=' . self::$versionHash . $themingSuffix;
250
+		return '?v='.self::$versionHash.$themingSuffix;
251 251
 	}
252 252
 
253 253
 	/**
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
 		// Read the selected theme from the config file
259 259
 		$theme = \OC_Util::getTheme();
260 260
 
261
-		if($compileScss) {
261
+		if ($compileScss) {
262 262
 			$SCSSCacher = \OC::$server->query(SCSSCacher::class);
263 263
 		} else {
264 264
 			$SCSSCacher = null;
@@ -267,8 +267,8 @@  discard block
 block discarded – undo
267 267
 		$locator = new \OC\Template\CSSResourceLocator(
268 268
 			\OC::$server->getLogger(),
269 269
 			$theme,
270
-			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
271
-			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
270
+			array(\OC::$SERVERROOT => \OC::$WEBROOT),
271
+			array(\OC::$SERVERROOT => \OC::$WEBROOT),
272 272
 			$SCSSCacher
273 273
 		);
274 274
 		$locator->find($styles);
@@ -303,8 +303,8 @@  discard block
 block discarded – undo
303 303
 		$locator = new \OC\Template\JSResourceLocator(
304 304
 			\OC::$server->getLogger(),
305 305
 			$theme,
306
-			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
307
-			array( \OC::$SERVERROOT => \OC::$WEBROOT ),
306
+			array(\OC::$SERVERROOT => \OC::$WEBROOT),
307
+			array(\OC::$SERVERROOT => \OC::$WEBROOT),
308 308
 			new JSCombiner(
309 309
 				\OC::$server->getAppDataDir('js'),
310 310
 				\OC::$server->getURLGenerator(),
@@ -325,7 +325,7 @@  discard block
 block discarded – undo
325 325
 	 */
326 326
 	public static function convertToRelativePath($filePath) {
327 327
 		$relativePath = explode(\OC::$SERVERROOT, $filePath);
328
-		if(count($relativePath) !== 2) {
328
+		if (count($relativePath) !== 2) {
329 329
 			throw new \Exception('$filePath is not under the \OC::$SERVERROOT');
330 330
 		}
331 331
 
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareController.php 1 patch
Indentation   +574 added lines, -574 removed lines patch added patch discarded remove patch
@@ -70,582 +70,582 @@
 block discarded – undo
70 70
  */
71 71
 class ShareController extends Controller {
72 72
 
73
-	/** @var IConfig */
74
-	protected $config;
75
-	/** @var IURLGenerator */
76
-	protected $urlGenerator;
77
-	/** @var IUserManager */
78
-	protected $userManager;
79
-	/** @var ILogger */
80
-	protected $logger;
81
-	/** @var \OCP\Activity\IManager */
82
-	protected $activityManager;
83
-	/** @var \OCP\Share\IManager */
84
-	protected $shareManager;
85
-	/** @var ISession */
86
-	protected $session;
87
-	/** @var IPreview */
88
-	protected $previewManager;
89
-	/** @var IRootFolder */
90
-	protected $rootFolder;
91
-	/** @var FederatedShareProvider */
92
-	protected $federatedShareProvider;
93
-	/** @var EventDispatcherInterface */
94
-	protected $eventDispatcher;
95
-	/** @var IL10N */
96
-	protected $l10n;
97
-	/** @var Defaults */
98
-	protected $defaults;
99
-
100
-	/**
101
-	 * @param string $appName
102
-	 * @param IRequest $request
103
-	 * @param IConfig $config
104
-	 * @param IURLGenerator $urlGenerator
105
-	 * @param IUserManager $userManager
106
-	 * @param ILogger $logger
107
-	 * @param \OCP\Activity\IManager $activityManager
108
-	 * @param \OCP\Share\IManager $shareManager
109
-	 * @param ISession $session
110
-	 * @param IPreview $previewManager
111
-	 * @param IRootFolder $rootFolder
112
-	 * @param FederatedShareProvider $federatedShareProvider
113
-	 * @param EventDispatcherInterface $eventDispatcher
114
-	 * @param IL10N $l10n
115
-	 * @param Defaults $defaults
116
-	 */
117
-	public function __construct($appName,
118
-								IRequest $request,
119
-								IConfig $config,
120
-								IURLGenerator $urlGenerator,
121
-								IUserManager $userManager,
122
-								ILogger $logger,
123
-								\OCP\Activity\IManager $activityManager,
124
-								\OCP\Share\IManager $shareManager,
125
-								ISession $session,
126
-								IPreview $previewManager,
127
-								IRootFolder $rootFolder,
128
-								FederatedShareProvider $federatedShareProvider,
129
-								EventDispatcherInterface $eventDispatcher,
130
-								IL10N $l10n,
131
-								Defaults $defaults) {
132
-		parent::__construct($appName, $request);
133
-
134
-		$this->config = $config;
135
-		$this->urlGenerator = $urlGenerator;
136
-		$this->userManager = $userManager;
137
-		$this->logger = $logger;
138
-		$this->activityManager = $activityManager;
139
-		$this->shareManager = $shareManager;
140
-		$this->session = $session;
141
-		$this->previewManager = $previewManager;
142
-		$this->rootFolder = $rootFolder;
143
-		$this->federatedShareProvider = $federatedShareProvider;
144
-		$this->eventDispatcher = $eventDispatcher;
145
-		$this->l10n = $l10n;
146
-		$this->defaults = $defaults;
147
-	}
148
-
149
-	/**
150
-	 * @PublicPage
151
-	 * @NoCSRFRequired
152
-	 *
153
-	 * @param string $token
154
-	 * @return TemplateResponse|RedirectResponse
155
-	 */
156
-	public function showAuthenticate($token) {
157
-		$share = $this->shareManager->getShareByToken($token);
158
-
159
-		if($this->linkShareAuth($share)) {
160
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
161
-		}
162
-
163
-		return new TemplateResponse($this->appName, 'authenticate', array(), 'guest');
164
-	}
165
-
166
-	/**
167
-	 * @PublicPage
168
-	 * @UseSession
169
-	 * @BruteForceProtection(action=publicLinkAuth)
170
-	 *
171
-	 * Authenticates against password-protected shares
172
-	 * @param string $token
173
-	 * @param string $password
174
-	 * @return RedirectResponse|TemplateResponse|NotFoundResponse
175
-	 */
176
-	public function authenticate($token, $password = '') {
177
-
178
-		// Check whether share exists
179
-		try {
180
-			$share = $this->shareManager->getShareByToken($token);
181
-		} catch (ShareNotFound $e) {
182
-			return new NotFoundResponse();
183
-		}
184
-
185
-		$authenticate = $this->linkShareAuth($share, $password);
186
-
187
-		if($authenticate === true) {
188
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
189
-		}
190
-
191
-		$response = new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest');
192
-		$response->throttle();
193
-		return $response;
194
-	}
195
-
196
-	/**
197
-	 * Authenticate a link item with the given password.
198
-	 * Or use the session if no password is provided.
199
-	 *
200
-	 * This is a modified version of Helper::authenticate
201
-	 * TODO: Try to merge back eventually with Helper::authenticate
202
-	 *
203
-	 * @param \OCP\Share\IShare $share
204
-	 * @param string|null $password
205
-	 * @return bool
206
-	 */
207
-	private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
208
-		if ($password !== null) {
209
-			if ($this->shareManager->checkPassword($share, $password)) {
210
-				$this->session->set('public_link_authenticated', (string)$share->getId());
211
-			} else {
212
-				$this->emitAccessShareHook($share, 403, 'Wrong password');
213
-				return false;
214
-			}
215
-		} else {
216
-			// not authenticated ?
217
-			if ( ! $this->session->exists('public_link_authenticated')
218
-				|| $this->session->get('public_link_authenticated') !== (string)$share->getId()) {
219
-				return false;
220
-			}
221
-		}
222
-		return true;
223
-	}
224
-
225
-	/**
226
-	 * throws hooks when a share is attempted to be accessed
227
-	 *
228
-	 * @param \OCP\Share\IShare|string $share the Share instance if available,
229
-	 * otherwise token
230
-	 * @param int $errorCode
231
-	 * @param string $errorMessage
232
-	 * @throws \OC\HintException
233
-	 * @throws \OC\ServerNotAvailableException
234
-	 */
235
-	protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
236
-		$itemType = $itemSource = $uidOwner = '';
237
-		$token = $share;
238
-		$exception = null;
239
-		if($share instanceof \OCP\Share\IShare) {
240
-			try {
241
-				$token = $share->getToken();
242
-				$uidOwner = $share->getSharedBy();
243
-				$itemType = $share->getNodeType();
244
-				$itemSource = $share->getNodeId();
245
-			} catch (\Exception $e) {
246
-				// we log what we know and pass on the exception afterwards
247
-				$exception = $e;
248
-			}
249
-		}
250
-		\OC_Hook::emit(Share::class, 'share_link_access', [
251
-			'itemType' => $itemType,
252
-			'itemSource' => $itemSource,
253
-			'uidOwner' => $uidOwner,
254
-			'token' => $token,
255
-			'errorCode' => $errorCode,
256
-			'errorMessage' => $errorMessage,
257
-		]);
258
-		if(!is_null($exception)) {
259
-			throw $exception;
260
-		}
261
-	}
262
-
263
-	/**
264
-	 * Validate the permissions of the share
265
-	 *
266
-	 * @param Share\IShare $share
267
-	 * @return bool
268
-	 */
269
-	private function validateShare(\OCP\Share\IShare $share) {
270
-		return $share->getNode()->isReadable() && $share->getNode()->isShareable();
271
-	}
272
-
273
-	/**
274
-	 * @PublicPage
275
-	 * @NoCSRFRequired
276
-	 *
277
-	 * @param string $token
278
-	 * @param string $path
279
-	 * @return TemplateResponse|RedirectResponse|NotFoundResponse
280
-	 * @throws NotFoundException
281
-	 * @throws \Exception
282
-	 */
283
-	public function showShare($token, $path = '') {
284
-		\OC_User::setIncognitoMode(true);
285
-
286
-		// Check whether share exists
287
-		try {
288
-			$share = $this->shareManager->getShareByToken($token);
289
-		} catch (ShareNotFound $e) {
290
-			$this->emitAccessShareHook($token, 404, 'Share not found');
291
-			return new NotFoundResponse();
292
-		}
293
-
294
-		// Share is password protected - check whether the user is permitted to access the share
295
-		if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
296
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
297
-				array('token' => $token)));
298
-		}
299
-
300
-		if (!$this->validateShare($share)) {
301
-			throw new NotFoundException();
302
-		}
303
-		// We can't get the path of a file share
304
-		try {
305
-			if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
306
-				$this->emitAccessShareHook($share, 404, 'Share not found');
307
-				throw new NotFoundException();
308
-			}
309
-		} catch (\Exception $e) {
310
-			$this->emitAccessShareHook($share, 404, 'Share not found');
311
-			throw $e;
312
-		}
313
-
314
-		$shareTmpl = [];
315
-		$shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
316
-		$shareTmpl['owner'] = $share->getShareOwner();
317
-		$shareTmpl['filename'] = $share->getNode()->getName();
318
-		$shareTmpl['directory_path'] = $share->getTarget();
319
-		$shareTmpl['mimetype'] = $share->getNode()->getMimetype();
320
-		$shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
321
-		$shareTmpl['dirToken'] = $token;
322
-		$shareTmpl['sharingToken'] = $token;
323
-		$shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
324
-		$shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
325
-		$shareTmpl['dir'] = '';
326
-		$shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
327
-		$shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
328
-
329
-		// Show file list
330
-		$hideFileList = false;
331
-		if ($share->getNode() instanceof \OCP\Files\Folder) {
332
-			/** @var \OCP\Files\Folder $rootFolder */
333
-			$rootFolder = $share->getNode();
334
-
335
-			try {
336
-				$folderNode = $rootFolder->get($path);
337
-			} catch (\OCP\Files\NotFoundException $e) {
338
-				$this->emitAccessShareHook($share, 404, 'Share not found');
339
-				throw new NotFoundException();
340
-			}
341
-
342
-			$shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
343
-
344
-			/*
73
+    /** @var IConfig */
74
+    protected $config;
75
+    /** @var IURLGenerator */
76
+    protected $urlGenerator;
77
+    /** @var IUserManager */
78
+    protected $userManager;
79
+    /** @var ILogger */
80
+    protected $logger;
81
+    /** @var \OCP\Activity\IManager */
82
+    protected $activityManager;
83
+    /** @var \OCP\Share\IManager */
84
+    protected $shareManager;
85
+    /** @var ISession */
86
+    protected $session;
87
+    /** @var IPreview */
88
+    protected $previewManager;
89
+    /** @var IRootFolder */
90
+    protected $rootFolder;
91
+    /** @var FederatedShareProvider */
92
+    protected $federatedShareProvider;
93
+    /** @var EventDispatcherInterface */
94
+    protected $eventDispatcher;
95
+    /** @var IL10N */
96
+    protected $l10n;
97
+    /** @var Defaults */
98
+    protected $defaults;
99
+
100
+    /**
101
+     * @param string $appName
102
+     * @param IRequest $request
103
+     * @param IConfig $config
104
+     * @param IURLGenerator $urlGenerator
105
+     * @param IUserManager $userManager
106
+     * @param ILogger $logger
107
+     * @param \OCP\Activity\IManager $activityManager
108
+     * @param \OCP\Share\IManager $shareManager
109
+     * @param ISession $session
110
+     * @param IPreview $previewManager
111
+     * @param IRootFolder $rootFolder
112
+     * @param FederatedShareProvider $federatedShareProvider
113
+     * @param EventDispatcherInterface $eventDispatcher
114
+     * @param IL10N $l10n
115
+     * @param Defaults $defaults
116
+     */
117
+    public function __construct($appName,
118
+                                IRequest $request,
119
+                                IConfig $config,
120
+                                IURLGenerator $urlGenerator,
121
+                                IUserManager $userManager,
122
+                                ILogger $logger,
123
+                                \OCP\Activity\IManager $activityManager,
124
+                                \OCP\Share\IManager $shareManager,
125
+                                ISession $session,
126
+                                IPreview $previewManager,
127
+                                IRootFolder $rootFolder,
128
+                                FederatedShareProvider $federatedShareProvider,
129
+                                EventDispatcherInterface $eventDispatcher,
130
+                                IL10N $l10n,
131
+                                Defaults $defaults) {
132
+        parent::__construct($appName, $request);
133
+
134
+        $this->config = $config;
135
+        $this->urlGenerator = $urlGenerator;
136
+        $this->userManager = $userManager;
137
+        $this->logger = $logger;
138
+        $this->activityManager = $activityManager;
139
+        $this->shareManager = $shareManager;
140
+        $this->session = $session;
141
+        $this->previewManager = $previewManager;
142
+        $this->rootFolder = $rootFolder;
143
+        $this->federatedShareProvider = $federatedShareProvider;
144
+        $this->eventDispatcher = $eventDispatcher;
145
+        $this->l10n = $l10n;
146
+        $this->defaults = $defaults;
147
+    }
148
+
149
+    /**
150
+     * @PublicPage
151
+     * @NoCSRFRequired
152
+     *
153
+     * @param string $token
154
+     * @return TemplateResponse|RedirectResponse
155
+     */
156
+    public function showAuthenticate($token) {
157
+        $share = $this->shareManager->getShareByToken($token);
158
+
159
+        if($this->linkShareAuth($share)) {
160
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
161
+        }
162
+
163
+        return new TemplateResponse($this->appName, 'authenticate', array(), 'guest');
164
+    }
165
+
166
+    /**
167
+     * @PublicPage
168
+     * @UseSession
169
+     * @BruteForceProtection(action=publicLinkAuth)
170
+     *
171
+     * Authenticates against password-protected shares
172
+     * @param string $token
173
+     * @param string $password
174
+     * @return RedirectResponse|TemplateResponse|NotFoundResponse
175
+     */
176
+    public function authenticate($token, $password = '') {
177
+
178
+        // Check whether share exists
179
+        try {
180
+            $share = $this->shareManager->getShareByToken($token);
181
+        } catch (ShareNotFound $e) {
182
+            return new NotFoundResponse();
183
+        }
184
+
185
+        $authenticate = $this->linkShareAuth($share, $password);
186
+
187
+        if($authenticate === true) {
188
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
189
+        }
190
+
191
+        $response = new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest');
192
+        $response->throttle();
193
+        return $response;
194
+    }
195
+
196
+    /**
197
+     * Authenticate a link item with the given password.
198
+     * Or use the session if no password is provided.
199
+     *
200
+     * This is a modified version of Helper::authenticate
201
+     * TODO: Try to merge back eventually with Helper::authenticate
202
+     *
203
+     * @param \OCP\Share\IShare $share
204
+     * @param string|null $password
205
+     * @return bool
206
+     */
207
+    private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
208
+        if ($password !== null) {
209
+            if ($this->shareManager->checkPassword($share, $password)) {
210
+                $this->session->set('public_link_authenticated', (string)$share->getId());
211
+            } else {
212
+                $this->emitAccessShareHook($share, 403, 'Wrong password');
213
+                return false;
214
+            }
215
+        } else {
216
+            // not authenticated ?
217
+            if ( ! $this->session->exists('public_link_authenticated')
218
+                || $this->session->get('public_link_authenticated') !== (string)$share->getId()) {
219
+                return false;
220
+            }
221
+        }
222
+        return true;
223
+    }
224
+
225
+    /**
226
+     * throws hooks when a share is attempted to be accessed
227
+     *
228
+     * @param \OCP\Share\IShare|string $share the Share instance if available,
229
+     * otherwise token
230
+     * @param int $errorCode
231
+     * @param string $errorMessage
232
+     * @throws \OC\HintException
233
+     * @throws \OC\ServerNotAvailableException
234
+     */
235
+    protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
236
+        $itemType = $itemSource = $uidOwner = '';
237
+        $token = $share;
238
+        $exception = null;
239
+        if($share instanceof \OCP\Share\IShare) {
240
+            try {
241
+                $token = $share->getToken();
242
+                $uidOwner = $share->getSharedBy();
243
+                $itemType = $share->getNodeType();
244
+                $itemSource = $share->getNodeId();
245
+            } catch (\Exception $e) {
246
+                // we log what we know and pass on the exception afterwards
247
+                $exception = $e;
248
+            }
249
+        }
250
+        \OC_Hook::emit(Share::class, 'share_link_access', [
251
+            'itemType' => $itemType,
252
+            'itemSource' => $itemSource,
253
+            'uidOwner' => $uidOwner,
254
+            'token' => $token,
255
+            'errorCode' => $errorCode,
256
+            'errorMessage' => $errorMessage,
257
+        ]);
258
+        if(!is_null($exception)) {
259
+            throw $exception;
260
+        }
261
+    }
262
+
263
+    /**
264
+     * Validate the permissions of the share
265
+     *
266
+     * @param Share\IShare $share
267
+     * @return bool
268
+     */
269
+    private function validateShare(\OCP\Share\IShare $share) {
270
+        return $share->getNode()->isReadable() && $share->getNode()->isShareable();
271
+    }
272
+
273
+    /**
274
+     * @PublicPage
275
+     * @NoCSRFRequired
276
+     *
277
+     * @param string $token
278
+     * @param string $path
279
+     * @return TemplateResponse|RedirectResponse|NotFoundResponse
280
+     * @throws NotFoundException
281
+     * @throws \Exception
282
+     */
283
+    public function showShare($token, $path = '') {
284
+        \OC_User::setIncognitoMode(true);
285
+
286
+        // Check whether share exists
287
+        try {
288
+            $share = $this->shareManager->getShareByToken($token);
289
+        } catch (ShareNotFound $e) {
290
+            $this->emitAccessShareHook($token, 404, 'Share not found');
291
+            return new NotFoundResponse();
292
+        }
293
+
294
+        // Share is password protected - check whether the user is permitted to access the share
295
+        if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
296
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
297
+                array('token' => $token)));
298
+        }
299
+
300
+        if (!$this->validateShare($share)) {
301
+            throw new NotFoundException();
302
+        }
303
+        // We can't get the path of a file share
304
+        try {
305
+            if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
306
+                $this->emitAccessShareHook($share, 404, 'Share not found');
307
+                throw new NotFoundException();
308
+            }
309
+        } catch (\Exception $e) {
310
+            $this->emitAccessShareHook($share, 404, 'Share not found');
311
+            throw $e;
312
+        }
313
+
314
+        $shareTmpl = [];
315
+        $shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
316
+        $shareTmpl['owner'] = $share->getShareOwner();
317
+        $shareTmpl['filename'] = $share->getNode()->getName();
318
+        $shareTmpl['directory_path'] = $share->getTarget();
319
+        $shareTmpl['mimetype'] = $share->getNode()->getMimetype();
320
+        $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
321
+        $shareTmpl['dirToken'] = $token;
322
+        $shareTmpl['sharingToken'] = $token;
323
+        $shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
324
+        $shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
325
+        $shareTmpl['dir'] = '';
326
+        $shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
327
+        $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
328
+
329
+        // Show file list
330
+        $hideFileList = false;
331
+        if ($share->getNode() instanceof \OCP\Files\Folder) {
332
+            /** @var \OCP\Files\Folder $rootFolder */
333
+            $rootFolder = $share->getNode();
334
+
335
+            try {
336
+                $folderNode = $rootFolder->get($path);
337
+            } catch (\OCP\Files\NotFoundException $e) {
338
+                $this->emitAccessShareHook($share, 404, 'Share not found');
339
+                throw new NotFoundException();
340
+            }
341
+
342
+            $shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
343
+
344
+            /*
345 345
 			 * The OC_Util methods require a view. This just uses the node API
346 346
 			 */
347
-			$freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
348
-			if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
349
-				$freeSpace = max($freeSpace, 0);
350
-			} else {
351
-				$freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
352
-			}
353
-
354
-			$hideFileList = !($share->getPermissions() & \OCP\Constants::PERMISSION_READ);
355
-			$maxUploadFilesize = $freeSpace;
356
-
357
-			$folder = new Template('files', 'list', '');
358
-			$folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
359
-			$folder->assign('dirToken', $token);
360
-			$folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
361
-			$folder->assign('isPublic', true);
362
-			$folder->assign('hideFileList', $hideFileList);
363
-			$folder->assign('publicUploadEnabled', 'no');
364
-			$folder->assign('uploadMaxFilesize', $maxUploadFilesize);
365
-			$folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
366
-			$folder->assign('freeSpace', $freeSpace);
367
-			$folder->assign('usedSpacePercent', 0);
368
-			$folder->assign('trash', false);
369
-			$shareTmpl['folder'] = $folder->fetchPage();
370
-		}
371
-
372
-		$shareTmpl['hideFileList'] = $hideFileList;
373
-		$shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
374
-		$shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $token]);
375
-		$shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $token]);
376
-		$shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
377
-		$shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
378
-		$shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
379
-		$shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
380
-		$shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
381
-		$shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
382
-		$ogPreview = '';
383
-		if ($shareTmpl['previewSupported']) {
384
-			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
385
-				['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 't' => $shareTmpl['dirToken']]);
386
-			$ogPreview = $shareTmpl['previewImage'];
387
-
388
-			// We just have direct previews for image files
389
-			if ($share->getNode()->getMimePart() === 'image') {
390
-				$shareTmpl['previewURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $token]);
391
-				$ogPreview = $shareTmpl['previewURL'];
392
-			}
393
-		} else {
394
-			$shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
395
-			$ogPreview = $shareTmpl['previewImage'];
396
-		}
397
-
398
-		// Load files we need
399
-		\OCP\Util::addScript('files', 'file-upload');
400
-		\OCP\Util::addStyle('files_sharing', 'publicView');
401
-		\OCP\Util::addScript('files_sharing', 'public');
402
-		\OCP\Util::addScript('files', 'fileactions');
403
-		\OCP\Util::addScript('files', 'fileactionsmenu');
404
-		\OCP\Util::addScript('files', 'jquery.fileupload');
405
-		\OCP\Util::addScript('files_sharing', 'files_drop');
406
-
407
-		if (isset($shareTmpl['folder'])) {
408
-			// JS required for folders
409
-			\OCP\Util::addStyle('files', 'merged');
410
-			\OCP\Util::addScript('files', 'filesummary');
411
-			\OCP\Util::addScript('files', 'breadcrumb');
412
-			\OCP\Util::addScript('files', 'fileinfomodel');
413
-			\OCP\Util::addScript('files', 'newfilemenu');
414
-			\OCP\Util::addScript('files', 'files');
415
-			\OCP\Util::addScript('files', 'filelist');
416
-			\OCP\Util::addScript('files', 'keyboardshortcuts');
417
-		}
418
-
419
-		// OpenGraph Support: http://ogp.me/
420
-		\OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
421
-		\OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
422
-		\OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
423
-		\OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
424
-		\OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
425
-		\OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $ogPreview]);
426
-
427
-		$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
428
-
429
-		$csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
430
-		$csp->addAllowedFrameDomain('\'self\'');
431
-
432
-		$response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl);
433
-		$response->setHeaderTitle($shareTmpl['filename']);
434
-		$response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']]));
435
-		$response->setHeaderActions([
436
-			new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0),
437
-			new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']),
438
-			new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']),
439
-			new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']),
440
-		]);
441
-
442
-		$response->setContentSecurityPolicy($csp);
443
-
444
-		$this->emitAccessShareHook($share);
445
-
446
-		return $response;
447
-	}
448
-
449
-	/**
450
-	 * @PublicPage
451
-	 * @NoCSRFRequired
452
-	 *
453
-	 * @param string $token
454
-	 * @param string $files
455
-	 * @param string $path
456
-	 * @param string $downloadStartSecret
457
-	 * @return void|\OCP\AppFramework\Http\Response
458
-	 * @throws NotFoundException
459
-	 */
460
-	public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
461
-		\OC_User::setIncognitoMode(true);
462
-
463
-		$share = $this->shareManager->getShareByToken($token);
464
-
465
-		if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
466
-			return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
467
-		}
468
-
469
-		// Share is password protected - check whether the user is permitted to access the share
470
-		if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
471
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
472
-				['token' => $token]));
473
-		}
474
-
475
-		$files_list = null;
476
-		if (!is_null($files)) { // download selected files
477
-			$files_list = json_decode($files);
478
-			// in case we get only a single file
479
-			if ($files_list === null) {
480
-				$files_list = [$files];
481
-			}
482
-			// Just in case $files is a single int like '1234'
483
-			if (!is_array($files_list)) {
484
-				$files_list = [$files_list];
485
-			}
486
-		}
487
-
488
-		$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
489
-		$originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
490
-
491
-		if (!$this->validateShare($share)) {
492
-			throw new NotFoundException();
493
-		}
494
-
495
-		// Single file share
496
-		if ($share->getNode() instanceof \OCP\Files\File) {
497
-			// Single file download
498
-			$this->singleFileDownloaded($share, $share->getNode());
499
-		}
500
-		// Directory share
501
-		else {
502
-			/** @var \OCP\Files\Folder $node */
503
-			$node = $share->getNode();
504
-
505
-			// Try to get the path
506
-			if ($path !== '') {
507
-				try {
508
-					$node = $node->get($path);
509
-				} catch (NotFoundException $e) {
510
-					$this->emitAccessShareHook($share, 404, 'Share not found');
511
-					return new NotFoundResponse();
512
-				}
513
-			}
514
-
515
-			$originalSharePath = $userFolder->getRelativePath($node->getPath());
516
-
517
-			if ($node instanceof \OCP\Files\File) {
518
-				// Single file download
519
-				$this->singleFileDownloaded($share, $share->getNode());
520
-			} else if (!empty($files_list)) {
521
-				$this->fileListDownloaded($share, $files_list, $node);
522
-			} else {
523
-				// The folder is downloaded
524
-				$this->singleFileDownloaded($share, $share->getNode());
525
-			}
526
-		}
527
-
528
-		/* FIXME: We should do this all nicely in OCP */
529
-		OC_Util::tearDownFS();
530
-		OC_Util::setupFS($share->getShareOwner());
531
-
532
-		/**
533
-		 * this sets a cookie to be able to recognize the start of the download
534
-		 * the content must not be longer than 32 characters and must only contain
535
-		 * alphanumeric characters
536
-		 */
537
-		if (!empty($downloadStartSecret)
538
-			&& !isset($downloadStartSecret[32])
539
-			&& preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
540
-
541
-			// FIXME: set on the response once we use an actual app framework response
542
-			setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
543
-		}
544
-
545
-		$this->emitAccessShareHook($share);
546
-
547
-		$server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
548
-
549
-		/**
550
-		 * Http range requests support
551
-		 */
552
-		if (isset($_SERVER['HTTP_RANGE'])) {
553
-			$server_params['range'] = $this->request->getHeader('Range');
554
-		}
555
-
556
-		// download selected files
557
-		if (!is_null($files) && $files !== '') {
558
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
559
-			// after dispatching the request which results in a "Cannot modify header information" notice.
560
-			OC_Files::get($originalSharePath, $files_list, $server_params);
561
-			exit();
562
-		} else {
563
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
564
-			// after dispatching the request which results in a "Cannot modify header information" notice.
565
-			OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
566
-			exit();
567
-		}
568
-	}
569
-
570
-	/**
571
-	 * create activity for every downloaded file
572
-	 *
573
-	 * @param Share\IShare $share
574
-	 * @param array $files_list
575
-	 * @param \OCP\Files\Folder $node
576
-	 */
577
-	protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
578
-		foreach ($files_list as $file) {
579
-			$subNode = $node->get($file);
580
-			$this->singleFileDownloaded($share, $subNode);
581
-		}
582
-
583
-	}
584
-
585
-	/**
586
-	 * create activity if a single file was downloaded from a link share
587
-	 *
588
-	 * @param Share\IShare $share
589
-	 */
590
-	protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
591
-
592
-		$fileId = $node->getId();
593
-
594
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
595
-		$userNodeList = $userFolder->getById($fileId);
596
-		$userNode = $userNodeList[0];
597
-		$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
598
-		$userPath = $userFolder->getRelativePath($userNode->getPath());
599
-		$ownerPath = $ownerFolder->getRelativePath($node->getPath());
600
-
601
-		$parameters = [$userPath];
602
-
603
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
604
-			if ($node instanceof \OCP\Files\File) {
605
-				$subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
606
-			} else {
607
-				$subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
608
-			}
609
-			$parameters[] = $share->getSharedWith();
610
-		} else {
611
-			if ($node instanceof \OCP\Files\File) {
612
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
613
-			} else {
614
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
615
-			}
616
-		}
617
-
618
-		$this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
619
-
620
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
621
-			$parameters[0] = $ownerPath;
622
-			$this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
623
-		}
624
-	}
625
-
626
-	/**
627
-	 * publish activity
628
-	 *
629
-	 * @param string $subject
630
-	 * @param array $parameters
631
-	 * @param string $affectedUser
632
-	 * @param int $fileId
633
-	 * @param string $filePath
634
-	 */
635
-	protected function publishActivity($subject,
636
-										array $parameters,
637
-										$affectedUser,
638
-										$fileId,
639
-										$filePath) {
640
-
641
-		$event = $this->activityManager->generateEvent();
642
-		$event->setApp('files_sharing')
643
-			->setType('public_links')
644
-			->setSubject($subject, $parameters)
645
-			->setAffectedUser($affectedUser)
646
-			->setObject('files', $fileId, $filePath);
647
-		$this->activityManager->publish($event);
648
-	}
347
+            $freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
348
+            if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
349
+                $freeSpace = max($freeSpace, 0);
350
+            } else {
351
+                $freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
352
+            }
353
+
354
+            $hideFileList = !($share->getPermissions() & \OCP\Constants::PERMISSION_READ);
355
+            $maxUploadFilesize = $freeSpace;
356
+
357
+            $folder = new Template('files', 'list', '');
358
+            $folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
359
+            $folder->assign('dirToken', $token);
360
+            $folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
361
+            $folder->assign('isPublic', true);
362
+            $folder->assign('hideFileList', $hideFileList);
363
+            $folder->assign('publicUploadEnabled', 'no');
364
+            $folder->assign('uploadMaxFilesize', $maxUploadFilesize);
365
+            $folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
366
+            $folder->assign('freeSpace', $freeSpace);
367
+            $folder->assign('usedSpacePercent', 0);
368
+            $folder->assign('trash', false);
369
+            $shareTmpl['folder'] = $folder->fetchPage();
370
+        }
371
+
372
+        $shareTmpl['hideFileList'] = $hideFileList;
373
+        $shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
374
+        $shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $token]);
375
+        $shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $token]);
376
+        $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
377
+        $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
378
+        $shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
379
+        $shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
380
+        $shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
381
+        $shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
382
+        $ogPreview = '';
383
+        if ($shareTmpl['previewSupported']) {
384
+            $shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
385
+                ['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 't' => $shareTmpl['dirToken']]);
386
+            $ogPreview = $shareTmpl['previewImage'];
387
+
388
+            // We just have direct previews for image files
389
+            if ($share->getNode()->getMimePart() === 'image') {
390
+                $shareTmpl['previewURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $token]);
391
+                $ogPreview = $shareTmpl['previewURL'];
392
+            }
393
+        } else {
394
+            $shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
395
+            $ogPreview = $shareTmpl['previewImage'];
396
+        }
397
+
398
+        // Load files we need
399
+        \OCP\Util::addScript('files', 'file-upload');
400
+        \OCP\Util::addStyle('files_sharing', 'publicView');
401
+        \OCP\Util::addScript('files_sharing', 'public');
402
+        \OCP\Util::addScript('files', 'fileactions');
403
+        \OCP\Util::addScript('files', 'fileactionsmenu');
404
+        \OCP\Util::addScript('files', 'jquery.fileupload');
405
+        \OCP\Util::addScript('files_sharing', 'files_drop');
406
+
407
+        if (isset($shareTmpl['folder'])) {
408
+            // JS required for folders
409
+            \OCP\Util::addStyle('files', 'merged');
410
+            \OCP\Util::addScript('files', 'filesummary');
411
+            \OCP\Util::addScript('files', 'breadcrumb');
412
+            \OCP\Util::addScript('files', 'fileinfomodel');
413
+            \OCP\Util::addScript('files', 'newfilemenu');
414
+            \OCP\Util::addScript('files', 'files');
415
+            \OCP\Util::addScript('files', 'filelist');
416
+            \OCP\Util::addScript('files', 'keyboardshortcuts');
417
+        }
418
+
419
+        // OpenGraph Support: http://ogp.me/
420
+        \OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
421
+        \OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
422
+        \OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
423
+        \OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
424
+        \OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
425
+        \OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $ogPreview]);
426
+
427
+        $this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
428
+
429
+        $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
430
+        $csp->addAllowedFrameDomain('\'self\'');
431
+
432
+        $response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl);
433
+        $response->setHeaderTitle($shareTmpl['filename']);
434
+        $response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']]));
435
+        $response->setHeaderActions([
436
+            new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0),
437
+            new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']),
438
+            new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']),
439
+            new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']),
440
+        ]);
441
+
442
+        $response->setContentSecurityPolicy($csp);
443
+
444
+        $this->emitAccessShareHook($share);
445
+
446
+        return $response;
447
+    }
448
+
449
+    /**
450
+     * @PublicPage
451
+     * @NoCSRFRequired
452
+     *
453
+     * @param string $token
454
+     * @param string $files
455
+     * @param string $path
456
+     * @param string $downloadStartSecret
457
+     * @return void|\OCP\AppFramework\Http\Response
458
+     * @throws NotFoundException
459
+     */
460
+    public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
461
+        \OC_User::setIncognitoMode(true);
462
+
463
+        $share = $this->shareManager->getShareByToken($token);
464
+
465
+        if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
466
+            return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
467
+        }
468
+
469
+        // Share is password protected - check whether the user is permitted to access the share
470
+        if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
471
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
472
+                ['token' => $token]));
473
+        }
474
+
475
+        $files_list = null;
476
+        if (!is_null($files)) { // download selected files
477
+            $files_list = json_decode($files);
478
+            // in case we get only a single file
479
+            if ($files_list === null) {
480
+                $files_list = [$files];
481
+            }
482
+            // Just in case $files is a single int like '1234'
483
+            if (!is_array($files_list)) {
484
+                $files_list = [$files_list];
485
+            }
486
+        }
487
+
488
+        $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
489
+        $originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
490
+
491
+        if (!$this->validateShare($share)) {
492
+            throw new NotFoundException();
493
+        }
494
+
495
+        // Single file share
496
+        if ($share->getNode() instanceof \OCP\Files\File) {
497
+            // Single file download
498
+            $this->singleFileDownloaded($share, $share->getNode());
499
+        }
500
+        // Directory share
501
+        else {
502
+            /** @var \OCP\Files\Folder $node */
503
+            $node = $share->getNode();
504
+
505
+            // Try to get the path
506
+            if ($path !== '') {
507
+                try {
508
+                    $node = $node->get($path);
509
+                } catch (NotFoundException $e) {
510
+                    $this->emitAccessShareHook($share, 404, 'Share not found');
511
+                    return new NotFoundResponse();
512
+                }
513
+            }
514
+
515
+            $originalSharePath = $userFolder->getRelativePath($node->getPath());
516
+
517
+            if ($node instanceof \OCP\Files\File) {
518
+                // Single file download
519
+                $this->singleFileDownloaded($share, $share->getNode());
520
+            } else if (!empty($files_list)) {
521
+                $this->fileListDownloaded($share, $files_list, $node);
522
+            } else {
523
+                // The folder is downloaded
524
+                $this->singleFileDownloaded($share, $share->getNode());
525
+            }
526
+        }
527
+
528
+        /* FIXME: We should do this all nicely in OCP */
529
+        OC_Util::tearDownFS();
530
+        OC_Util::setupFS($share->getShareOwner());
531
+
532
+        /**
533
+         * this sets a cookie to be able to recognize the start of the download
534
+         * the content must not be longer than 32 characters and must only contain
535
+         * alphanumeric characters
536
+         */
537
+        if (!empty($downloadStartSecret)
538
+            && !isset($downloadStartSecret[32])
539
+            && preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
540
+
541
+            // FIXME: set on the response once we use an actual app framework response
542
+            setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
543
+        }
544
+
545
+        $this->emitAccessShareHook($share);
546
+
547
+        $server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
548
+
549
+        /**
550
+         * Http range requests support
551
+         */
552
+        if (isset($_SERVER['HTTP_RANGE'])) {
553
+            $server_params['range'] = $this->request->getHeader('Range');
554
+        }
555
+
556
+        // download selected files
557
+        if (!is_null($files) && $files !== '') {
558
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
559
+            // after dispatching the request which results in a "Cannot modify header information" notice.
560
+            OC_Files::get($originalSharePath, $files_list, $server_params);
561
+            exit();
562
+        } else {
563
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
564
+            // after dispatching the request which results in a "Cannot modify header information" notice.
565
+            OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
566
+            exit();
567
+        }
568
+    }
569
+
570
+    /**
571
+     * create activity for every downloaded file
572
+     *
573
+     * @param Share\IShare $share
574
+     * @param array $files_list
575
+     * @param \OCP\Files\Folder $node
576
+     */
577
+    protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
578
+        foreach ($files_list as $file) {
579
+            $subNode = $node->get($file);
580
+            $this->singleFileDownloaded($share, $subNode);
581
+        }
582
+
583
+    }
584
+
585
+    /**
586
+     * create activity if a single file was downloaded from a link share
587
+     *
588
+     * @param Share\IShare $share
589
+     */
590
+    protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
591
+
592
+        $fileId = $node->getId();
593
+
594
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
595
+        $userNodeList = $userFolder->getById($fileId);
596
+        $userNode = $userNodeList[0];
597
+        $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
598
+        $userPath = $userFolder->getRelativePath($userNode->getPath());
599
+        $ownerPath = $ownerFolder->getRelativePath($node->getPath());
600
+
601
+        $parameters = [$userPath];
602
+
603
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
604
+            if ($node instanceof \OCP\Files\File) {
605
+                $subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
606
+            } else {
607
+                $subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
608
+            }
609
+            $parameters[] = $share->getSharedWith();
610
+        } else {
611
+            if ($node instanceof \OCP\Files\File) {
612
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
613
+            } else {
614
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
615
+            }
616
+        }
617
+
618
+        $this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
619
+
620
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
621
+            $parameters[0] = $ownerPath;
622
+            $this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
623
+        }
624
+    }
625
+
626
+    /**
627
+     * publish activity
628
+     *
629
+     * @param string $subject
630
+     * @param array $parameters
631
+     * @param string $affectedUser
632
+     * @param int $fileId
633
+     * @param string $filePath
634
+     */
635
+    protected function publishActivity($subject,
636
+                                        array $parameters,
637
+                                        $affectedUser,
638
+                                        $fileId,
639
+                                        $filePath) {
640
+
641
+        $event = $this->activityManager->generateEvent();
642
+        $event->setApp('files_sharing')
643
+            ->setType('public_links')
644
+            ->setSubject($subject, $parameters)
645
+            ->setAffectedUser($affectedUser)
646
+            ->setObject('files', $fileId, $filePath);
647
+        $this->activityManager->publish($event);
648
+    }
649 649
 
650 650
 
651 651
 }
Please login to merge, or discard this patch.
lib/public/AppFramework/Http/Template/SimpleMenuAction.php 2 patches
Indentation   +137 added lines, -137 removed lines patch added patch discarded remove patch
@@ -33,142 +33,142 @@
 block discarded – undo
33 33
  */
34 34
 class SimpleMenuAction implements IMenuAction {
35 35
 
36
-	/** @var string */
37
-	private $id;
38
-
39
-	/** @var string */
40
-	private $label;
41
-
42
-	/** @var string */
43
-	private $icon;
44
-
45
-	/** @var string */
46
-	private $link;
47
-
48
-	/** @var int */
49
-	private $priority;
50
-
51
-	/** @var string */
52
-	private $detail;
53
-
54
-	/**
55
-	 * SimpleMenuAction constructor.
56
-	 *
57
-	 * @param string $id
58
-	 * @param string $label
59
-	 * @param string $icon
60
-	 * @param string $link
61
-	 * @param int $priority
62
-	 * @param string $detail
63
-	 * @since 14.0.0
64
-	 */
65
-	public function __construct(string $id, string $label, string $icon, string $link = '', int $priority = 100, string $detail = '') {
66
-		$this->id = $id;
67
-		$this->label = $label;
68
-		$this->icon = $icon;
69
-		$this->link = $link;
70
-		$this->priority = $priority;
71
-		$this->detail = $detail;
72
-	}
73
-
74
-	/**
75
-	 * @param string $id
76
-	 * @since 14.0.0
77
-	 */
78
-	public function setId(string $id) {
79
-		$this->id = $id;
80
-	}
81
-
82
-	/**
83
-	 * @param string $label
84
-	 * @since 14.0.0
85
-	 */
86
-	public function setLabel(string $label) {
87
-		$this->label = $label;
88
-	}
89
-
90
-	/**
91
-	 * @param string $detail
92
-	 * @since 14.0.0
93
-	 */
94
-	public function setDetail(string $detail) {
95
-		$this->detail = $detail;
96
-	}
97
-
98
-	/**
99
-	 * @param string $icon
100
-	 * @since 14.0.0
101
-	 */
102
-	public function setIcon(string $icon) {
103
-		$this->icon = $icon;
104
-	}
105
-
106
-	/**
107
-	 * @param string $link
108
-	 * @since 14.0.0
109
-	 */
110
-	public function setLink(string $link) {
111
-		$this->link = $link;
112
-	}
113
-
114
-	/**
115
-	 * @param int $priority
116
-	 * @since 14.0.0
117
-	 */
118
-	public function setPriority(int $priority) {
119
-		$this->priority = $priority;
120
-	}
121
-
122
-	/**
123
-	 * @return string
124
-	 * @since 14.0.0
125
-	 */
126
-	public function getId(): string {
127
-		return $this->id;
128
-	}
129
-
130
-	/**
131
-	 * @return string
132
-	 * @since 14.0.0
133
-	 */
134
-	public function getLabel(): string {
135
-		return $this->label;
136
-	}
137
-
138
-	/**
139
-	 * @return string
140
-	 * @since 14.0.0
141
-	 */
142
-	public function getIcon(): string {
143
-		return $this->icon;
144
-	}
145
-
146
-	/**
147
-	 * @return string
148
-	 * @since 14.0.0
149
-	 */
150
-	public function getLink(): string {
151
-		return $this->link;
152
-	}
153
-
154
-	/**
155
-	 * @return int
156
-	 * @since 14.0.0
157
-	 */
158
-	public function getPriority(): int {
159
-		return $this->priority;
160
-	}
161
-
162
-	/**
163
-	 * @return string
164
-	 * @since 14.0.0
165
-	 */
166
-	public function render(): string {
167
-		$detailContent = ($this->detail !== '') ? '&nbsp;<span class="download-size">(' . Util::sanitizeHTML($this->detail) . ')</span>' : '';
168
-		return sprintf(
169
-			'<li id="%s"><a href="%s"><span class="icon %s"></span>%s %s</a></li>',
170
-			Util::sanitizeHTML($this->id), Util::sanitizeHTML($this->link), Util::sanitizeHTML($this->icon), Util::sanitizeHTML($this->label), $detailContent
171
-		);
172
-	}
36
+    /** @var string */
37
+    private $id;
38
+
39
+    /** @var string */
40
+    private $label;
41
+
42
+    /** @var string */
43
+    private $icon;
44
+
45
+    /** @var string */
46
+    private $link;
47
+
48
+    /** @var int */
49
+    private $priority;
50
+
51
+    /** @var string */
52
+    private $detail;
53
+
54
+    /**
55
+     * SimpleMenuAction constructor.
56
+     *
57
+     * @param string $id
58
+     * @param string $label
59
+     * @param string $icon
60
+     * @param string $link
61
+     * @param int $priority
62
+     * @param string $detail
63
+     * @since 14.0.0
64
+     */
65
+    public function __construct(string $id, string $label, string $icon, string $link = '', int $priority = 100, string $detail = '') {
66
+        $this->id = $id;
67
+        $this->label = $label;
68
+        $this->icon = $icon;
69
+        $this->link = $link;
70
+        $this->priority = $priority;
71
+        $this->detail = $detail;
72
+    }
73
+
74
+    /**
75
+     * @param string $id
76
+     * @since 14.0.0
77
+     */
78
+    public function setId(string $id) {
79
+        $this->id = $id;
80
+    }
81
+
82
+    /**
83
+     * @param string $label
84
+     * @since 14.0.0
85
+     */
86
+    public function setLabel(string $label) {
87
+        $this->label = $label;
88
+    }
89
+
90
+    /**
91
+     * @param string $detail
92
+     * @since 14.0.0
93
+     */
94
+    public function setDetail(string $detail) {
95
+        $this->detail = $detail;
96
+    }
97
+
98
+    /**
99
+     * @param string $icon
100
+     * @since 14.0.0
101
+     */
102
+    public function setIcon(string $icon) {
103
+        $this->icon = $icon;
104
+    }
105
+
106
+    /**
107
+     * @param string $link
108
+     * @since 14.0.0
109
+     */
110
+    public function setLink(string $link) {
111
+        $this->link = $link;
112
+    }
113
+
114
+    /**
115
+     * @param int $priority
116
+     * @since 14.0.0
117
+     */
118
+    public function setPriority(int $priority) {
119
+        $this->priority = $priority;
120
+    }
121
+
122
+    /**
123
+     * @return string
124
+     * @since 14.0.0
125
+     */
126
+    public function getId(): string {
127
+        return $this->id;
128
+    }
129
+
130
+    /**
131
+     * @return string
132
+     * @since 14.0.0
133
+     */
134
+    public function getLabel(): string {
135
+        return $this->label;
136
+    }
137
+
138
+    /**
139
+     * @return string
140
+     * @since 14.0.0
141
+     */
142
+    public function getIcon(): string {
143
+        return $this->icon;
144
+    }
145
+
146
+    /**
147
+     * @return string
148
+     * @since 14.0.0
149
+     */
150
+    public function getLink(): string {
151
+        return $this->link;
152
+    }
153
+
154
+    /**
155
+     * @return int
156
+     * @since 14.0.0
157
+     */
158
+    public function getPriority(): int {
159
+        return $this->priority;
160
+    }
161
+
162
+    /**
163
+     * @return string
164
+     * @since 14.0.0
165
+     */
166
+    public function render(): string {
167
+        $detailContent = ($this->detail !== '') ? '&nbsp;<span class="download-size">(' . Util::sanitizeHTML($this->detail) . ')</span>' : '';
168
+        return sprintf(
169
+            '<li id="%s"><a href="%s"><span class="icon %s"></span>%s %s</a></li>',
170
+            Util::sanitizeHTML($this->id), Util::sanitizeHTML($this->link), Util::sanitizeHTML($this->icon), Util::sanitizeHTML($this->label), $detailContent
171
+        );
172
+    }
173 173
 
174 174
 }
175 175
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -164,7 +164,7 @@
 block discarded – undo
164 164
 	 * @since 14.0.0
165 165
 	 */
166 166
 	public function render(): string {
167
-		$detailContent = ($this->detail !== '') ? '&nbsp;<span class="download-size">(' . Util::sanitizeHTML($this->detail) . ')</span>' : '';
167
+		$detailContent = ($this->detail !== '') ? '&nbsp;<span class="download-size">('.Util::sanitizeHTML($this->detail).')</span>' : '';
168 168
 		return sprintf(
169 169
 			'<li id="%s"><a href="%s"><span class="icon %s"></span>%s %s</a></li>',
170 170
 			Util::sanitizeHTML($this->id), Util::sanitizeHTML($this->link), Util::sanitizeHTML($this->icon), Util::sanitizeHTML($this->label), $detailContent
Please login to merge, or discard this patch.
lib/public/AppFramework/Http/Template/PublicTemplateResponse.php 1 patch
Indentation   +95 added lines, -95 removed lines patch added patch discarded remove patch
@@ -34,110 +34,110 @@
 block discarded – undo
34 34
  */
35 35
 class PublicTemplateResponse extends TemplateResponse {
36 36
 
37
-	private $headerTitle = '';
38
-	private $headerDetails = '';
39
-	private $headerActions = [];
37
+    private $headerTitle = '';
38
+    private $headerDetails = '';
39
+    private $headerActions = [];
40 40
 
41
-	/**
42
-	 * PublicTemplateResponse constructor.
43
-	 *
44
-	 * @param string $appName
45
-	 * @param string $templateName
46
-	 * @param array $params
47
-	 * @since 14.0.0
48
-	 */
49
-	public function __construct(string $appName, string $templateName, array $params = array()) {
50
-		parent::__construct($appName, $templateName, $params, 'public');
51
-		\OC_Util::addScript('core', 'public/publicpage');
52
-	}
41
+    /**
42
+     * PublicTemplateResponse constructor.
43
+     *
44
+     * @param string $appName
45
+     * @param string $templateName
46
+     * @param array $params
47
+     * @since 14.0.0
48
+     */
49
+    public function __construct(string $appName, string $templateName, array $params = array()) {
50
+        parent::__construct($appName, $templateName, $params, 'public');
51
+        \OC_Util::addScript('core', 'public/publicpage');
52
+    }
53 53
 
54
-	/**
55
-	 * @param string $title
56
-	 * @since 14.0.0
57
-	 */
58
-	public function setHeaderTitle(string $title) {
59
-		$this->headerTitle = $title;
60
-	}
54
+    /**
55
+     * @param string $title
56
+     * @since 14.0.0
57
+     */
58
+    public function setHeaderTitle(string $title) {
59
+        $this->headerTitle = $title;
60
+    }
61 61
 
62
-	/**
63
-	 * @return string
64
-	 * @since 14.0.0
65
-	 */
66
-	public function getHeaderTitle(): string {
67
-		return $this->headerTitle;
68
-	}
62
+    /**
63
+     * @return string
64
+     * @since 14.0.0
65
+     */
66
+    public function getHeaderTitle(): string {
67
+        return $this->headerTitle;
68
+    }
69 69
 
70
-	/**
71
-	 * @param string $details
72
-	 * @since 14.0.0
73
-	 */
74
-	public function setHeaderDetails(string $details) {
75
-		$this->headerDetails = $details;
76
-	}
70
+    /**
71
+     * @param string $details
72
+     * @since 14.0.0
73
+     */
74
+    public function setHeaderDetails(string $details) {
75
+        $this->headerDetails = $details;
76
+    }
77 77
 
78
-	/**
79
-	 * @return string
80
-	 * @since 14.0.0
81
-	 */
82
-	public function getHeaderDetails(): string {
83
-		return $this->headerDetails;
84
-	}
78
+    /**
79
+     * @return string
80
+     * @since 14.0.0
81
+     */
82
+    public function getHeaderDetails(): string {
83
+        return $this->headerDetails;
84
+    }
85 85
 
86
-	/**
87
-	 * @param array $actions
88
-	 * @since 14.0.0
89
-	 * @throws InvalidArgumentException
90
-	 */
91
-	public function setHeaderActions(array $actions) {
92
-		foreach ($actions as $action) {
93
-			if ($actions instanceof IMenuAction) {
94
-				throw new InvalidArgumentException('Actions must be of type IMenuAction');
95
-			}
96
-			$this->headerActions[] = $action;
97
-		}
98
-		usort($this->headerActions, function(IMenuAction $a, IMenuAction $b) {
99
-			return $a->getPriority() > $b->getPriority();
100
-		});
101
-	}
86
+    /**
87
+     * @param array $actions
88
+     * @since 14.0.0
89
+     * @throws InvalidArgumentException
90
+     */
91
+    public function setHeaderActions(array $actions) {
92
+        foreach ($actions as $action) {
93
+            if ($actions instanceof IMenuAction) {
94
+                throw new InvalidArgumentException('Actions must be of type IMenuAction');
95
+            }
96
+            $this->headerActions[] = $action;
97
+        }
98
+        usort($this->headerActions, function(IMenuAction $a, IMenuAction $b) {
99
+            return $a->getPriority() > $b->getPriority();
100
+        });
101
+    }
102 102
 
103
-	/**
104
-	 * @return IMenuAction
105
-	 * @since 14.0.0
106
-	 * @throws \Exception
107
-	 */
108
-	public function getPrimaryAction(): IMenuAction {
109
-		if ($this->getActionCount() > 0) {
110
-			return $this->headerActions[0];
111
-		}
112
-		throw new \Exception('No header actions have been set');
113
-	}
103
+    /**
104
+     * @return IMenuAction
105
+     * @since 14.0.0
106
+     * @throws \Exception
107
+     */
108
+    public function getPrimaryAction(): IMenuAction {
109
+        if ($this->getActionCount() > 0) {
110
+            return $this->headerActions[0];
111
+        }
112
+        throw new \Exception('No header actions have been set');
113
+    }
114 114
 
115
-	/**
116
-	 * @return int
117
-	 * @since 14.0.0
118
-	 */
119
-	public function getActionCount(): int {
120
-		return count($this->headerActions);
121
-	}
115
+    /**
116
+     * @return int
117
+     * @since 14.0.0
118
+     */
119
+    public function getActionCount(): int {
120
+        return count($this->headerActions);
121
+    }
122 122
 
123
-	/**
124
-	 * @return IMenuAction[]
125
-	 * @since 14.0.0
126
-	 */
127
-	public function getOtherActions(): array {
128
-		return array_slice($this->headerActions, 1);
129
-	}
123
+    /**
124
+     * @return IMenuAction[]
125
+     * @since 14.0.0
126
+     */
127
+    public function getOtherActions(): array {
128
+        return array_slice($this->headerActions, 1);
129
+    }
130 130
 
131
-	/**
132
-	 * @return string
133
-	 * @since 14.0.0
134
-	 */
135
-	public function render(): string {
136
-		$params = array_merge($this->getParams(), [
137
-			'template' => $this,
138
-		]);
139
-		$this->setParams($params);
140
-		return  parent::render();
141
-	}
131
+    /**
132
+     * @return string
133
+     * @since 14.0.0
134
+     */
135
+    public function render(): string {
136
+        $params = array_merge($this->getParams(), [
137
+            'template' => $this,
138
+        ]);
139
+        $this->setParams($params);
140
+        return  parent::render();
141
+    }
142 142
 
143 143
 }
144 144
\ No newline at end of file
Please login to merge, or discard this patch.