Completed
Pull Request — master (#8051)
by Julius
19:02
created
lib/private/Template/Base.php 1 patch
Indentation   +156 added lines, -156 removed lines patch added patch discarded remove patch
@@ -31,161 +31,161 @@
 block discarded – undo
31 31
 use OCP\Defaults;
32 32
 
33 33
 class Base {
34
-	private $template; // The template
35
-	private $vars; // Vars
36
-
37
-	/** @var \OCP\IL10N */
38
-	private $l10n;
39
-
40
-	/** @var Defaults */
41
-	private $theme;
42
-
43
-	/**
44
-	 * @param string $template
45
-	 * @param string $requestToken
46
-	 * @param \OCP\IL10N $l10n
47
-	 * @param Defaults $theme
48
-	 */
49
-	public function __construct($template, $requestToken, $l10n, $theme ) {
50
-		$this->vars = array();
51
-		$this->vars['requesttoken'] = $requestToken;
52
-		$this->l10n = $l10n;
53
-		$this->template = $template;
54
-		$this->theme = $theme;
55
-	}
56
-
57
-	/**
58
-	 * @param string $serverRoot
59
-	 * @param string|false $app_dir
60
-	 * @param string $theme
61
-	 * @param string $app
62
-	 * @return string[]
63
-	 */
64
-	protected function getAppTemplateDirs($theme, $app, $serverRoot, $app_dir) {
65
-		// Check if the app is in the app folder or in the root
66
-		if( file_exists($app_dir.'/templates/' )) {
67
-			return [
68
-				$serverRoot.'/themes/'.$theme.'/apps/'.$app.'/templates/',
69
-				$app_dir.'/templates/',
70
-			];
71
-		}
72
-		return [
73
-			$serverRoot.'/themes/'.$theme.'/'.$app.'/templates/',
74
-			$serverRoot.'/'.$app.'/templates/',
75
-		];
76
-	}
77
-
78
-	/**
79
-	 * @param string $serverRoot
80
-	 * @param string $theme
81
-	 * @return string[]
82
-	 */
83
-	protected function getCoreTemplateDirs($theme, $serverRoot) {
84
-		return [
85
-			$serverRoot.'/themes/'.$theme.'/core/templates/',
86
-			$serverRoot.'/core/templates/',
87
-		];
88
-	}
89
-
90
-	/**
91
-	 * Assign variables
92
-	 * @param string $key key
93
-	 * @param array|bool|integer|string $value value
94
-	 * @return bool
95
-	 *
96
-	 * This function assigns a variable. It can be accessed via $_[$key] in
97
-	 * the template.
98
-	 *
99
-	 * If the key existed before, it will be overwritten
100
-	 */
101
-	public function assign( $key, $value) {
102
-		$this->vars[$key] = $value;
103
-		return true;
104
-	}
105
-
106
-	/**
107
-	 * Appends a variable
108
-	 * @param string $key key
109
-	 * @param mixed $value value
110
-	 * @return boolean|null
111
-	 *
112
-	 * This function assigns a variable in an array context. If the key already
113
-	 * exists, the value will be appended. It can be accessed via
114
-	 * $_[$key][$position] in the template.
115
-	 */
116
-	public function append( $key, $value ) {
117
-		if( array_key_exists( $key, $this->vars )) {
118
-			$this->vars[$key][] = $value;
119
-		}
120
-		else{
121
-			$this->vars[$key] = array( $value );
122
-		}
123
-	}
124
-
125
-	/**
126
-	 * Prints the proceeded template
127
-	 * @return bool
128
-	 *
129
-	 * This function proceeds the template and prints its output.
130
-	 */
131
-	public function printPage() {
132
-		$data = $this->fetchPage();
133
-		if( $data === false ) {
134
-			return false;
135
-		}
136
-		else{
137
-			print $data;
138
-			return true;
139
-		}
140
-	}
141
-
142
-	/**
143
-	 * Process the template
144
-	 *
145
-	 * @param array|null $additionalParams
146
-	 * @return string This function processes the template.
147
-	 *
148
-	 * This function processes the template.
149
-	 */
150
-	public function fetchPage($additionalParams = null) {
151
-		return $this->load($this->template, $additionalParams);
152
-	}
153
-
154
-	/**
155
-	 * doing the actual work
156
-	 *
157
-	 * @param string $file
158
-	 * @param array|null $additionalParams
159
-	 * @return string content
160
-	 *
161
-	 * Includes the template file, fetches its output
162
-	 */
163
-	protected function load($file, $additionalParams = null) {
164
-		// Register the variables
165
-		$_ = $this->vars;
166
-		$l = $this->l10n;
167
-		$theme = $this->theme;
168
-
169
-		if(!is_null($additionalParams)) {
170
-			$_ = array_merge( $additionalParams, $this->vars );
171
-			foreach ($_ as $var => $value) {
172
-				${$var} = $value;
173
-			}
174
-		}
175
-
176
-		// Include
177
-		ob_start();
178
-		try {
179
-			include $file;
180
-			$data = ob_get_contents();
181
-		} catch (\Exception $e) {
182
-			@ob_end_clean();
183
-			throw $e;
184
-		}
185
-		@ob_end_clean();
186
-
187
-		// Return data
188
-		return $data;
189
-	}
34
+    private $template; // The template
35
+    private $vars; // Vars
36
+
37
+    /** @var \OCP\IL10N */
38
+    private $l10n;
39
+
40
+    /** @var Defaults */
41
+    private $theme;
42
+
43
+    /**
44
+     * @param string $template
45
+     * @param string $requestToken
46
+     * @param \OCP\IL10N $l10n
47
+     * @param Defaults $theme
48
+     */
49
+    public function __construct($template, $requestToken, $l10n, $theme ) {
50
+        $this->vars = array();
51
+        $this->vars['requesttoken'] = $requestToken;
52
+        $this->l10n = $l10n;
53
+        $this->template = $template;
54
+        $this->theme = $theme;
55
+    }
56
+
57
+    /**
58
+     * @param string $serverRoot
59
+     * @param string|false $app_dir
60
+     * @param string $theme
61
+     * @param string $app
62
+     * @return string[]
63
+     */
64
+    protected function getAppTemplateDirs($theme, $app, $serverRoot, $app_dir) {
65
+        // Check if the app is in the app folder or in the root
66
+        if( file_exists($app_dir.'/templates/' )) {
67
+            return [
68
+                $serverRoot.'/themes/'.$theme.'/apps/'.$app.'/templates/',
69
+                $app_dir.'/templates/',
70
+            ];
71
+        }
72
+        return [
73
+            $serverRoot.'/themes/'.$theme.'/'.$app.'/templates/',
74
+            $serverRoot.'/'.$app.'/templates/',
75
+        ];
76
+    }
77
+
78
+    /**
79
+     * @param string $serverRoot
80
+     * @param string $theme
81
+     * @return string[]
82
+     */
83
+    protected function getCoreTemplateDirs($theme, $serverRoot) {
84
+        return [
85
+            $serverRoot.'/themes/'.$theme.'/core/templates/',
86
+            $serverRoot.'/core/templates/',
87
+        ];
88
+    }
89
+
90
+    /**
91
+     * Assign variables
92
+     * @param string $key key
93
+     * @param array|bool|integer|string $value value
94
+     * @return bool
95
+     *
96
+     * This function assigns a variable. It can be accessed via $_[$key] in
97
+     * the template.
98
+     *
99
+     * If the key existed before, it will be overwritten
100
+     */
101
+    public function assign( $key, $value) {
102
+        $this->vars[$key] = $value;
103
+        return true;
104
+    }
105
+
106
+    /**
107
+     * Appends a variable
108
+     * @param string $key key
109
+     * @param mixed $value value
110
+     * @return boolean|null
111
+     *
112
+     * This function assigns a variable in an array context. If the key already
113
+     * exists, the value will be appended. It can be accessed via
114
+     * $_[$key][$position] in the template.
115
+     */
116
+    public function append( $key, $value ) {
117
+        if( array_key_exists( $key, $this->vars )) {
118
+            $this->vars[$key][] = $value;
119
+        }
120
+        else{
121
+            $this->vars[$key] = array( $value );
122
+        }
123
+    }
124
+
125
+    /**
126
+     * Prints the proceeded template
127
+     * @return bool
128
+     *
129
+     * This function proceeds the template and prints its output.
130
+     */
131
+    public function printPage() {
132
+        $data = $this->fetchPage();
133
+        if( $data === false ) {
134
+            return false;
135
+        }
136
+        else{
137
+            print $data;
138
+            return true;
139
+        }
140
+    }
141
+
142
+    /**
143
+     * Process the template
144
+     *
145
+     * @param array|null $additionalParams
146
+     * @return string This function processes the template.
147
+     *
148
+     * This function processes the template.
149
+     */
150
+    public function fetchPage($additionalParams = null) {
151
+        return $this->load($this->template, $additionalParams);
152
+    }
153
+
154
+    /**
155
+     * doing the actual work
156
+     *
157
+     * @param string $file
158
+     * @param array|null $additionalParams
159
+     * @return string content
160
+     *
161
+     * Includes the template file, fetches its output
162
+     */
163
+    protected function load($file, $additionalParams = null) {
164
+        // Register the variables
165
+        $_ = $this->vars;
166
+        $l = $this->l10n;
167
+        $theme = $this->theme;
168
+
169
+        if(!is_null($additionalParams)) {
170
+            $_ = array_merge( $additionalParams, $this->vars );
171
+            foreach ($_ as $var => $value) {
172
+                ${$var} = $value;
173
+            }
174
+        }
175
+
176
+        // Include
177
+        ob_start();
178
+        try {
179
+            include $file;
180
+            $data = ob_get_contents();
181
+        } catch (\Exception $e) {
182
+            @ob_end_clean();
183
+            throw $e;
184
+        }
185
+        @ob_end_clean();
186
+
187
+        // Return data
188
+        return $data;
189
+    }
190 190
 
191 191
 }
Please login to merge, or discard this patch.
lib/public/AppFramework/Http/TemplateResponse.php 1 patch
Indentation   +119 added lines, -119 removed lines patch added patch discarded remove patch
@@ -37,124 +37,124 @@
 block discarded – undo
37 37
  */
38 38
 class TemplateResponse extends Response {
39 39
 
40
-	/**
41
-	 * name of the template
42
-	 * @var string
43
-	 */
44
-	protected $templateName;
45
-
46
-	/**
47
-	 * parameters
48
-	 * @var array
49
-	 */
50
-	protected $params;
51
-
52
-	/**
53
-	 * rendering type (admin, user, blank)
54
-	 * @var string
55
-	 */
56
-	protected $renderAs;
57
-
58
-	/**
59
-	 * app name
60
-	 * @var string
61
-	 */
62
-	protected $appName;
63
-
64
-	/**
65
-	 * constructor of TemplateResponse
66
-	 * @param string $appName the name of the app to load the template from
67
-	 * @param string $templateName the name of the template
68
-	 * @param array $params an array of parameters which should be passed to the
69
-	 * template
70
-	 * @param string $renderAs how the page should be rendered, defaults to user
71
-	 * @since 6.0.0 - parameters $params and $renderAs were added in 7.0.0
72
-	 */
73
-	public function __construct($appName, $templateName, array $params=array(),
74
-	                            $renderAs='user') {
75
-		$this->templateName = $templateName;
76
-		$this->appName = $appName;
77
-		$this->params = $params;
78
-		$this->renderAs = $renderAs;
79
-	}
80
-
81
-
82
-	/**
83
-	 * Sets template parameters
84
-	 * @param array $params an array with key => value structure which sets template
85
-	 *                      variables
86
-	 * @return TemplateResponse Reference to this object
87
-	 * @since 6.0.0 - return value was added in 7.0.0
88
-	 */
89
-	public function setParams(array $params){
90
-		$this->params = $params;
91
-
92
-		return $this;
93
-	}
94
-
95
-
96
-	/**
97
-	 * Used for accessing the set parameters
98
-	 * @return array the params
99
-	 * @since 6.0.0
100
-	 */
101
-	public function getParams(){
102
-		return $this->params;
103
-	}
104
-
105
-
106
-	/**
107
-	 * Used for accessing the name of the set template
108
-	 * @return string the name of the used template
109
-	 * @since 6.0.0
110
-	 */
111
-	public function getTemplateName(){
112
-		return $this->templateName;
113
-	}
114
-
115
-
116
-	/**
117
-	 * Sets the template page
118
-	 * @param string $renderAs admin, user or blank. Admin also prints the admin
119
-	 *                         settings header and footer, user renders the normal
120
-	 *                         normal page including footer and header and blank
121
-	 *                         just renders the plain template
122
-	 * @return TemplateResponse Reference to this object
123
-	 * @since 6.0.0 - return value was added in 7.0.0
124
-	 */
125
-	public function renderAs($renderAs){
126
-		$this->renderAs = $renderAs;
127
-
128
-		return $this;
129
-	}
130
-
131
-
132
-	/**
133
-	 * Returns the set renderAs
134
-	 * @return string the renderAs value
135
-	 * @since 6.0.0
136
-	 */
137
-	public function getRenderAs(){
138
-		return $this->renderAs;
139
-	}
140
-
141
-
142
-	/**
143
-	 * Returns the rendered html
144
-	 * @return string the rendered html
145
-	 * @since 6.0.0
146
-	 */
147
-	public function render(){
148
-		// \OCP\Template needs an empty string instead of 'blank' for an unwrapped response
149
-		$renderAs = $this->renderAs === 'blank' ? '' : $this->renderAs;
150
-
151
-		$template = new \OCP\Template($this->appName, $this->templateName, $renderAs);
152
-
153
-		foreach($this->params as $key => $value){
154
-			$template->assign($key, $value);
155
-		}
156
-
157
-		return $template->fetchPage($this->params);
158
-	}
40
+    /**
41
+     * name of the template
42
+     * @var string
43
+     */
44
+    protected $templateName;
45
+
46
+    /**
47
+     * parameters
48
+     * @var array
49
+     */
50
+    protected $params;
51
+
52
+    /**
53
+     * rendering type (admin, user, blank)
54
+     * @var string
55
+     */
56
+    protected $renderAs;
57
+
58
+    /**
59
+     * app name
60
+     * @var string
61
+     */
62
+    protected $appName;
63
+
64
+    /**
65
+     * constructor of TemplateResponse
66
+     * @param string $appName the name of the app to load the template from
67
+     * @param string $templateName the name of the template
68
+     * @param array $params an array of parameters which should be passed to the
69
+     * template
70
+     * @param string $renderAs how the page should be rendered, defaults to user
71
+     * @since 6.0.0 - parameters $params and $renderAs were added in 7.0.0
72
+     */
73
+    public function __construct($appName, $templateName, array $params=array(),
74
+                                $renderAs='user') {
75
+        $this->templateName = $templateName;
76
+        $this->appName = $appName;
77
+        $this->params = $params;
78
+        $this->renderAs = $renderAs;
79
+    }
80
+
81
+
82
+    /**
83
+     * Sets template parameters
84
+     * @param array $params an array with key => value structure which sets template
85
+     *                      variables
86
+     * @return TemplateResponse Reference to this object
87
+     * @since 6.0.0 - return value was added in 7.0.0
88
+     */
89
+    public function setParams(array $params){
90
+        $this->params = $params;
91
+
92
+        return $this;
93
+    }
94
+
95
+
96
+    /**
97
+     * Used for accessing the set parameters
98
+     * @return array the params
99
+     * @since 6.0.0
100
+     */
101
+    public function getParams(){
102
+        return $this->params;
103
+    }
104
+
105
+
106
+    /**
107
+     * Used for accessing the name of the set template
108
+     * @return string the name of the used template
109
+     * @since 6.0.0
110
+     */
111
+    public function getTemplateName(){
112
+        return $this->templateName;
113
+    }
114
+
115
+
116
+    /**
117
+     * Sets the template page
118
+     * @param string $renderAs admin, user or blank. Admin also prints the admin
119
+     *                         settings header and footer, user renders the normal
120
+     *                         normal page including footer and header and blank
121
+     *                         just renders the plain template
122
+     * @return TemplateResponse Reference to this object
123
+     * @since 6.0.0 - return value was added in 7.0.0
124
+     */
125
+    public function renderAs($renderAs){
126
+        $this->renderAs = $renderAs;
127
+
128
+        return $this;
129
+    }
130
+
131
+
132
+    /**
133
+     * Returns the set renderAs
134
+     * @return string the renderAs value
135
+     * @since 6.0.0
136
+     */
137
+    public function getRenderAs(){
138
+        return $this->renderAs;
139
+    }
140
+
141
+
142
+    /**
143
+     * Returns the rendered html
144
+     * @return string the rendered html
145
+     * @since 6.0.0
146
+     */
147
+    public function render(){
148
+        // \OCP\Template needs an empty string instead of 'blank' for an unwrapped response
149
+        $renderAs = $this->renderAs === 'blank' ? '' : $this->renderAs;
150
+
151
+        $template = new \OCP\Template($this->appName, $this->templateName, $renderAs);
152
+
153
+        foreach($this->params as $key => $value){
154
+            $template->assign($key, $value);
155
+        }
156
+
157
+        return $template->fetchPage($this->params);
158
+    }
159 159
 
160 160
 }
Please login to merge, or discard this patch.
lib/public/AppFramework/Http/Template/IMenuAction.php 1 patch
Indentation   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -31,34 +31,34 @@
 block discarded – undo
31 31
  */
32 32
 interface IMenuAction {
33 33
 
34
-	/**
35
-	 * @since 14.0.0
36
-	 * @return string
37
-	 */
38
-	public function getId(): string;
34
+    /**
35
+     * @since 14.0.0
36
+     * @return string
37
+     */
38
+    public function getId(): string;
39 39
 
40
-	/**
41
-	 * @since 14.0.0
42
-	 * @return string
43
-	 */
44
-	public function getLabel(): string;
40
+    /**
41
+     * @since 14.0.0
42
+     * @return string
43
+     */
44
+    public function getLabel(): string;
45 45
 
46
-	/**
47
-	 * @since 14.0.0
48
-	 * @return string
49
-	 */
50
-	public function getLink(): string;
46
+    /**
47
+     * @since 14.0.0
48
+     * @return string
49
+     */
50
+    public function getLink(): string;
51 51
 
52
-	/**
53
-	 * @since 14.0.0
54
-	 * @return int
55
-	 */
56
-	public function getPriority(): int;
52
+    /**
53
+     * @since 14.0.0
54
+     * @return int
55
+     */
56
+    public function getPriority(): int;
57 57
 
58
-	/**
59
-	 * @since 14.0.0
60
-	 * @return string
61
-	 */
62
-	public function render(): string;
58
+    /**
59
+     * @since 14.0.0
60
+     * @return string
61
+     */
62
+    public function render(): string;
63 63
 
64 64
 }
65 65
\ No newline at end of file
Please login to merge, or discard this patch.
core/templates/layout.public.php 1 patch
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -4,9 +4,9 @@  discard block
 block discarded – undo
4 4
 	<meta charset="utf-8">
5 5
 	<title>
6 6
 		<?php
7
-		p(!empty($_['application'])?$_['application'].' - ':'');
8
-		p($theme->getTitle());
9
-		?>
7
+        p(!empty($_['application'])?$_['application'].' - ':'');
8
+        p($theme->getTitle());
9
+        ?>
10 10
 	</title>
11 11
 	<meta http-equiv="X-UA-Compatible" content="IE=edge">
12 12
 	<meta name="referrer" content="never">
@@ -42,11 +42,11 @@  discard block
 block discarded – undo
42 42
 		</div>
43 43
 
44 44
 		<?php
45
-		/** @var \OCP\AppFramework\Http\Template\PublicTemplateResponse $template */
46
-		if($template->getActionCount() !== 0) {
47
-			$primary = $template->getPrimaryAction();
48
-			$others = $template->getOtherActions();
49
-			?>
45
+        /** @var \OCP\AppFramework\Http\Template\PublicTemplateResponse $template */
46
+        if($template->getActionCount() !== 0) {
47
+            $primary = $template->getPrimaryAction();
48
+            $others = $template->getOtherActions();
49
+            ?>
50 50
 		<div class="header-right">
51 51
 			<span id="header-primary-action" class="<?php if($template->getActionCount() === 1) {  p($primary->getIcon()); } ?>">
52 52
 				<a href="<?php p($primary->getLink()); ?>">
@@ -58,11 +58,11 @@  discard block
 block discarded – undo
58 58
 			<div id="share-menu" class="popovermenu menu">
59 59
 				<ul>
60 60
 					<?php
61
-						/** @var \OCP\AppFramework\Http\Template\IMenuAction $action */
62
-						foreach($template->getOtherActions() as $action) {
63
-							print_unescaped($action->render());
64
-						}
65
-					?>
61
+                        /** @var \OCP\AppFramework\Http\Template\IMenuAction $action */
62
+                        foreach($template->getOtherActions() as $action) {
63
+                            print_unescaped($action->render());
64
+                        }
65
+                    ?>
66 66
 				</ul>
67 67
 			</div>
68 68
 			<?php } ?>
Please login to merge, or discard this patch.
apps/files_sharing/lib/Template/LinkMenuAction.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -28,27 +28,27 @@
 block discarded – undo
28 28
 
29 29
 class LinkMenuAction extends SimpleMenuAction {
30 30
 
31
-	/**
32
-	 * LinkMenuAction constructor.
33
-	 *
34
-	 * @param string $label
35
-	 * @param string $icon
36
-	 * @param string $link
37
-	 */
38
-	public function __construct(string $label, string $icon, string $link) {
39
-		parent::__construct('directLink-container', $label, $icon, $link);
40
-	}
31
+    /**
32
+     * LinkMenuAction constructor.
33
+     *
34
+     * @param string $label
35
+     * @param string $icon
36
+     * @param string $link
37
+     */
38
+    public function __construct(string $label, string $icon, string $link) {
39
+        parent::__construct('directLink-container', $label, $icon, $link);
40
+    }
41 41
 
42
-	/**
43
-	 * @return string
44
-	 */
45
-	public function render(): string {
46
-		return '<li>' .
47
-			'<a id="directLink-container">' .
48
-			'<span class="icon ' . Util::sanitizeHTML($this->getIcon()) . '"></span>' .
49
-			'<label for="directLink">' . Util::sanitizeHTML($this->getLabel()) . '</label>' .
50
-			'<input id="directLink" type="text" readonly="" value="' . Util::sanitizeHTML($this->getLink()) . '">' .
51
-			'</a>' .
52
-			'</li>';
53
-	}
42
+    /**
43
+     * @return string
44
+     */
45
+    public function render(): string {
46
+        return '<li>' .
47
+            '<a id="directLink-container">' .
48
+            '<span class="icon ' . Util::sanitizeHTML($this->getIcon()) . '"></span>' .
49
+            '<label for="directLink">' . Util::sanitizeHTML($this->getLabel()) . '</label>' .
50
+            '<input id="directLink" type="text" readonly="" value="' . Util::sanitizeHTML($this->getLink()) . '">' .
51
+            '</a>' .
52
+            '</li>';
53
+    }
54 54
 }
55 55
\ No newline at end of file
Please login to merge, or discard this patch.
apps/files_sharing/lib/Template/ExternalShareMenuAction.php 1 patch
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -28,41 +28,41 @@
 block discarded – undo
28 28
 
29 29
 class ExternalShareMenuAction extends SimpleMenuAction {
30 30
 
31
-	/** @var string */
32
-	private $owner;
31
+    /** @var string */
32
+    private $owner;
33 33
 
34
-	/** @var string */
35
-	private $displayname;
34
+    /** @var string */
35
+    private $displayname;
36 36
 
37
-	/** @var string */
38
-	private $shareName;
37
+    /** @var string */
38
+    private $shareName;
39 39
 
40
-	/**
41
-	 * ExternalShareMenuAction constructor.
42
-	 *
43
-	 * @param string $label
44
-	 * @param string $icon
45
-	 * @param string $owner
46
-	 * @param string $displayname
47
-	 * @param string $shareName
48
-	 */
49
-	public function __construct(string $label, string $icon, string $owner, string $displayname, string $shareName) {
50
-		parent::__construct('save', $label, $icon);
51
-		$this->owner = $owner;
52
-		$this->displayname = $displayname;
53
-		$this->shareName = $shareName;
54
-	}
40
+    /**
41
+     * ExternalShareMenuAction constructor.
42
+     *
43
+     * @param string $label
44
+     * @param string $icon
45
+     * @param string $owner
46
+     * @param string $displayname
47
+     * @param string $shareName
48
+     */
49
+    public function __construct(string $label, string $icon, string $owner, string $displayname, string $shareName) {
50
+        parent::__construct('save', $label, $icon);
51
+        $this->owner = $owner;
52
+        $this->displayname = $displayname;
53
+        $this->shareName = $shareName;
54
+    }
55 55
 
56
-	public function render(): string {
57
-		return '<li>' .
58
-			'<a id="save" data-protected="false" data-owner-display-name="' . Util::sanitizeHTML($this->displayname) . '" data-owner="' . Util::sanitizeHTML($this->owner) . '" data-name="' . Util::sanitizeHTML($this->shareName) . '">' .
59
-			'<span class="icon ' . Util::sanitizeHTML($this->getIcon()) . '"></span>' .
60
-			'<span id="save-button">' . Util::sanitizeHTML($this->getLabel()) . '</span>' .
61
-			'<form class="save-form hidden" action="#">' .
62
-			'<input type="text" id="remote_address" placeholder="[email protected]">' .
63
-			'<button id="save-button-confirm" class="icon-confirm svg" disabled=""></button>' .
64
-			'</form>' .
65
-			'</a>' .
66
-			'</li>';
67
-	}
56
+    public function render(): string {
57
+        return '<li>' .
58
+            '<a id="save" data-protected="false" data-owner-display-name="' . Util::sanitizeHTML($this->displayname) . '" data-owner="' . Util::sanitizeHTML($this->owner) . '" data-name="' . Util::sanitizeHTML($this->shareName) . '">' .
59
+            '<span class="icon ' . Util::sanitizeHTML($this->getIcon()) . '"></span>' .
60
+            '<span id="save-button">' . Util::sanitizeHTML($this->getLabel()) . '</span>' .
61
+            '<form class="save-form hidden" action="#">' .
62
+            '<input type="text" id="remote_address" placeholder="[email protected]">' .
63
+            '<button id="save-button-confirm" class="icon-confirm svg" disabled=""></button>' .
64
+            '</form>' .
65
+            '</a>' .
66
+            '</li>';
67
+    }
68 68
 }
69 69
\ No newline at end of file
Please login to merge, or discard this patch.
lib/private/legacy/template.php 1 patch
Indentation   +345 added lines, -345 removed lines patch added patch discarded remove patch
@@ -46,349 +46,349 @@
 block discarded – undo
46 46
  */
47 47
 class OC_Template extends \OC\Template\Base {
48 48
 
49
-	/** @var string */
50
-	private $renderAs; // Create a full page?
51
-
52
-	/** @var string */
53
-	private $path; // The path to the template
54
-
55
-	/** @var array */
56
-	private $headers = array(); //custom headers
57
-
58
-	/** @var string */
59
-	protected $app; // app id
60
-
61
-	protected static $initTemplateEngineFirstRun = true;
62
-
63
-	/**
64
-	 * Constructor
65
-	 *
66
-	 * @param string $app app providing the template
67
-	 * @param string $name of the template file (without suffix)
68
-	 * @param string $renderAs If $renderAs is set, OC_Template will try to
69
-	 *                         produce a full page in the according layout. For
70
-	 *                         now, $renderAs can be set to "guest", "user" or
71
-	 *                         "admin".
72
-	 * @param bool $registerCall = true
73
-	 */
74
-	public function __construct( $app, $name, $renderAs = "", $registerCall = true ) {
75
-		// Read the selected theme from the config file
76
-		self::initTemplateEngine($renderAs);
77
-
78
-		$theme = OC_Util::getTheme();
79
-
80
-		$requestToken = (OC::$server->getSession() && $registerCall) ? \OCP\Util::callRegister() : '';
81
-
82
-		$parts = explode('/', $app); // fix translation when app is something like core/lostpassword
83
-		$l10n = \OC::$server->getL10N($parts[0]);
84
-		/** @var \OCP\Defaults $themeDefaults */
85
-		$themeDefaults = \OC::$server->query(\OCP\Defaults::class);
86
-
87
-		list($path, $template) = $this->findTemplate($theme, $app, $name);
88
-
89
-		// Set the private data
90
-		$this->renderAs = $renderAs;
91
-		$this->path = $path;
92
-		$this->app = $app;
93
-
94
-		parent::__construct($template, $requestToken, $l10n, $themeDefaults);
95
-	}
96
-
97
-	/**
98
-	 * @param string $renderAs
99
-	 */
100
-	public static function initTemplateEngine($renderAs) {
101
-		if (self::$initTemplateEngineFirstRun){
102
-
103
-			//apps that started before the template initialization can load their own scripts/styles
104
-			//so to make sure this scripts/styles here are loaded first we use OC_Util::addScript() with $prepend=true
105
-			//meaning the last script/style in this list will be loaded first
106
-			if (\OC::$server->getSystemConfig()->getValue ('installed', false) && $renderAs !== 'error' && !\OCP\Util::needUpgrade()) {
107
-				if (\OC::$server->getConfig ()->getAppValue ( 'core', 'backgroundjobs_mode', 'ajax' ) == 'ajax') {
108
-					OC_Util::addScript ( 'backgroundjobs', null, true );
109
-				}
110
-			}
111
-
112
-			OC_Util::addStyle('server', null, true);
113
-			OC_Util::addStyle('jquery-ui-fixes',null,true);
114
-			OC_Util::addVendorStyle('jquery-ui/themes/base/jquery-ui',null,true);
115
-			OC_Util::addVendorStyle('select2/select2', null, true);
116
-			OC_Util::addStyle('jquery.ocdialog');
117
-			OC_Util::addTranslations("core", null, true);
118
-			OC_Util::addScript('search', 'search', true);
119
-			OC_Util::addScript('merged-template-prepend', null, true);
120
-			OC_Util::addScript('jquery-ui-fixes');
121
-			OC_Util::addScript('files/fileinfo');
122
-			OC_Util::addScript('files/client');
123
-			OC_Util::addScript('contactsmenu');
124
-
125
-			if (\OC::$server->getConfig()->getSystemValue('debug')) {
126
-				// Add the stuff we need always
127
-				// following logic will import all vendor libraries that are
128
-				// specified in core/js/core.json
129
-				$fileContent = file_get_contents(OC::$SERVERROOT . '/core/js/core.json');
130
-				if($fileContent !== false) {
131
-					$coreDependencies = json_decode($fileContent, true);
132
-					foreach(array_reverse($coreDependencies['vendor']) as $vendorLibrary) {
133
-						//remove trailing ".js" as addVendorScript will append it
134
-						OC_Util::addVendorScript(
135
-							substr($vendorLibrary, 0, -3),null,true);
136
-						}
137
- 				} else {
138
-					throw new \Exception('Cannot read core/js/core.json');
139
-				}
140
-			} else {
141
-				// Import all (combined) default vendor libraries
142
-				OC_Util::addVendorScript('core', null, true);
143
-			}
144
-
145
-			if (\OC::$server->getRequest()->isUserAgent([\OC\AppFramework\Http\Request::USER_AGENT_IE])) {
146
-				// polyfill for btoa/atob for IE friends
147
-				OC_Util::addVendorScript('base64/base64');
148
-				// shim for the davclient.js library
149
-				\OCP\Util::addScript('files/iedavclient');
150
-			}
151
-
152
-			self::$initTemplateEngineFirstRun = false;
153
-		}
154
-
155
-	}
156
-
157
-
158
-	/**
159
-	 * find the template with the given name
160
-	 * @param string $name of the template file (without suffix)
161
-	 *
162
-	 * Will select the template file for the selected theme.
163
-	 * Checking all the possible locations.
164
-	 * @param string $theme
165
-	 * @param string $app
166
-	 * @return string[]
167
-	 */
168
-	protected function findTemplate($theme, $app, $name) {
169
-		// Check if it is a app template or not.
170
-		if( $app !== '' ) {
171
-			$dirs = $this->getAppTemplateDirs($theme, $app, OC::$SERVERROOT, OC_App::getAppPath($app));
172
-		} else {
173
-			$dirs = $this->getCoreTemplateDirs($theme, OC::$SERVERROOT);
174
-		}
175
-		$locator = new \OC\Template\TemplateFileLocator( $dirs );
176
-		$template = $locator->find($name);
177
-		$path = $locator->getPath();
178
-		return array($path, $template);
179
-	}
180
-
181
-	/**
182
-	 * Add a custom element to the header
183
-	 * @param string $tag tag name of the element
184
-	 * @param array $attributes array of attributes for the element
185
-	 * @param string $text the text content for the element. If $text is null then the
186
-	 * element will be written as empty element. So use "" to get a closing tag.
187
-	 */
188
-	public function addHeader($tag, $attributes, $text=null) {
189
-		$this->headers[]= array(
190
-			'tag' => $tag,
191
-			'attributes' => $attributes,
192
-			'text' => $text
193
-		);
194
-	}
195
-
196
-	/**
197
-	 * Process the template
198
-	 * @return boolean|string
199
-	 *
200
-	 * This function process the template. If $this->renderAs is set, it
201
-	 * will produce a full page.
202
-	 */
203
-	public function fetchPage($additionalParams = null) {
204
-		$data = parent::fetchPage($additionalParams);
205
-
206
-		if( $this->renderAs ) {
207
-			$page = new TemplateLayout($this->renderAs, $this->app);
208
-
209
-			if(is_array($additionalParams)) {
210
-				foreach ($additionalParams as $key => $value) {
211
-					$page->assign($key, $value);
212
-				}
213
-			}
214
-
215
-			// Add custom headers
216
-			$headers = '';
217
-			foreach(OC_Util::$headers as $header) {
218
-				$headers .= '<'.\OCP\Util::sanitizeHTML($header['tag']);
219
-				if ( strcasecmp($header['tag'], 'script') === 0 && in_array('src', array_map('strtolower', array_keys($header['attributes']))) ) {
220
-					$headers .= ' defer';
221
-				}
222
-				foreach($header['attributes'] as $name=>$value) {
223
-					$headers .= ' '.\OCP\Util::sanitizeHTML($name).'="'.\OCP\Util::sanitizeHTML($value).'"';
224
-				}
225
-				if ($header['text'] !== null) {
226
-					$headers .= '>'.\OCP\Util::sanitizeHTML($header['text']).'</'.\OCP\Util::sanitizeHTML($header['tag']).'>';
227
-				} else {
228
-					$headers .= '/>';
229
-				}
230
-			}
231
-
232
-			$page->assign('headers', $headers);
233
-
234
-			$page->assign('content', $data);
235
-			return $page->fetchPage($additionalParams);
236
-		}
237
-
238
-		return $data;
239
-	}
240
-
241
-	/**
242
-	 * Include template
243
-	 *
244
-	 * @param string $file
245
-	 * @param array|null $additionalParams
246
-	 * @return string returns content of included template
247
-	 *
248
-	 * Includes another template. use <?php echo $this->inc('template'); ?> to
249
-	 * do this.
250
-	 */
251
-	public function inc( $file, $additionalParams = null ) {
252
-		return $this->load($this->path.$file.'.php', $additionalParams);
253
-	}
254
-
255
-	/**
256
-	 * Shortcut to print a simple page for users
257
-	 * @param string $application The application we render the template for
258
-	 * @param string $name Name of the template
259
-	 * @param array $parameters Parameters for the template
260
-	 * @return boolean|null
261
-	 */
262
-	public static function printUserPage( $application, $name, $parameters = array() ) {
263
-		$content = new OC_Template( $application, $name, "user" );
264
-		foreach( $parameters as $key => $value ) {
265
-			$content->assign( $key, $value );
266
-		}
267
-		print $content->printPage();
268
-	}
269
-
270
-	/**
271
-	 * Shortcut to print a simple page for admins
272
-	 * @param string $application The application we render the template for
273
-	 * @param string $name Name of the template
274
-	 * @param array $parameters Parameters for the template
275
-	 * @return bool
276
-	 */
277
-	public static function printAdminPage( $application, $name, $parameters = array() ) {
278
-		$content = new OC_Template( $application, $name, "admin" );
279
-		foreach( $parameters as $key => $value ) {
280
-			$content->assign( $key, $value );
281
-		}
282
-		return $content->printPage();
283
-	}
284
-
285
-	/**
286
-	 * Shortcut to print a simple page for guests
287
-	 * @param string $application The application we render the template for
288
-	 * @param string $name Name of the template
289
-	 * @param array|string $parameters Parameters for the template
290
-	 * @return bool
291
-	 */
292
-	public static function printGuestPage( $application, $name, $parameters = array() ) {
293
-		$content = new OC_Template( $application, $name, "guest" );
294
-		foreach( $parameters as $key => $value ) {
295
-			$content->assign( $key, $value );
296
-		}
297
-		return $content->printPage();
298
-	}
299
-
300
-	/**
301
-	 * Print a fatal error page and terminates the script
302
-	 * @param string $error_msg The error message to show
303
-	 * @param string $hint An optional hint message - needs to be properly escape
304
-	 * @suppress PhanAccessMethodInternal
305
-	 */
306
-	public static function printErrorPage( $error_msg, $hint = '' ) {
307
-		if (\OC::$server->getAppManager()->isEnabledForUser('theming') && !\OC_App::isAppLoaded('theming')) {
308
-			\OC_App::loadApp('theming');
309
-		}
310
-
311
-
312
-		if ($error_msg === $hint) {
313
-			// If the hint is the same as the message there is no need to display it twice.
314
-			$hint = '';
315
-		}
316
-
317
-		try {
318
-			$content = new \OC_Template( '', 'error', 'error', false );
319
-			$errors = array(array('error' => $error_msg, 'hint' => $hint));
320
-			$content->assign( 'errors', $errors );
321
-			$content->printPage();
322
-		} catch (\Exception $e) {
323
-			$logger = \OC::$server->getLogger();
324
-			$logger->error("$error_msg $hint", ['app' => 'core']);
325
-			$logger->logException($e, ['app' => 'core']);
326
-
327
-			header(self::getHttpProtocol() . ' 500 Internal Server Error');
328
-			header('Content-Type: text/plain; charset=utf-8');
329
-			print("$error_msg $hint");
330
-		}
331
-		die();
332
-	}
333
-
334
-	/**
335
-	 * print error page using Exception details
336
-	 * @param Exception|Throwable $exception
337
-	 * @param bool $fetchPage
338
-	 * @return bool|string
339
-	 * @suppress PhanAccessMethodInternal
340
-	 */
341
-	public static function printExceptionErrorPage($exception, $fetchPage = false) {
342
-		try {
343
-			$request = \OC::$server->getRequest();
344
-			$content = new \OC_Template('', 'exception', 'error', false);
345
-			$content->assign('errorClass', get_class($exception));
346
-			$content->assign('errorMsg', $exception->getMessage());
347
-			$content->assign('errorCode', $exception->getCode());
348
-			$content->assign('file', $exception->getFile());
349
-			$content->assign('line', $exception->getLine());
350
-			$content->assign('trace', $exception->getTraceAsString());
351
-			$content->assign('debugMode', \OC::$server->getSystemConfig()->getValue('debug', false));
352
-			$content->assign('remoteAddr', $request->getRemoteAddress());
353
-			$content->assign('requestID', $request->getId());
354
-			if ($fetchPage) {
355
-				return $content->fetchPage();
356
-			}
357
-			$content->printPage();
358
-		} catch (\Exception $e) {
359
-			$logger = \OC::$server->getLogger();
360
-			$logger->logException($exception, ['app' => 'core']);
361
-			$logger->logException($e, ['app' => 'core']);
362
-
363
-			header(self::getHttpProtocol() . ' 500 Internal Server Error');
364
-			header('Content-Type: text/plain; charset=utf-8');
365
-			print("Internal Server Error\n\n");
366
-			print("The server encountered an internal error and was unable to complete your request.\n");
367
-			print("Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.\n");
368
-			print("More details can be found in the server log.\n");
369
-		}
370
-		die();
371
-	}
372
-
373
-	/**
374
-	 * This is only here to reduce the dependencies in case of an exception to
375
-	 * still be able to print a plain error message.
376
-	 *
377
-	 * Returns the used HTTP protocol.
378
-	 *
379
-	 * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0.
380
-	 * @internal Don't use this - use AppFramework\Http\Request->getHttpProtocol instead
381
-	 */
382
-	protected static function getHttpProtocol() {
383
-		$claimedProtocol = strtoupper($_SERVER['SERVER_PROTOCOL']);
384
-		$validProtocols = [
385
-			'HTTP/1.0',
386
-			'HTTP/1.1',
387
-			'HTTP/2',
388
-		];
389
-		if(in_array($claimedProtocol, $validProtocols, true)) {
390
-			return $claimedProtocol;
391
-		}
392
-		return 'HTTP/1.1';
393
-	}
49
+    /** @var string */
50
+    private $renderAs; // Create a full page?
51
+
52
+    /** @var string */
53
+    private $path; // The path to the template
54
+
55
+    /** @var array */
56
+    private $headers = array(); //custom headers
57
+
58
+    /** @var string */
59
+    protected $app; // app id
60
+
61
+    protected static $initTemplateEngineFirstRun = true;
62
+
63
+    /**
64
+     * Constructor
65
+     *
66
+     * @param string $app app providing the template
67
+     * @param string $name of the template file (without suffix)
68
+     * @param string $renderAs If $renderAs is set, OC_Template will try to
69
+     *                         produce a full page in the according layout. For
70
+     *                         now, $renderAs can be set to "guest", "user" or
71
+     *                         "admin".
72
+     * @param bool $registerCall = true
73
+     */
74
+    public function __construct( $app, $name, $renderAs = "", $registerCall = true ) {
75
+        // Read the selected theme from the config file
76
+        self::initTemplateEngine($renderAs);
77
+
78
+        $theme = OC_Util::getTheme();
79
+
80
+        $requestToken = (OC::$server->getSession() && $registerCall) ? \OCP\Util::callRegister() : '';
81
+
82
+        $parts = explode('/', $app); // fix translation when app is something like core/lostpassword
83
+        $l10n = \OC::$server->getL10N($parts[0]);
84
+        /** @var \OCP\Defaults $themeDefaults */
85
+        $themeDefaults = \OC::$server->query(\OCP\Defaults::class);
86
+
87
+        list($path, $template) = $this->findTemplate($theme, $app, $name);
88
+
89
+        // Set the private data
90
+        $this->renderAs = $renderAs;
91
+        $this->path = $path;
92
+        $this->app = $app;
93
+
94
+        parent::__construct($template, $requestToken, $l10n, $themeDefaults);
95
+    }
96
+
97
+    /**
98
+     * @param string $renderAs
99
+     */
100
+    public static function initTemplateEngine($renderAs) {
101
+        if (self::$initTemplateEngineFirstRun){
102
+
103
+            //apps that started before the template initialization can load their own scripts/styles
104
+            //so to make sure this scripts/styles here are loaded first we use OC_Util::addScript() with $prepend=true
105
+            //meaning the last script/style in this list will be loaded first
106
+            if (\OC::$server->getSystemConfig()->getValue ('installed', false) && $renderAs !== 'error' && !\OCP\Util::needUpgrade()) {
107
+                if (\OC::$server->getConfig ()->getAppValue ( 'core', 'backgroundjobs_mode', 'ajax' ) == 'ajax') {
108
+                    OC_Util::addScript ( 'backgroundjobs', null, true );
109
+                }
110
+            }
111
+
112
+            OC_Util::addStyle('server', null, true);
113
+            OC_Util::addStyle('jquery-ui-fixes',null,true);
114
+            OC_Util::addVendorStyle('jquery-ui/themes/base/jquery-ui',null,true);
115
+            OC_Util::addVendorStyle('select2/select2', null, true);
116
+            OC_Util::addStyle('jquery.ocdialog');
117
+            OC_Util::addTranslations("core", null, true);
118
+            OC_Util::addScript('search', 'search', true);
119
+            OC_Util::addScript('merged-template-prepend', null, true);
120
+            OC_Util::addScript('jquery-ui-fixes');
121
+            OC_Util::addScript('files/fileinfo');
122
+            OC_Util::addScript('files/client');
123
+            OC_Util::addScript('contactsmenu');
124
+
125
+            if (\OC::$server->getConfig()->getSystemValue('debug')) {
126
+                // Add the stuff we need always
127
+                // following logic will import all vendor libraries that are
128
+                // specified in core/js/core.json
129
+                $fileContent = file_get_contents(OC::$SERVERROOT . '/core/js/core.json');
130
+                if($fileContent !== false) {
131
+                    $coreDependencies = json_decode($fileContent, true);
132
+                    foreach(array_reverse($coreDependencies['vendor']) as $vendorLibrary) {
133
+                        //remove trailing ".js" as addVendorScript will append it
134
+                        OC_Util::addVendorScript(
135
+                            substr($vendorLibrary, 0, -3),null,true);
136
+                        }
137
+                    } else {
138
+                    throw new \Exception('Cannot read core/js/core.json');
139
+                }
140
+            } else {
141
+                // Import all (combined) default vendor libraries
142
+                OC_Util::addVendorScript('core', null, true);
143
+            }
144
+
145
+            if (\OC::$server->getRequest()->isUserAgent([\OC\AppFramework\Http\Request::USER_AGENT_IE])) {
146
+                // polyfill for btoa/atob for IE friends
147
+                OC_Util::addVendorScript('base64/base64');
148
+                // shim for the davclient.js library
149
+                \OCP\Util::addScript('files/iedavclient');
150
+            }
151
+
152
+            self::$initTemplateEngineFirstRun = false;
153
+        }
154
+
155
+    }
156
+
157
+
158
+    /**
159
+     * find the template with the given name
160
+     * @param string $name of the template file (without suffix)
161
+     *
162
+     * Will select the template file for the selected theme.
163
+     * Checking all the possible locations.
164
+     * @param string $theme
165
+     * @param string $app
166
+     * @return string[]
167
+     */
168
+    protected function findTemplate($theme, $app, $name) {
169
+        // Check if it is a app template or not.
170
+        if( $app !== '' ) {
171
+            $dirs = $this->getAppTemplateDirs($theme, $app, OC::$SERVERROOT, OC_App::getAppPath($app));
172
+        } else {
173
+            $dirs = $this->getCoreTemplateDirs($theme, OC::$SERVERROOT);
174
+        }
175
+        $locator = new \OC\Template\TemplateFileLocator( $dirs );
176
+        $template = $locator->find($name);
177
+        $path = $locator->getPath();
178
+        return array($path, $template);
179
+    }
180
+
181
+    /**
182
+     * Add a custom element to the header
183
+     * @param string $tag tag name of the element
184
+     * @param array $attributes array of attributes for the element
185
+     * @param string $text the text content for the element. If $text is null then the
186
+     * element will be written as empty element. So use "" to get a closing tag.
187
+     */
188
+    public function addHeader($tag, $attributes, $text=null) {
189
+        $this->headers[]= array(
190
+            'tag' => $tag,
191
+            'attributes' => $attributes,
192
+            'text' => $text
193
+        );
194
+    }
195
+
196
+    /**
197
+     * Process the template
198
+     * @return boolean|string
199
+     *
200
+     * This function process the template. If $this->renderAs is set, it
201
+     * will produce a full page.
202
+     */
203
+    public function fetchPage($additionalParams = null) {
204
+        $data = parent::fetchPage($additionalParams);
205
+
206
+        if( $this->renderAs ) {
207
+            $page = new TemplateLayout($this->renderAs, $this->app);
208
+
209
+            if(is_array($additionalParams)) {
210
+                foreach ($additionalParams as $key => $value) {
211
+                    $page->assign($key, $value);
212
+                }
213
+            }
214
+
215
+            // Add custom headers
216
+            $headers = '';
217
+            foreach(OC_Util::$headers as $header) {
218
+                $headers .= '<'.\OCP\Util::sanitizeHTML($header['tag']);
219
+                if ( strcasecmp($header['tag'], 'script') === 0 && in_array('src', array_map('strtolower', array_keys($header['attributes']))) ) {
220
+                    $headers .= ' defer';
221
+                }
222
+                foreach($header['attributes'] as $name=>$value) {
223
+                    $headers .= ' '.\OCP\Util::sanitizeHTML($name).'="'.\OCP\Util::sanitizeHTML($value).'"';
224
+                }
225
+                if ($header['text'] !== null) {
226
+                    $headers .= '>'.\OCP\Util::sanitizeHTML($header['text']).'</'.\OCP\Util::sanitizeHTML($header['tag']).'>';
227
+                } else {
228
+                    $headers .= '/>';
229
+                }
230
+            }
231
+
232
+            $page->assign('headers', $headers);
233
+
234
+            $page->assign('content', $data);
235
+            return $page->fetchPage($additionalParams);
236
+        }
237
+
238
+        return $data;
239
+    }
240
+
241
+    /**
242
+     * Include template
243
+     *
244
+     * @param string $file
245
+     * @param array|null $additionalParams
246
+     * @return string returns content of included template
247
+     *
248
+     * Includes another template. use <?php echo $this->inc('template'); ?> to
249
+     * do this.
250
+     */
251
+    public function inc( $file, $additionalParams = null ) {
252
+        return $this->load($this->path.$file.'.php', $additionalParams);
253
+    }
254
+
255
+    /**
256
+     * Shortcut to print a simple page for users
257
+     * @param string $application The application we render the template for
258
+     * @param string $name Name of the template
259
+     * @param array $parameters Parameters for the template
260
+     * @return boolean|null
261
+     */
262
+    public static function printUserPage( $application, $name, $parameters = array() ) {
263
+        $content = new OC_Template( $application, $name, "user" );
264
+        foreach( $parameters as $key => $value ) {
265
+            $content->assign( $key, $value );
266
+        }
267
+        print $content->printPage();
268
+    }
269
+
270
+    /**
271
+     * Shortcut to print a simple page for admins
272
+     * @param string $application The application we render the template for
273
+     * @param string $name Name of the template
274
+     * @param array $parameters Parameters for the template
275
+     * @return bool
276
+     */
277
+    public static function printAdminPage( $application, $name, $parameters = array() ) {
278
+        $content = new OC_Template( $application, $name, "admin" );
279
+        foreach( $parameters as $key => $value ) {
280
+            $content->assign( $key, $value );
281
+        }
282
+        return $content->printPage();
283
+    }
284
+
285
+    /**
286
+     * Shortcut to print a simple page for guests
287
+     * @param string $application The application we render the template for
288
+     * @param string $name Name of the template
289
+     * @param array|string $parameters Parameters for the template
290
+     * @return bool
291
+     */
292
+    public static function printGuestPage( $application, $name, $parameters = array() ) {
293
+        $content = new OC_Template( $application, $name, "guest" );
294
+        foreach( $parameters as $key => $value ) {
295
+            $content->assign( $key, $value );
296
+        }
297
+        return $content->printPage();
298
+    }
299
+
300
+    /**
301
+     * Print a fatal error page and terminates the script
302
+     * @param string $error_msg The error message to show
303
+     * @param string $hint An optional hint message - needs to be properly escape
304
+     * @suppress PhanAccessMethodInternal
305
+     */
306
+    public static function printErrorPage( $error_msg, $hint = '' ) {
307
+        if (\OC::$server->getAppManager()->isEnabledForUser('theming') && !\OC_App::isAppLoaded('theming')) {
308
+            \OC_App::loadApp('theming');
309
+        }
310
+
311
+
312
+        if ($error_msg === $hint) {
313
+            // If the hint is the same as the message there is no need to display it twice.
314
+            $hint = '';
315
+        }
316
+
317
+        try {
318
+            $content = new \OC_Template( '', 'error', 'error', false );
319
+            $errors = array(array('error' => $error_msg, 'hint' => $hint));
320
+            $content->assign( 'errors', $errors );
321
+            $content->printPage();
322
+        } catch (\Exception $e) {
323
+            $logger = \OC::$server->getLogger();
324
+            $logger->error("$error_msg $hint", ['app' => 'core']);
325
+            $logger->logException($e, ['app' => 'core']);
326
+
327
+            header(self::getHttpProtocol() . ' 500 Internal Server Error');
328
+            header('Content-Type: text/plain; charset=utf-8');
329
+            print("$error_msg $hint");
330
+        }
331
+        die();
332
+    }
333
+
334
+    /**
335
+     * print error page using Exception details
336
+     * @param Exception|Throwable $exception
337
+     * @param bool $fetchPage
338
+     * @return bool|string
339
+     * @suppress PhanAccessMethodInternal
340
+     */
341
+    public static function printExceptionErrorPage($exception, $fetchPage = false) {
342
+        try {
343
+            $request = \OC::$server->getRequest();
344
+            $content = new \OC_Template('', 'exception', 'error', false);
345
+            $content->assign('errorClass', get_class($exception));
346
+            $content->assign('errorMsg', $exception->getMessage());
347
+            $content->assign('errorCode', $exception->getCode());
348
+            $content->assign('file', $exception->getFile());
349
+            $content->assign('line', $exception->getLine());
350
+            $content->assign('trace', $exception->getTraceAsString());
351
+            $content->assign('debugMode', \OC::$server->getSystemConfig()->getValue('debug', false));
352
+            $content->assign('remoteAddr', $request->getRemoteAddress());
353
+            $content->assign('requestID', $request->getId());
354
+            if ($fetchPage) {
355
+                return $content->fetchPage();
356
+            }
357
+            $content->printPage();
358
+        } catch (\Exception $e) {
359
+            $logger = \OC::$server->getLogger();
360
+            $logger->logException($exception, ['app' => 'core']);
361
+            $logger->logException($e, ['app' => 'core']);
362
+
363
+            header(self::getHttpProtocol() . ' 500 Internal Server Error');
364
+            header('Content-Type: text/plain; charset=utf-8');
365
+            print("Internal Server Error\n\n");
366
+            print("The server encountered an internal error and was unable to complete your request.\n");
367
+            print("Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.\n");
368
+            print("More details can be found in the server log.\n");
369
+        }
370
+        die();
371
+    }
372
+
373
+    /**
374
+     * This is only here to reduce the dependencies in case of an exception to
375
+     * still be able to print a plain error message.
376
+     *
377
+     * Returns the used HTTP protocol.
378
+     *
379
+     * @return string HTTP protocol. HTTP/2, HTTP/1.1 or HTTP/1.0.
380
+     * @internal Don't use this - use AppFramework\Http\Request->getHttpProtocol instead
381
+     */
382
+    protected static function getHttpProtocol() {
383
+        $claimedProtocol = strtoupper($_SERVER['SERVER_PROTOCOL']);
384
+        $validProtocols = [
385
+            'HTTP/1.0',
386
+            'HTTP/1.1',
387
+            'HTTP/2',
388
+        ];
389
+        if(in_array($claimedProtocol, $validProtocols, true)) {
390
+            return $claimedProtocol;
391
+        }
392
+        return 'HTTP/1.1';
393
+    }
394 394
 }
Please login to merge, or discard this patch.
lib/private/TemplateLayout.php 1 patch
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.
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.