Completed
Push — stable10 ( b85e94...1e5021 )
by
unknown
23:18 queued 12:32
created
lib/private/Mail/Mailer.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -98,7 +98,7 @@  discard block
 block discarded – undo
98 98
 		$mailer = $this->getInstance();
99 99
 
100 100
 		// Enable logger if debug mode is enabled
101
-		if($debugMode) {
101
+		if ($debugMode) {
102 102
 			$mailLogger = new \Swift_Plugins_Loggers_ArrayLogger();
103 103
 			$mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($mailLogger));
104 104
 		}
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
 		// Debugging logging
109 109
 		$logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject());
110 110
 		$this->logger->debug($logMessage, ['app' => 'core']);
111
-		if($debugMode && isset($mailLogger)) {
111
+		if ($debugMode && isset($mailLogger)) {
112 112
 			$this->logger->debug($mailLogger->dump(), ['app' => 'core']);
113 113
 		}
114 114
 
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
 				break;
210 210
 		}
211 211
 
212
-		return \Swift_SendmailTransport::newInstance($binaryPath . ' -bs');
212
+		return \Swift_SendmailTransport::newInstance($binaryPath.' -bs');
213 213
 	}
214 214
 
215 215
 	/**
Please login to merge, or discard this patch.
Indentation   +175 added lines, -175 removed lines patch added patch discarded remove patch
@@ -45,180 +45,180 @@
 block discarded – undo
45 45
  * @package OC\Mail
46 46
  */
47 47
 class Mailer implements IMailer {
48
-	/** @var \Swift_SmtpTransport|\Swift_SendmailTransport|\Swift_MailTransport Cached transport */
49
-	private $instance = null;
50
-	/** @var IConfig */
51
-	private $config;
52
-	/** @var ILogger */
53
-	private $logger;
54
-	/** @var \OC_Defaults */
55
-	private $defaults;
56
-
57
-	/**
58
-	 * @param IConfig $config
59
-	 * @param ILogger $logger
60
-	 * @param \OC_Defaults $defaults
61
-	 */
62
-	function __construct(IConfig $config,
63
-						 ILogger $logger,
64
-						 \OC_Defaults $defaults) {
65
-		$this->config = $config;
66
-		$this->logger = $logger;
67
-		$this->defaults = $defaults;
68
-	}
69
-
70
-	/**
71
-	 * Creates a new message object that can be passed to send()
72
-	 *
73
-	 * @return Message
74
-	 */
75
-	public function createMessage() {
76
-		return new Message(new \Swift_Message());
77
-	}
78
-
79
-	/**
80
-	 * Send the specified message. Also sets the from address to the value defined in config.php
81
-	 * if no-one has been passed.
82
-	 *
83
-	 * @param Message $message Message to send
84
-	 * @return string[] Array with failed recipients. Be aware that this depends on the used mail backend and
85
-	 * therefore should be considered
86
-	 * @throws \Exception In case it was not possible to send the message. (for example if an invalid mail address
87
-	 * has been supplied.)
88
-	 */
89
-	public function send(Message $message) {
90
-		$debugMode = $this->config->getSystemValue('mail_smtpdebug', false);
91
-
92
-		if (sizeof($message->getFrom()) === 0) {
93
-			$message->setFrom([\OCP\Util::getDefaultEmailAddress($this->defaults->getName())]);
94
-		}
95
-
96
-		$failedRecipients = [];
97
-
98
-		$mailer = $this->getInstance();
99
-
100
-		// Enable logger if debug mode is enabled
101
-		if($debugMode) {
102
-			$mailLogger = new \Swift_Plugins_Loggers_ArrayLogger();
103
-			$mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($mailLogger));
104
-		}
105
-
106
-		$mailer->send($message->getSwiftMessage(), $failedRecipients);
107
-
108
-		// Debugging logging
109
-		$logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject());
110
-		$this->logger->debug($logMessage, ['app' => 'core']);
111
-		if($debugMode && isset($mailLogger)) {
112
-			$this->logger->debug($mailLogger->dump(), ['app' => 'core']);
113
-		}
114
-
115
-		return $failedRecipients;
116
-	}
117
-
118
-	/**
119
-	 * Checks if an e-mail address is valid
120
-	 *
121
-	 * @param string $email Email address to be validated
122
-	 * @return bool True if the mail address is valid, false otherwise
123
-	 */
124
-	public function validateMailAddress($email) {
125
-		return \Swift_Validate::email($this->convertEmail($email));
126
-	}
127
-
128
-	/**
129
-	 * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains
130
-	 *
131
-	 * FIXME: Remove this once SwiftMailer supports IDN
132
-	 *
133
-	 * @param string $email
134
-	 * @return string Converted mail address if `idn_to_ascii` exists
135
-	 */
136
-	protected function convertEmail($email) {
137
-		if (!function_exists('idn_to_ascii') || strpos($email, '@') === false) {
138
-			return $email;
139
-		}
140
-
141
-		list($name, $domain) = explode('@', $email, 2);
142
-		$domain = idn_to_ascii($domain);
143
-		return $name.'@'.$domain;
144
-	}
145
-
146
-	/**
147
-	 * Returns whatever transport is configured within the config
148
-	 *
149
-	 * @return \Swift_SmtpTransport|\Swift_SendmailTransport|\Swift_MailTransport
150
-	 */
151
-	protected function getInstance() {
152
-		if (!is_null($this->instance)) {
153
-			return $this->instance;
154
-		}
155
-
156
-		switch ($this->config->getSystemValue('mail_smtpmode', 'php')) {
157
-			case 'smtp':
158
-				$this->instance = $this->getSMTPInstance();
159
-				break;
160
-			case 'sendmail':
161
-				// FIXME: Move into the return statement but requires proper testing
162
-				//       for SMTP and mail as well. Thus not really doable for a
163
-				//       minor release.
164
-				$this->instance = \Swift_Mailer::newInstance($this->getSendMailInstance());
165
-				break;
166
-			default:
167
-				$this->instance = $this->getMailInstance();
168
-				break;
169
-		}
170
-
171
-		return $this->instance;
172
-	}
173
-
174
-	/**
175
-	 * Returns the SMTP transport
176
-	 *
177
-	 * @return \Swift_SmtpTransport
178
-	 */
179
-	protected function getSmtpInstance() {
180
-		$transport = \Swift_SmtpTransport::newInstance();
181
-		$transport->setTimeout($this->config->getSystemValue('mail_smtptimeout', 10));
182
-		$transport->setHost($this->config->getSystemValue('mail_smtphost', '127.0.0.1'));
183
-		$transport->setPort($this->config->getSystemValue('mail_smtpport', 25));
184
-		if ($this->config->getSystemValue('mail_smtpauth', false)) {
185
-			$transport->setUsername($this->config->getSystemValue('mail_smtpname', ''));
186
-			$transport->setPassword($this->config->getSystemValue('mail_smtppassword', ''));
187
-			$transport->setAuthMode($this->config->getSystemValue('mail_smtpauthtype', 'LOGIN'));
188
-		}
189
-		$smtpSecurity = $this->config->getSystemValue('mail_smtpsecure', '');
190
-		if (!empty($smtpSecurity)) {
191
-			$transport->setEncryption($smtpSecurity);
192
-		}
193
-		$transport->start();
194
-		return $transport;
195
-	}
196
-
197
-	/**
198
-	 * Returns the sendmail transport
199
-	 *
200
-	 * @return \Swift_SendmailTransport
201
-	 */
202
-	protected function getSendMailInstance() {
203
-		switch ($this->config->getSystemValue('mail_smtpmode', 'sendmail')) {
204
-			case 'qmail':
205
-				$binaryPath = '/var/qmail/bin/sendmail';
206
-				break;
207
-			default:
208
-				$binaryPath = '/usr/sbin/sendmail';
209
-				break;
210
-		}
211
-
212
-		return \Swift_SendmailTransport::newInstance($binaryPath . ' -bs');
213
-	}
214
-
215
-	/**
216
-	 * Returns the mail transport
217
-	 *
218
-	 * @return \Swift_MailTransport
219
-	 */
220
-	protected function getMailInstance() {
221
-		return \Swift_MailTransport::newInstance();
222
-	}
48
+    /** @var \Swift_SmtpTransport|\Swift_SendmailTransport|\Swift_MailTransport Cached transport */
49
+    private $instance = null;
50
+    /** @var IConfig */
51
+    private $config;
52
+    /** @var ILogger */
53
+    private $logger;
54
+    /** @var \OC_Defaults */
55
+    private $defaults;
56
+
57
+    /**
58
+     * @param IConfig $config
59
+     * @param ILogger $logger
60
+     * @param \OC_Defaults $defaults
61
+     */
62
+    function __construct(IConfig $config,
63
+                            ILogger $logger,
64
+                            \OC_Defaults $defaults) {
65
+        $this->config = $config;
66
+        $this->logger = $logger;
67
+        $this->defaults = $defaults;
68
+    }
69
+
70
+    /**
71
+     * Creates a new message object that can be passed to send()
72
+     *
73
+     * @return Message
74
+     */
75
+    public function createMessage() {
76
+        return new Message(new \Swift_Message());
77
+    }
78
+
79
+    /**
80
+     * Send the specified message. Also sets the from address to the value defined in config.php
81
+     * if no-one has been passed.
82
+     *
83
+     * @param Message $message Message to send
84
+     * @return string[] Array with failed recipients. Be aware that this depends on the used mail backend and
85
+     * therefore should be considered
86
+     * @throws \Exception In case it was not possible to send the message. (for example if an invalid mail address
87
+     * has been supplied.)
88
+     */
89
+    public function send(Message $message) {
90
+        $debugMode = $this->config->getSystemValue('mail_smtpdebug', false);
91
+
92
+        if (sizeof($message->getFrom()) === 0) {
93
+            $message->setFrom([\OCP\Util::getDefaultEmailAddress($this->defaults->getName())]);
94
+        }
95
+
96
+        $failedRecipients = [];
97
+
98
+        $mailer = $this->getInstance();
99
+
100
+        // Enable logger if debug mode is enabled
101
+        if($debugMode) {
102
+            $mailLogger = new \Swift_Plugins_Loggers_ArrayLogger();
103
+            $mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($mailLogger));
104
+        }
105
+
106
+        $mailer->send($message->getSwiftMessage(), $failedRecipients);
107
+
108
+        // Debugging logging
109
+        $logMessage = sprintf('Sent mail to "%s" with subject "%s"', print_r($message->getTo(), true), $message->getSubject());
110
+        $this->logger->debug($logMessage, ['app' => 'core']);
111
+        if($debugMode && isset($mailLogger)) {
112
+            $this->logger->debug($mailLogger->dump(), ['app' => 'core']);
113
+        }
114
+
115
+        return $failedRecipients;
116
+    }
117
+
118
+    /**
119
+     * Checks if an e-mail address is valid
120
+     *
121
+     * @param string $email Email address to be validated
122
+     * @return bool True if the mail address is valid, false otherwise
123
+     */
124
+    public function validateMailAddress($email) {
125
+        return \Swift_Validate::email($this->convertEmail($email));
126
+    }
127
+
128
+    /**
129
+     * SwiftMailer does currently not work with IDN domains, this function therefore converts the domains
130
+     *
131
+     * FIXME: Remove this once SwiftMailer supports IDN
132
+     *
133
+     * @param string $email
134
+     * @return string Converted mail address if `idn_to_ascii` exists
135
+     */
136
+    protected function convertEmail($email) {
137
+        if (!function_exists('idn_to_ascii') || strpos($email, '@') === false) {
138
+            return $email;
139
+        }
140
+
141
+        list($name, $domain) = explode('@', $email, 2);
142
+        $domain = idn_to_ascii($domain);
143
+        return $name.'@'.$domain;
144
+    }
145
+
146
+    /**
147
+     * Returns whatever transport is configured within the config
148
+     *
149
+     * @return \Swift_SmtpTransport|\Swift_SendmailTransport|\Swift_MailTransport
150
+     */
151
+    protected function getInstance() {
152
+        if (!is_null($this->instance)) {
153
+            return $this->instance;
154
+        }
155
+
156
+        switch ($this->config->getSystemValue('mail_smtpmode', 'php')) {
157
+            case 'smtp':
158
+                $this->instance = $this->getSMTPInstance();
159
+                break;
160
+            case 'sendmail':
161
+                // FIXME: Move into the return statement but requires proper testing
162
+                //       for SMTP and mail as well. Thus not really doable for a
163
+                //       minor release.
164
+                $this->instance = \Swift_Mailer::newInstance($this->getSendMailInstance());
165
+                break;
166
+            default:
167
+                $this->instance = $this->getMailInstance();
168
+                break;
169
+        }
170
+
171
+        return $this->instance;
172
+    }
173
+
174
+    /**
175
+     * Returns the SMTP transport
176
+     *
177
+     * @return \Swift_SmtpTransport
178
+     */
179
+    protected function getSmtpInstance() {
180
+        $transport = \Swift_SmtpTransport::newInstance();
181
+        $transport->setTimeout($this->config->getSystemValue('mail_smtptimeout', 10));
182
+        $transport->setHost($this->config->getSystemValue('mail_smtphost', '127.0.0.1'));
183
+        $transport->setPort($this->config->getSystemValue('mail_smtpport', 25));
184
+        if ($this->config->getSystemValue('mail_smtpauth', false)) {
185
+            $transport->setUsername($this->config->getSystemValue('mail_smtpname', ''));
186
+            $transport->setPassword($this->config->getSystemValue('mail_smtppassword', ''));
187
+            $transport->setAuthMode($this->config->getSystemValue('mail_smtpauthtype', 'LOGIN'));
188
+        }
189
+        $smtpSecurity = $this->config->getSystemValue('mail_smtpsecure', '');
190
+        if (!empty($smtpSecurity)) {
191
+            $transport->setEncryption($smtpSecurity);
192
+        }
193
+        $transport->start();
194
+        return $transport;
195
+    }
196
+
197
+    /**
198
+     * Returns the sendmail transport
199
+     *
200
+     * @return \Swift_SendmailTransport
201
+     */
202
+    protected function getSendMailInstance() {
203
+        switch ($this->config->getSystemValue('mail_smtpmode', 'sendmail')) {
204
+            case 'qmail':
205
+                $binaryPath = '/var/qmail/bin/sendmail';
206
+                break;
207
+            default:
208
+                $binaryPath = '/usr/sbin/sendmail';
209
+                break;
210
+        }
211
+
212
+        return \Swift_SendmailTransport::newInstance($binaryPath . ' -bs');
213
+    }
214
+
215
+    /**
216
+     * Returns the mail transport
217
+     *
218
+     * @return \Swift_MailTransport
219
+     */
220
+    protected function getMailInstance() {
221
+        return \Swift_MailTransport::newInstance();
222
+    }
223 223
 
224 224
 }
Please login to merge, or discard this patch.
lib/private/NavigationManager.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -82,7 +82,7 @@
 block discarded – undo
82 82
 		}
83 83
 
84 84
 		$entry['active'] = false;
85
-		if(!isset($entry['icon'])) {
85
+		if (!isset($entry['icon'])) {
86 86
 			$entry['icon'] = '';
87 87
 		}
88 88
 		$this->entries[] = $entry;
Please login to merge, or discard this patch.
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -30,67 +30,67 @@
 block discarded – undo
30 30
  * Manages the ownCloud navigation
31 31
  */
32 32
 class NavigationManager implements \OCP\INavigationManager {
33
-	protected $entries = array();
34
-	protected $closureEntries = array();
35
-	protected $activeEntry;
33
+    protected $entries = array();
34
+    protected $closureEntries = array();
35
+    protected $activeEntry;
36 36
 
37
-	/**
38
-	 * Creates a new navigation entry
39
-	 *
40
-	 * @param array|\Closure $entry Array containing: id, name, order, icon and href key
41
-	 *					The use of a closure is preferred, because it will avoid
42
-	 * 					loading the routing of your app, unless required.
43
-	 * @return void
44
-	 */
45
-	public function add($entry) {
46
-		if ($entry instanceof \Closure) {
47
-			$this->closureEntries[] = $entry;
48
-			return;
49
-		}
37
+    /**
38
+     * Creates a new navigation entry
39
+     *
40
+     * @param array|\Closure $entry Array containing: id, name, order, icon and href key
41
+     *					The use of a closure is preferred, because it will avoid
42
+     * 					loading the routing of your app, unless required.
43
+     * @return void
44
+     */
45
+    public function add($entry) {
46
+        if ($entry instanceof \Closure) {
47
+            $this->closureEntries[] = $entry;
48
+            return;
49
+        }
50 50
 
51
-		$entry['active'] = false;
52
-		if(!isset($entry['icon'])) {
53
-			$entry['icon'] = '';
54
-		}
55
-		$this->entries[] = $entry;
56
-	}
51
+        $entry['active'] = false;
52
+        if(!isset($entry['icon'])) {
53
+            $entry['icon'] = '';
54
+        }
55
+        $this->entries[] = $entry;
56
+    }
57 57
 
58
-	/**
59
-	 * returns all the added Menu entries
60
-	 * @return array an array of the added entries
61
-	 */
62
-	public function getAll() {
63
-		foreach ($this->closureEntries as $c) {
64
-			$this->add($c());
65
-		}
66
-		$this->closureEntries = array();
67
-		return $this->entries;
68
-	}
58
+    /**
59
+     * returns all the added Menu entries
60
+     * @return array an array of the added entries
61
+     */
62
+    public function getAll() {
63
+        foreach ($this->closureEntries as $c) {
64
+            $this->add($c());
65
+        }
66
+        $this->closureEntries = array();
67
+        return $this->entries;
68
+    }
69 69
 
70
-	/**
71
-	 * removes all the entries
72
-	 */
73
-	public function clear() {
74
-		$this->entries = array();
75
-		$this->closureEntries = array();
76
-	}
70
+    /**
71
+     * removes all the entries
72
+     */
73
+    public function clear() {
74
+        $this->entries = array();
75
+        $this->closureEntries = array();
76
+    }
77 77
 
78
-	/**
79
-	 * Sets the current navigation entry of the currently running app
80
-	 * @param string $id of the app entry to activate (from added $entry)
81
-	 */
82
-	public function setActiveEntry($id) {
83
-		$this->activeEntry = $id;
84
-	}
78
+    /**
79
+     * Sets the current navigation entry of the currently running app
80
+     * @param string $id of the app entry to activate (from added $entry)
81
+     */
82
+    public function setActiveEntry($id) {
83
+        $this->activeEntry = $id;
84
+    }
85 85
 
86
-	/**
87
-	 * gets the active Menu entry
88
-	 * @return string id or empty string
89
-	 *
90
-	 * This function returns the id of the active navigation entry (set by
91
-	 * setActiveEntry
92
-	 */
93
-	public function getActiveEntry() {
94
-		return $this->activeEntry;
95
-	}
86
+    /**
87
+     * gets the active Menu entry
88
+     * @return string id or empty string
89
+     *
90
+     * This function returns the id of the active navigation entry (set by
91
+     * setActiveEntry
92
+     */
93
+    public function getActiveEntry() {
94
+        return $this->activeEntry;
95
+    }
96 96
 }
Please login to merge, or discard this patch.
lib/private/Share/Helper.php 2 patches
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -93,14 +93,14 @@  discard block
 block discarded – undo
93 93
 			$params = array();
94 94
 			if (count($ids) == 1 && isset($uidOwner)) {
95 95
 				// FIXME: don't concat $parents, use Docrine's PARAM_INT_ARRAY approach
96
-				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
97
-					'`item_target`, `file_target`, `parent` ' .
98
-					'FROM `*PREFIX*share` ' .
96
+				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, '.
97
+					'`item_target`, `file_target`, `parent` '.
98
+					'FROM `*PREFIX*share` '.
99 99
 					'WHERE `parent` IN ('.$parents.') AND `uid_owner` = ? ';
100 100
 				$params[] = $uidOwner;
101 101
 			} else {
102
-				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
103
-					'`item_target`, `file_target`, `parent`, `uid_owner` ' .
102
+				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, '.
103
+					'`item_target`, `file_target`, `parent`, `uid_owner` '.
104 104
 					'FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') ';
105 105
 			}
106 106
 			if ($excludeGroupChildren) {
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
 					'shareWith' => $item['share_with'],
118 118
 					'itemTarget' => $item['item_target'],
119 119
 					'itemType' => $item['item_type'],
120
-					'shareType' => (int)$item['share_type'],
120
+					'shareType' => (int) $item['share_type'],
121 121
 				);
122 122
 				if (isset($item['file_target'])) {
123 123
 					$tmpItem['fileTarget'] = $item['file_target'];
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
 		if ($defaultExpireDate === 'yes') {
169 169
 			$enforceExpireDate = $config->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
170 170
 			$defaultExpireSettings['defaultExpireDateSet'] = true;
171
-			$defaultExpireSettings['expireAfterDays'] = (int)($config->getAppValue('core', 'shareapi_expire_after_n_days', '7'));
171
+			$defaultExpireSettings['expireAfterDays'] = (int) ($config->getAppValue('core', 'shareapi_expire_after_n_days', '7'));
172 172
 			$defaultExpireSettings['enforceExpireDate'] = $enforceExpireDate === 'yes' ? true : false;
173 173
 		}
174 174
 
Please login to merge, or discard this patch.
Indentation   +291 added lines, -291 removed lines patch added patch discarded remove patch
@@ -33,295 +33,295 @@
 block discarded – undo
33 33
 
34 34
 class Helper extends \OC\Share\Constants {
35 35
 
36
-	/**
37
-	 * Generate a unique target for the item
38
-	 * @param string $itemType
39
-	 * @param string $itemSource
40
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
41
-	 * @param string $shareWith User or group the item is being shared with
42
-	 * @param string $uidOwner User that is the owner of shared item
43
-	 * @param string $suggestedTarget The suggested target originating from a reshare (optional)
44
-	 * @param int $groupParent The id of the parent group share (optional)
45
-	 * @throws \Exception
46
-	 * @return string Item target
47
-	 */
48
-	public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
49
-		// FIXME: $uidOwner and $groupParent seems to be unused
50
-		$backend = \OC\Share\Share::getBackend($itemType);
51
-		if ($shareType === self::SHARE_TYPE_LINK || $shareType === self::SHARE_TYPE_REMOTE) {
52
-			if (isset($suggestedTarget)) {
53
-				return $suggestedTarget;
54
-			}
55
-			return $backend->generateTarget($itemSource, false);
56
-		} else {
57
-			if ($shareType == self::SHARE_TYPE_USER) {
58
-				// Share with is a user, so set share type to user and groups
59
-				$shareType = self::$shareTypeUserAndGroups;
60
-			}
61
-
62
-			// Check if suggested target exists first
63
-			if (!isset($suggestedTarget)) {
64
-				$suggestedTarget = $itemSource;
65
-			}
66
-			if ($shareType == self::SHARE_TYPE_GROUP) {
67
-				$target = $backend->generateTarget($suggestedTarget, false);
68
-			} else {
69
-				$target = $backend->generateTarget($suggestedTarget, $shareWith);
70
-			}
71
-
72
-			return $target;
73
-		}
74
-	}
75
-
76
-	/**
77
-	 * Delete all reshares and group share children of an item
78
-	 * @param int $parent Id of item to delete
79
-	 * @param bool $excludeParent If true, exclude the parent from the delete (optional)
80
-	 * @param string $uidOwner The user that the parent was shared with (optional)
81
-	 * @param int $newParent new parent for the childrens
82
-	 * @param bool $excludeGroupChildren exclude group children elements
83
-	 */
84
-	public static function delete($parent, $excludeParent = false, $uidOwner = null, $newParent = null, $excludeGroupChildren = false) {
85
-		$ids = array($parent);
86
-		$deletedItems = array();
87
-		$changeParent = array();
88
-		$parents = array($parent);
89
-		while (!empty($parents)) {
90
-			$parents = "'".implode("','", $parents)."'";
91
-			// Check the owner on the first search of reshares, useful for
92
-			// finding and deleting the reshares by a single user of a group share
93
-			$params = array();
94
-			if (count($ids) == 1 && isset($uidOwner)) {
95
-				// FIXME: don't concat $parents, use Docrine's PARAM_INT_ARRAY approach
96
-				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
97
-					'`item_target`, `file_target`, `parent` ' .
98
-					'FROM `*PREFIX*share` ' .
99
-					'WHERE `parent` IN ('.$parents.') AND `uid_owner` = ? ';
100
-				$params[] = $uidOwner;
101
-			} else {
102
-				$queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
103
-					'`item_target`, `file_target`, `parent`, `uid_owner` ' .
104
-					'FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') ';
105
-			}
106
-			if ($excludeGroupChildren) {
107
-				$queryString .= ' AND `share_type` != ?';
108
-				$params[] = self::$shareTypeGroupUserUnique;
109
-			}
110
-			$query = \OC_DB::prepare($queryString);
111
-			$result = $query->execute($params);
112
-			// Reset parents array, only go through loop again if items are found
113
-			$parents = array();
114
-			while ($item = $result->fetchRow()) {
115
-				$tmpItem = array(
116
-					'id' => $item['id'],
117
-					'shareWith' => $item['share_with'],
118
-					'itemTarget' => $item['item_target'],
119
-					'itemType' => $item['item_type'],
120
-					'shareType' => (int)$item['share_type'],
121
-				);
122
-				if (isset($item['file_target'])) {
123
-					$tmpItem['fileTarget'] = $item['file_target'];
124
-				}
125
-				// if we have a new parent for the child we remember the child
126
-				// to update the parent, if not we add it to the list of items
127
-				// which should be deleted
128
-				if ($newParent !== null) {
129
-					$changeParent[] = $item['id'];
130
-				} else {
131
-					$deletedItems[] = $tmpItem;
132
-					$ids[] = $item['id'];
133
-					$parents[] = $item['id'];
134
-				}
135
-			}
136
-		}
137
-		if ($excludeParent) {
138
-			unset($ids[0]);
139
-		}
140
-
141
-		if (!empty($changeParent)) {
142
-			$idList = "'".implode("','", $changeParent)."'";
143
-			$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` IN ('.$idList.')');
144
-			$query->execute(array($newParent));
145
-		}
146
-
147
-		if (!empty($ids)) {
148
-			$idList = "'".implode("','", $ids)."'";
149
-			$query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$idList.')');
150
-			$query->execute();
151
-		}
152
-
153
-		return $deletedItems;
154
-	}
155
-
156
-	/**
157
-	 * get default expire settings defined by the admin
158
-	 * @return array contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
159
-	 */
160
-	public static function getDefaultExpireSetting() {
161
-
162
-		$config = \OC::$server->getConfig();
163
-
164
-		$defaultExpireSettings = array('defaultExpireDateSet' => false);
165
-
166
-		// get default expire settings
167
-		$defaultExpireDate = $config->getAppValue('core', 'shareapi_default_expire_date', 'no');
168
-		if ($defaultExpireDate === 'yes') {
169
-			$enforceExpireDate = $config->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
170
-			$defaultExpireSettings['defaultExpireDateSet'] = true;
171
-			$defaultExpireSettings['expireAfterDays'] = (int)($config->getAppValue('core', 'shareapi_expire_after_n_days', '7'));
172
-			$defaultExpireSettings['enforceExpireDate'] = $enforceExpireDate === 'yes' ? true : false;
173
-		}
174
-
175
-		return $defaultExpireSettings;
176
-	}
177
-
178
-	public static function calcExpireDate() {
179
-		$expireAfter = \OC\Share\Share::getExpireInterval() * 24 * 60 * 60;
180
-		$expireAt = time() + $expireAfter;
181
-		$date = new \DateTime();
182
-		$date->setTimestamp($expireAt);
183
-		$date->setTime(0, 0, 0);
184
-		//$dateString = $date->format('Y-m-d') . ' 00:00:00';
185
-
186
-		return $date;
187
-
188
-	}
189
-
190
-	/**
191
-	 * calculate expire date
192
-	 * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
193
-	 * @param int $creationTime timestamp when the share was created
194
-	 * @param int $userExpireDate expire timestamp set by the user
195
-	 * @return mixed integer timestamp or False
196
-	 */
197
-	public static function calculateExpireDate($defaultExpireSettings, $creationTime, $userExpireDate = null) {
198
-
199
-		$expires = false;
200
-		$defaultExpires = null;
201
-
202
-		if (!empty($defaultExpireSettings['defaultExpireDateSet'])) {
203
-			$defaultExpires = $creationTime + $defaultExpireSettings['expireAfterDays'] * 86400;
204
-		}
205
-
206
-
207
-		if (isset($userExpireDate)) {
208
-			// if the admin decided to enforce the default expire date then we only take
209
-			// the user defined expire date of it is before the default expire date
210
-			if ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
211
-				$expires = min($userExpireDate, $defaultExpires);
212
-			} else {
213
-				$expires = $userExpireDate;
214
-			}
215
-		} else if ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
216
-			$expires = $defaultExpires;
217
-		}
218
-
219
-		return $expires;
220
-	}
221
-
222
-	/**
223
-	 * Strips away a potential file names and trailing slashes:
224
-	 * - http://localhost
225
-	 * - http://localhost/
226
-	 * - http://localhost/index.php
227
-	 * - http://localhost/index.php/s/{shareToken}
228
-	 *
229
-	 * all return: http://localhost
230
-	 *
231
-	 * @param string $remote
232
-	 * @return string
233
-	 */
234
-	protected static function fixRemoteURL($remote) {
235
-		$remote = str_replace('\\', '/', $remote);
236
-		if ($fileNamePosition = strpos($remote, '/index.php')) {
237
-			$remote = substr($remote, 0, $fileNamePosition);
238
-		}
239
-		$remote = rtrim($remote, '/');
240
-
241
-		return $remote;
242
-	}
243
-
244
-	/**
245
-	 * split user and remote from federated cloud id
246
-	 *
247
-	 * @param string $id
248
-	 * @return string[]
249
-	 * @throws HintException
250
-	 */
251
-	public static function splitUserRemote($id) {
252
-		if (strpos($id, '@') === false) {
253
-			$l = \OC::$server->getL10N('core');
254
-			$hint = $l->t('Invalid Federated Cloud ID');
255
-			throw new HintException('Invalid Federated Cloud ID', $hint);
256
-		}
257
-
258
-		// Find the first character that is not allowed in user names
259
-		$id = str_replace('\\', '/', $id);
260
-		$posSlash = strpos($id, '/');
261
-		$posColon = strpos($id, ':');
262
-
263
-		if ($posSlash === false && $posColon === false) {
264
-			$invalidPos = strlen($id);
265
-		} else if ($posSlash === false) {
266
-			$invalidPos = $posColon;
267
-		} else if ($posColon === false) {
268
-			$invalidPos = $posSlash;
269
-		} else {
270
-			$invalidPos = min($posSlash, $posColon);
271
-		}
272
-
273
-		// Find the last @ before $invalidPos
274
-		$pos = $lastAtPos = 0;
275
-		while ($lastAtPos !== false && $lastAtPos <= $invalidPos) {
276
-			$pos = $lastAtPos;
277
-			$lastAtPos = strpos($id, '@', $pos + 1);
278
-		}
279
-
280
-		if ($pos !== false) {
281
-			$user = substr($id, 0, $pos);
282
-			$remote = substr($id, $pos + 1);
283
-			$remote = self::fixRemoteURL($remote);
284
-			if (!empty($user) && !empty($remote)) {
285
-				return array($user, $remote);
286
-			}
287
-		}
288
-
289
-		$l = \OC::$server->getL10N('core');
290
-		$hint = $l->t('Invalid Federated Cloud ID');
291
-		throw new HintException('Invalid Fededrated Cloud ID', $hint);
292
-	}
293
-
294
-	/**
295
-	 * check if two federated cloud IDs refer to the same user
296
-	 *
297
-	 * @param string $user1
298
-	 * @param string $server1
299
-	 * @param string $user2
300
-	 * @param string $server2
301
-	 * @return bool true if both users and servers are the same
302
-	 */
303
-	public static function isSameUserOnSameServer($user1, $server1, $user2, $server2) {
304
-		$normalizedServer1 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server1));
305
-		$normalizedServer2 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server2));
306
-
307
-		if (rtrim($normalizedServer1, '/') === rtrim($normalizedServer2, '/')) {
308
-			// FIXME this should be a method in the user management instead
309
-			\OCP\Util::emitHook(
310
-					'\OCA\Files_Sharing\API\Server2Server',
311
-					'preLoginNameUsedAsUserName',
312
-					array('uid' => &$user1)
313
-			);
314
-			\OCP\Util::emitHook(
315
-					'\OCA\Files_Sharing\API\Server2Server',
316
-					'preLoginNameUsedAsUserName',
317
-					array('uid' => &$user2)
318
-			);
319
-
320
-			if ($user1 === $user2) {
321
-				return true;
322
-			}
323
-		}
324
-
325
-		return false;
326
-	}
36
+    /**
37
+     * Generate a unique target for the item
38
+     * @param string $itemType
39
+     * @param string $itemSource
40
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
41
+     * @param string $shareWith User or group the item is being shared with
42
+     * @param string $uidOwner User that is the owner of shared item
43
+     * @param string $suggestedTarget The suggested target originating from a reshare (optional)
44
+     * @param int $groupParent The id of the parent group share (optional)
45
+     * @throws \Exception
46
+     * @return string Item target
47
+     */
48
+    public static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $suggestedTarget = null, $groupParent = null) {
49
+        // FIXME: $uidOwner and $groupParent seems to be unused
50
+        $backend = \OC\Share\Share::getBackend($itemType);
51
+        if ($shareType === self::SHARE_TYPE_LINK || $shareType === self::SHARE_TYPE_REMOTE) {
52
+            if (isset($suggestedTarget)) {
53
+                return $suggestedTarget;
54
+            }
55
+            return $backend->generateTarget($itemSource, false);
56
+        } else {
57
+            if ($shareType == self::SHARE_TYPE_USER) {
58
+                // Share with is a user, so set share type to user and groups
59
+                $shareType = self::$shareTypeUserAndGroups;
60
+            }
61
+
62
+            // Check if suggested target exists first
63
+            if (!isset($suggestedTarget)) {
64
+                $suggestedTarget = $itemSource;
65
+            }
66
+            if ($shareType == self::SHARE_TYPE_GROUP) {
67
+                $target = $backend->generateTarget($suggestedTarget, false);
68
+            } else {
69
+                $target = $backend->generateTarget($suggestedTarget, $shareWith);
70
+            }
71
+
72
+            return $target;
73
+        }
74
+    }
75
+
76
+    /**
77
+     * Delete all reshares and group share children of an item
78
+     * @param int $parent Id of item to delete
79
+     * @param bool $excludeParent If true, exclude the parent from the delete (optional)
80
+     * @param string $uidOwner The user that the parent was shared with (optional)
81
+     * @param int $newParent new parent for the childrens
82
+     * @param bool $excludeGroupChildren exclude group children elements
83
+     */
84
+    public static function delete($parent, $excludeParent = false, $uidOwner = null, $newParent = null, $excludeGroupChildren = false) {
85
+        $ids = array($parent);
86
+        $deletedItems = array();
87
+        $changeParent = array();
88
+        $parents = array($parent);
89
+        while (!empty($parents)) {
90
+            $parents = "'".implode("','", $parents)."'";
91
+            // Check the owner on the first search of reshares, useful for
92
+            // finding and deleting the reshares by a single user of a group share
93
+            $params = array();
94
+            if (count($ids) == 1 && isset($uidOwner)) {
95
+                // FIXME: don't concat $parents, use Docrine's PARAM_INT_ARRAY approach
96
+                $queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
97
+                    '`item_target`, `file_target`, `parent` ' .
98
+                    'FROM `*PREFIX*share` ' .
99
+                    'WHERE `parent` IN ('.$parents.') AND `uid_owner` = ? ';
100
+                $params[] = $uidOwner;
101
+            } else {
102
+                $queryString = 'SELECT `id`, `share_with`, `item_type`, `share_type`, ' .
103
+                    '`item_target`, `file_target`, `parent`, `uid_owner` ' .
104
+                    'FROM `*PREFIX*share` WHERE `parent` IN ('.$parents.') ';
105
+            }
106
+            if ($excludeGroupChildren) {
107
+                $queryString .= ' AND `share_type` != ?';
108
+                $params[] = self::$shareTypeGroupUserUnique;
109
+            }
110
+            $query = \OC_DB::prepare($queryString);
111
+            $result = $query->execute($params);
112
+            // Reset parents array, only go through loop again if items are found
113
+            $parents = array();
114
+            while ($item = $result->fetchRow()) {
115
+                $tmpItem = array(
116
+                    'id' => $item['id'],
117
+                    'shareWith' => $item['share_with'],
118
+                    'itemTarget' => $item['item_target'],
119
+                    'itemType' => $item['item_type'],
120
+                    'shareType' => (int)$item['share_type'],
121
+                );
122
+                if (isset($item['file_target'])) {
123
+                    $tmpItem['fileTarget'] = $item['file_target'];
124
+                }
125
+                // if we have a new parent for the child we remember the child
126
+                // to update the parent, if not we add it to the list of items
127
+                // which should be deleted
128
+                if ($newParent !== null) {
129
+                    $changeParent[] = $item['id'];
130
+                } else {
131
+                    $deletedItems[] = $tmpItem;
132
+                    $ids[] = $item['id'];
133
+                    $parents[] = $item['id'];
134
+                }
135
+            }
136
+        }
137
+        if ($excludeParent) {
138
+            unset($ids[0]);
139
+        }
140
+
141
+        if (!empty($changeParent)) {
142
+            $idList = "'".implode("','", $changeParent)."'";
143
+            $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `parent` = ? WHERE `id` IN ('.$idList.')');
144
+            $query->execute(array($newParent));
145
+        }
146
+
147
+        if (!empty($ids)) {
148
+            $idList = "'".implode("','", $ids)."'";
149
+            $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `id` IN ('.$idList.')');
150
+            $query->execute();
151
+        }
152
+
153
+        return $deletedItems;
154
+    }
155
+
156
+    /**
157
+     * get default expire settings defined by the admin
158
+     * @return array contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
159
+     */
160
+    public static function getDefaultExpireSetting() {
161
+
162
+        $config = \OC::$server->getConfig();
163
+
164
+        $defaultExpireSettings = array('defaultExpireDateSet' => false);
165
+
166
+        // get default expire settings
167
+        $defaultExpireDate = $config->getAppValue('core', 'shareapi_default_expire_date', 'no');
168
+        if ($defaultExpireDate === 'yes') {
169
+            $enforceExpireDate = $config->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
170
+            $defaultExpireSettings['defaultExpireDateSet'] = true;
171
+            $defaultExpireSettings['expireAfterDays'] = (int)($config->getAppValue('core', 'shareapi_expire_after_n_days', '7'));
172
+            $defaultExpireSettings['enforceExpireDate'] = $enforceExpireDate === 'yes' ? true : false;
173
+        }
174
+
175
+        return $defaultExpireSettings;
176
+    }
177
+
178
+    public static function calcExpireDate() {
179
+        $expireAfter = \OC\Share\Share::getExpireInterval() * 24 * 60 * 60;
180
+        $expireAt = time() + $expireAfter;
181
+        $date = new \DateTime();
182
+        $date->setTimestamp($expireAt);
183
+        $date->setTime(0, 0, 0);
184
+        //$dateString = $date->format('Y-m-d') . ' 00:00:00';
185
+
186
+        return $date;
187
+
188
+    }
189
+
190
+    /**
191
+     * calculate expire date
192
+     * @param array $defaultExpireSettings contains 'defaultExpireDateSet', 'enforceExpireDate', 'expireAfterDays'
193
+     * @param int $creationTime timestamp when the share was created
194
+     * @param int $userExpireDate expire timestamp set by the user
195
+     * @return mixed integer timestamp or False
196
+     */
197
+    public static function calculateExpireDate($defaultExpireSettings, $creationTime, $userExpireDate = null) {
198
+
199
+        $expires = false;
200
+        $defaultExpires = null;
201
+
202
+        if (!empty($defaultExpireSettings['defaultExpireDateSet'])) {
203
+            $defaultExpires = $creationTime + $defaultExpireSettings['expireAfterDays'] * 86400;
204
+        }
205
+
206
+
207
+        if (isset($userExpireDate)) {
208
+            // if the admin decided to enforce the default expire date then we only take
209
+            // the user defined expire date of it is before the default expire date
210
+            if ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
211
+                $expires = min($userExpireDate, $defaultExpires);
212
+            } else {
213
+                $expires = $userExpireDate;
214
+            }
215
+        } else if ($defaultExpires && !empty($defaultExpireSettings['enforceExpireDate'])) {
216
+            $expires = $defaultExpires;
217
+        }
218
+
219
+        return $expires;
220
+    }
221
+
222
+    /**
223
+     * Strips away a potential file names and trailing slashes:
224
+     * - http://localhost
225
+     * - http://localhost/
226
+     * - http://localhost/index.php
227
+     * - http://localhost/index.php/s/{shareToken}
228
+     *
229
+     * all return: http://localhost
230
+     *
231
+     * @param string $remote
232
+     * @return string
233
+     */
234
+    protected static function fixRemoteURL($remote) {
235
+        $remote = str_replace('\\', '/', $remote);
236
+        if ($fileNamePosition = strpos($remote, '/index.php')) {
237
+            $remote = substr($remote, 0, $fileNamePosition);
238
+        }
239
+        $remote = rtrim($remote, '/');
240
+
241
+        return $remote;
242
+    }
243
+
244
+    /**
245
+     * split user and remote from federated cloud id
246
+     *
247
+     * @param string $id
248
+     * @return string[]
249
+     * @throws HintException
250
+     */
251
+    public static function splitUserRemote($id) {
252
+        if (strpos($id, '@') === false) {
253
+            $l = \OC::$server->getL10N('core');
254
+            $hint = $l->t('Invalid Federated Cloud ID');
255
+            throw new HintException('Invalid Federated Cloud ID', $hint);
256
+        }
257
+
258
+        // Find the first character that is not allowed in user names
259
+        $id = str_replace('\\', '/', $id);
260
+        $posSlash = strpos($id, '/');
261
+        $posColon = strpos($id, ':');
262
+
263
+        if ($posSlash === false && $posColon === false) {
264
+            $invalidPos = strlen($id);
265
+        } else if ($posSlash === false) {
266
+            $invalidPos = $posColon;
267
+        } else if ($posColon === false) {
268
+            $invalidPos = $posSlash;
269
+        } else {
270
+            $invalidPos = min($posSlash, $posColon);
271
+        }
272
+
273
+        // Find the last @ before $invalidPos
274
+        $pos = $lastAtPos = 0;
275
+        while ($lastAtPos !== false && $lastAtPos <= $invalidPos) {
276
+            $pos = $lastAtPos;
277
+            $lastAtPos = strpos($id, '@', $pos + 1);
278
+        }
279
+
280
+        if ($pos !== false) {
281
+            $user = substr($id, 0, $pos);
282
+            $remote = substr($id, $pos + 1);
283
+            $remote = self::fixRemoteURL($remote);
284
+            if (!empty($user) && !empty($remote)) {
285
+                return array($user, $remote);
286
+            }
287
+        }
288
+
289
+        $l = \OC::$server->getL10N('core');
290
+        $hint = $l->t('Invalid Federated Cloud ID');
291
+        throw new HintException('Invalid Fededrated Cloud ID', $hint);
292
+    }
293
+
294
+    /**
295
+     * check if two federated cloud IDs refer to the same user
296
+     *
297
+     * @param string $user1
298
+     * @param string $server1
299
+     * @param string $user2
300
+     * @param string $server2
301
+     * @return bool true if both users and servers are the same
302
+     */
303
+    public static function isSameUserOnSameServer($user1, $server1, $user2, $server2) {
304
+        $normalizedServer1 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server1));
305
+        $normalizedServer2 = strtolower(\OC\Share\Share::removeProtocolFromUrl($server2));
306
+
307
+        if (rtrim($normalizedServer1, '/') === rtrim($normalizedServer2, '/')) {
308
+            // FIXME this should be a method in the user management instead
309
+            \OCP\Util::emitHook(
310
+                    '\OCA\Files_Sharing\API\Server2Server',
311
+                    'preLoginNameUsedAsUserName',
312
+                    array('uid' => &$user1)
313
+            );
314
+            \OCP\Util::emitHook(
315
+                    '\OCA\Files_Sharing\API\Server2Server',
316
+                    'preLoginNameUsedAsUserName',
317
+                    array('uid' => &$user2)
318
+            );
319
+
320
+            if ($user1 === $user2) {
321
+                return true;
322
+            }
323
+        }
324
+
325
+        return false;
326
+    }
327 327
 }
Please login to merge, or discard this patch.
lib/private/Share/SearchResultSorter.php 2 patches
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -26,51 +26,51 @@
 block discarded – undo
26 26
 use OCP\ILogger;
27 27
 
28 28
 class SearchResultSorter {
29
-	private $search;
30
-	private $encoding;
31
-	private $key;
32
-	private $log;
29
+    private $search;
30
+    private $encoding;
31
+    private $key;
32
+    private $log;
33 33
 
34
-	/**
35
-	 * @param string $search the search term as was given by the user
36
-	 * @param string $key the array key containing the value that should be compared
37
-	 * against
38
-	 * @param string $encoding optional, encoding to use, defaults to UTF-8
39
-	 * @param ILogger $log optional
40
-	 */
41
-	public function __construct($search, $key, ILogger $log = null, $encoding = 'UTF-8') {
42
-		$this->encoding = $encoding;
43
-		$this->key = $key;
44
-		$this->log = $log;
45
-		$this->search = mb_strtolower($search, $this->encoding);
46
-	}
34
+    /**
35
+     * @param string $search the search term as was given by the user
36
+     * @param string $key the array key containing the value that should be compared
37
+     * against
38
+     * @param string $encoding optional, encoding to use, defaults to UTF-8
39
+     * @param ILogger $log optional
40
+     */
41
+    public function __construct($search, $key, ILogger $log = null, $encoding = 'UTF-8') {
42
+        $this->encoding = $encoding;
43
+        $this->key = $key;
44
+        $this->log = $log;
45
+        $this->search = mb_strtolower($search, $this->encoding);
46
+    }
47 47
 
48
-	/**
49
-	 * User and Group names matching the search term at the beginning shall appear
50
-	 * on top of the share dialog. Following entries in alphabetical order.
51
-	 * Callback function for usort. http://php.net/usort
52
-	 */
53
-	public function sort($a, $b) {
54
-		if(!isset($a[$this->key]) || !isset($b[$this->key])) {
55
-			if(!is_null($this->log)) {
56
-				$this->log->error('Sharing dialogue: cannot sort due to ' .
57
-								  'missing array key', array('app' => 'core'));
58
-			}
59
-			return 0;
60
-		}
61
-		$nameA = mb_strtolower($a[$this->key], $this->encoding);
62
-		$nameB = mb_strtolower($b[$this->key], $this->encoding);
63
-		$i = mb_strpos($nameA, $this->search, 0, $this->encoding);
64
-		$j = mb_strpos($nameB, $this->search, 0, $this->encoding);
48
+    /**
49
+     * User and Group names matching the search term at the beginning shall appear
50
+     * on top of the share dialog. Following entries in alphabetical order.
51
+     * Callback function for usort. http://php.net/usort
52
+     */
53
+    public function sort($a, $b) {
54
+        if(!isset($a[$this->key]) || !isset($b[$this->key])) {
55
+            if(!is_null($this->log)) {
56
+                $this->log->error('Sharing dialogue: cannot sort due to ' .
57
+                                    'missing array key', array('app' => 'core'));
58
+            }
59
+            return 0;
60
+        }
61
+        $nameA = mb_strtolower($a[$this->key], $this->encoding);
62
+        $nameB = mb_strtolower($b[$this->key], $this->encoding);
63
+        $i = mb_strpos($nameA, $this->search, 0, $this->encoding);
64
+        $j = mb_strpos($nameB, $this->search, 0, $this->encoding);
65 65
 
66
-		if($i === $j || $i > 0 && $j > 0) {
67
-			return strcmp(mb_strtolower($nameA, $this->encoding),
68
-						  mb_strtolower($nameB, $this->encoding));
69
-		} elseif ($i === 0) {
70
-			return -1;
71
-		} else {
72
-			return 1;
73
-		}
74
-	}
66
+        if($i === $j || $i > 0 && $j > 0) {
67
+            return strcmp(mb_strtolower($nameA, $this->encoding),
68
+                            mb_strtolower($nameB, $this->encoding));
69
+        } elseif ($i === 0) {
70
+            return -1;
71
+        } else {
72
+            return 1;
73
+        }
74
+    }
75 75
 }
76 76
 
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -51,9 +51,9 @@  discard block
 block discarded – undo
51 51
 	 * Callback function for usort. http://php.net/usort
52 52
 	 */
53 53
 	public function sort($a, $b) {
54
-		if(!isset($a[$this->key]) || !isset($b[$this->key])) {
55
-			if(!is_null($this->log)) {
56
-				$this->log->error('Sharing dialogue: cannot sort due to ' .
54
+		if (!isset($a[$this->key]) || !isset($b[$this->key])) {
55
+			if (!is_null($this->log)) {
56
+				$this->log->error('Sharing dialogue: cannot sort due to '.
57 57
 								  'missing array key', array('app' => 'core'));
58 58
 			}
59 59
 			return 0;
@@ -63,7 +63,7 @@  discard block
 block discarded – undo
63 63
 		$i = mb_strpos($nameA, $this->search, 0, $this->encoding);
64 64
 		$j = mb_strpos($nameB, $this->search, 0, $this->encoding);
65 65
 
66
-		if($i === $j || $i > 0 && $j > 0) {
66
+		if ($i === $j || $i > 0 && $j > 0) {
67 67
 			return strcmp(mb_strtolower($nameA, $this->encoding),
68 68
 						  mb_strtolower($nameB, $this->encoding));
69 69
 		} elseif ($i === 0) {
Please login to merge, or discard this patch.
lib/private/Share/Share.php 2 patches
Spacing   +76 added lines, -76 removed lines patch added patch discarded remove patch
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
 					'collectionOf' => $collectionOf,
92 92
 					'supportedFileExtensions' => $supportedFileExtensions
93 93
 				);
94
-				if(count(self::$backendTypes) === 1) {
94
+				if (count(self::$backendTypes) === 1) {
95 95
 					\OC_Util::addScript('core', 'shareconfigmodel');
96 96
 					\OC_Util::addScript('core', 'shareitemmodel');
97 97
 					\OC_Util::addScript('core', 'sharedialogresharerinfoview');
@@ -170,22 +170,22 @@  discard block
 block discarded – undo
170 170
 		$source = -1;
171 171
 		$cache = $mountPath = false;
172 172
 
173
-		$view = new \OC\Files\View('/' . $ownerUser . '/files');
173
+		$view = new \OC\Files\View('/'.$ownerUser.'/files');
174 174
 		$meta = $view->getFileInfo($path);
175 175
 		if ($meta) {
176
-			$path = substr($meta->getPath(), strlen('/' . $ownerUser . '/files'));
176
+			$path = substr($meta->getPath(), strlen('/'.$ownerUser.'/files'));
177 177
 		} else {
178 178
 			// if the file doesn't exists yet we start with the parent folder
179 179
 			$meta = $view->getFileInfo(dirname($path));
180 180
 		}
181 181
 
182
-		if($meta !== false) {
182
+		if ($meta !== false) {
183 183
 			$source = $meta['fileid'];
184 184
 			$cache = new \OC\Files\Cache\Cache($meta['storage']);
185 185
 
186 186
 			$mountPath = $meta->getMountPoint()->getMountPoint();
187 187
 			if ($mountPath !== false) {
188
-				$mountPath = substr($mountPath, strlen('/' . $ownerUser . '/files'));
188
+				$mountPath = substr($mountPath, strlen('/'.$ownerUser.'/files'));
189 189
 			}
190 190
 		}
191 191
 
@@ -292,10 +292,10 @@  discard block
 block discarded – undo
292 292
 			}
293 293
 
294 294
 			// let's get the parent for the next round
295
-			$meta = $cache->get((int)$source);
295
+			$meta = $cache->get((int) $source);
296 296
 			if ($recursive === true && $meta !== false) {
297 297
 				$paths[$source] = $meta['path'];
298
-				$source = (int)$meta['parent'];
298
+				$source = (int) $meta['parent'];
299 299
 			} else {
300 300
 				$source = -1;
301 301
 			}
@@ -314,7 +314,7 @@  discard block
 block discarded – undo
314 314
 				$query = \OC_DB::prepare(
315 315
 					'SELECT `fileid`, `path`
316 316
 					FROM `*PREFIX*filecache`
317
-					WHERE `fileid` IN (' . implode(',', $fileTargetIDs) . ')'
317
+					WHERE `fileid` IN (' . implode(',', $fileTargetIDs).')'
318 318
 				);
319 319
 				$result = $query->execute();
320 320
 
@@ -329,7 +329,7 @@  discard block
 block discarded – undo
329 329
 								$sharePaths[$uid] = $sharedPath;
330 330
 							} else {
331 331
 								$sharedPath = $shareData['file_target'];
332
-								$sharedPath .= substr($path, strlen($row['path']) -5);
332
+								$sharedPath .= substr($path, strlen($row['path']) - 5);
333 333
 								$sharePaths[$uid] = $sharedPath;
334 334
 							}
335 335
 						}
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
 
422 422
 		$select = self::createSelectStatement(self::FORMAT_NONE, $fileDependent);
423 423
 
424
-		$where .= ' `' . $column . '` = ? AND `item_type` = ? ';
424
+		$where .= ' `'.$column.'` = ? AND `item_type` = ? ';
425 425
 		$arguments = array($itemSource, $itemType);
426 426
 		// for link shares $user === null
427 427
 		if ($user !== null) {
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
 			$arguments[] = $owner;
440 440
 		}
441 441
 
442
-		$query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` '. $fileDependentWhere . $where);
442
+		$query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$fileDependentWhere.$where);
443 443
 
444 444
 		$result = \OC_DB::executeAudited($query, $arguments);
445 445
 
@@ -447,7 +447,7 @@  discard block
 block discarded – undo
447 447
 			if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
448 448
 				continue;
449 449
 			}
450
-			if ($fileDependent && (int)$row['file_parent'] === -1) {
450
+			if ($fileDependent && (int) $row['file_parent'] === -1) {
451 451
 				// if it is a mount point we need to get the path from the mount manager
452 452
 				$mountManager = \OC\Files\Filesystem::getMountManager();
453 453
 				$mountPoint = $mountManager->findByStorageId($row['storage_id']);
@@ -458,7 +458,7 @@  discard block
 block discarded – undo
458 458
 					$row['path'] = $path;
459 459
 				} else {
460 460
 					\OC::$server->getLogger()->warning(
461
-						'Could not resolve mount point for ' . $row['storage_id'],
461
+						'Could not resolve mount point for '.$row['storage_id'],
462 462
 						['app' => 'OCP\Share']
463 463
 					);
464 464
 				}
@@ -467,11 +467,11 @@  discard block
 block discarded – undo
467 467
 		}
468 468
 
469 469
 		//if didn't found a result than let's look for a group share.
470
-		if(empty($shares) && $user !== null) {
470
+		if (empty($shares) && $user !== null) {
471 471
 			$groups = \OC_Group::getUserGroups($user);
472 472
 
473 473
 			if (!empty($groups)) {
474
-				$where = $fileDependentWhere . ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)';
474
+				$where = $fileDependentWhere.' WHERE `'.$column.'` = ? AND `item_type` = ? AND `share_with` in (?)';
475 475
 				$arguments = array($itemSource, $itemType, $groups);
476 476
 				$types = array(null, null, IQueryBuilder::PARAM_STR_ARRAY);
477 477
 
@@ -485,7 +485,7 @@  discard block
 block discarded – undo
485 485
 				// class isn't static anymore...
486 486
 				$conn = \OC::$server->getDatabaseConnection();
487 487
 				$result = $conn->executeQuery(
488
-					'SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where,
488
+					'SELECT '.$select.' FROM `*PREFIX*share` '.$where,
489 489
 					$arguments,
490 490
 					$types
491 491
 				);
@@ -539,7 +539,7 @@  discard block
 block discarded – undo
539 539
 		$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?', 1);
540 540
 		$result = $query->execute(array($token));
541 541
 		if ($result === false) {
542
-			\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage() . ', token=' . $token, \OCP\Util::ERROR);
542
+			\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage().', token='.$token, \OCP\Util::ERROR);
543 543
 		}
544 544
 		$row = $result->fetchRow();
545 545
 		if ($row === false) {
@@ -625,9 +625,9 @@  discard block
 block discarded – undo
625 625
 		$items = self::getItems($itemType, $itemSource, null, null, $uidOwner, self::FORMAT_NONE, null, -1, $includeCollections, false, $checkExpireDate);
626 626
 		if ($items) {
627 627
 			foreach ($items as $item) {
628
-				if ((int)$item['share_type'] === self::SHARE_TYPE_USER) {
628
+				if ((int) $item['share_type'] === self::SHARE_TYPE_USER) {
629 629
 					$users[] = $item['share_with'];
630
-				} else if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
630
+				} else if ((int) $item['share_type'] === self::SHARE_TYPE_GROUP) {
631 631
 					$users = array_merge($users, \OC_Group::usersInGroup($item['share_with']));
632 632
 				}
633 633
 			}
@@ -692,12 +692,12 @@  discard block
 block discarded – undo
692 692
 
693 693
 		//verify that we don't share a folder which already contains a share mount point
694 694
 		if ($itemType === 'folder') {
695
-			$path = '/' . $uidOwner . '/files' . \OC\Files\Filesystem::getPath($itemSource) . '/';
695
+			$path = '/'.$uidOwner.'/files'.\OC\Files\Filesystem::getPath($itemSource).'/';
696 696
 			$mountManager = \OC\Files\Filesystem::getMountManager();
697 697
 			$mounts = $mountManager->findIn($path);
698 698
 			foreach ($mounts as $mount) {
699 699
 				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
700
-					$message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!';
700
+					$message = 'Sharing "'.$itemSourceName.'" failed, because it contains files shared with you!';
701 701
 					\OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG);
702 702
 					throw new \Exception($message);
703 703
 				}
@@ -707,7 +707,7 @@  discard block
 block discarded – undo
707 707
 
708 708
 		// single file shares should never have delete permissions
709 709
 		if ($itemType === 'file') {
710
-			$permissions = (int)$permissions & ~\OCP\Constants::PERMISSION_DELETE;
710
+			$permissions = (int) $permissions & ~\OCP\Constants::PERMISSION_DELETE;
711 711
 		}
712 712
 
713 713
 		//Validate expirationDate
@@ -834,7 +834,7 @@  discard block
 block discarded – undo
834 834
 					} else {
835 835
 						// reuse the already set password, but only if we change permissions
836 836
 						// otherwise the user disabled the password protection
837
-						if ($checkExists && (int)$permissions !== (int)$oldPermissions) {
837
+						if ($checkExists && (int) $permissions !== (int) $oldPermissions) {
838 838
 							$shareWith = $checkExists['share_with'];
839 839
 						}
840 840
 					}
@@ -907,10 +907,10 @@  discard block
 block discarded – undo
907 907
 				throw new \Exception($message_t);
908 908
 			}
909 909
 
910
-			$token = \OC::$server->getSecureRandom()->generate(self::TOKEN_LENGTH, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER .
910
+			$token = \OC::$server->getSecureRandom()->generate(self::TOKEN_LENGTH, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_UPPER.
911 911
 				\OCP\Security\ISecureRandom::CHAR_DIGITS);
912 912
 
913
-			$shareWith = $user . '@' . $remote;
913
+			$shareWith = $user.'@'.$remote;
914 914
 			$shareId = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName);
915 915
 
916 916
 			$send = false;
@@ -961,12 +961,12 @@  discard block
 block discarded – undo
961 961
 		$currentUser = $owner ? $owner : \OC_User::getUser();
962 962
 		foreach ($items as $item) {
963 963
 			// delete the item with the expected share_type and owner
964
-			if ((int)$item['share_type'] === (int)$shareType && $item['uid_owner'] === $currentUser) {
964
+			if ((int) $item['share_type'] === (int) $shareType && $item['uid_owner'] === $currentUser) {
965 965
 				$toDelete = $item;
966 966
 				// if there is more then one result we don't have to delete the children
967 967
 				// but update their parent. For group shares the new parent should always be
968 968
 				// the original group share and not the db entry with the unique name
969
-			} else if ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
969
+			} else if ((int) $item['share_type'] === self::$shareTypeGroupUserUnique) {
970 970
 				$newParent = $item['parent'];
971 971
 			} else {
972 972
 				$newParent = $item['id'];
@@ -988,7 +988,7 @@  discard block
 block discarded – undo
988 988
 	 */
989 989
 	public static function unshareAll($itemType, $itemSource) {
990 990
 		// Get all of the owners of shares of this item.
991
-		$query = \OC_DB::prepare( 'SELECT `uid_owner` from `*PREFIX*share` WHERE `item_type`=? AND `item_source`=?' );
991
+		$query = \OC_DB::prepare('SELECT `uid_owner` from `*PREFIX*share` WHERE `item_type`=? AND `item_source`=?');
992 992
 		$result = $query->execute(array($itemType, $itemSource));
993 993
 		$shares = array();
994 994
 		// Add each owner's shares to the array of all shares for this item.
@@ -1026,9 +1026,9 @@  discard block
 block discarded – undo
1026 1026
 		$uid = \OCP\User::getUser();
1027 1027
 
1028 1028
 		if ($itemType === 'file' || $itemType === 'folder') {
1029
-			$statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `file_' . $originType . '` = ?';
1029
+			$statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `file_'.$originType.'` = ?';
1030 1030
 		} else {
1031
-			$statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `item_' . $originType . '` = ?';
1031
+			$statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `item_'.$originType.'` = ?';
1032 1032
 		}
1033 1033
 
1034 1034
 		$query = \OCP\DB::prepare($statement);
@@ -1040,7 +1040,7 @@  discard block
 block discarded – undo
1040 1040
 
1041 1041
 		$itemUnshared = false;
1042 1042
 		foreach ($shares as $share) {
1043
-			if ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_USER &&
1043
+			if ((int) $share['share_type'] === \OCP\Share::SHARE_TYPE_USER &&
1044 1044
 				$share['share_with'] === $uid) {
1045 1045
 				$deletedShares = Helper::delete($share['id']);
1046 1046
 				$shareTmp = array(
@@ -1048,7 +1048,7 @@  discard block
 block discarded – undo
1048 1048
 					'shareWith' => $share['share_with'],
1049 1049
 					'itemTarget' => $share['item_target'],
1050 1050
 					'itemType' => $share['item_type'],
1051
-					'shareType' => (int)$share['share_type'],
1051
+					'shareType' => (int) $share['share_type'],
1052 1052
 				);
1053 1053
 				if (isset($share['file_target'])) {
1054 1054
 					$shareTmp['fileTarget'] = $share['file_target'];
@@ -1056,11 +1056,11 @@  discard block
 block discarded – undo
1056 1056
 				$listOfUnsharedItems = array_merge($listOfUnsharedItems, $deletedShares, array($shareTmp));
1057 1057
 				$itemUnshared = true;
1058 1058
 				break;
1059
-			} elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
1059
+			} elseif ((int) $share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
1060 1060
 				if (\OC_Group::inGroup($uid, $share['share_with'])) {
1061 1061
 					$groupShare = $share;
1062 1062
 				}
1063
-			} elseif ((int)$share['share_type'] === self::$shareTypeGroupUserUnique &&
1063
+			} elseif ((int) $share['share_type'] === self::$shareTypeGroupUserUnique &&
1064 1064
 				$share['share_with'] === $uid) {
1065 1065
 				$uniqueGroupShare = $share;
1066 1066
 			}
@@ -1080,7 +1080,7 @@  discard block
 block discarded – undo
1080 1080
 				'shareWith' => $groupShare['share_with'],
1081 1081
 				'itemTarget' => $groupShare['item_target'],
1082 1082
 				'itemType' => $groupShare['item_type'],
1083
-				'shareType' => (int)$groupShare['share_type'],
1083
+				'shareType' => (int) $groupShare['share_type'],
1084 1084
 			);
1085 1085
 			if (isset($groupShare['file_target'])) {
1086 1086
 				$shareTmp['fileTarget'] = $groupShare['file_target'];
@@ -1095,7 +1095,7 @@  discard block
 block discarded – undo
1095 1095
 				'shareWith' => $uniqueGroupShare['share_with'],
1096 1096
 				'itemTarget' => $uniqueGroupShare['item_target'],
1097 1097
 				'itemType' => $uniqueGroupShare['item_type'],
1098
-				'shareType' => (int)$uniqueGroupShare['share_type'],
1098
+				'shareType' => (int) $uniqueGroupShare['share_type'],
1099 1099
 			);
1100 1100
 			if (isset($uniqueGroupShare['file_target'])) {
1101 1101
 				$shareTmp['fileTarget'] = $uniqueGroupShare['file_target'];
@@ -1130,7 +1130,7 @@  discard block
 block discarded – undo
1130 1130
 
1131 1131
 		$result = $query->execute(array($status, $itemType, $itemSource, $shareType, $recipient));
1132 1132
 
1133
-		if($result === false) {
1133
+		if ($result === false) {
1134 1134
 			\OCP\Util::writeLog('OCP\Share', 'Couldn\'t set send mail status', \OCP\Util::ERROR);
1135 1135
 		}
1136 1136
 	}
@@ -1151,12 +1151,12 @@  discard block
 block discarded – undo
1151 1151
 
1152 1152
 		$intArrayToLiteralArray = function($intArray, $eb) {
1153 1153
 			return array_map(function($int) use ($eb) {
1154
-				return $eb->literal((int)$int, 'integer');
1154
+				return $eb->literal((int) $int, 'integer');
1155 1155
 			}, $intArray);
1156 1156
 		};
1157 1157
 		$sanitizeItem = function($item) {
1158
-			$item['id'] = (int)$item['id'];
1159
-			$item['premissions'] = (int)$item['permissions'];
1158
+			$item['id'] = (int) $item['id'];
1159
+			$item['premissions'] = (int) $item['permissions'];
1160 1160
 			return $item;
1161 1161
 		};
1162 1162
 
@@ -1174,7 +1174,7 @@  discard block
 block discarded – undo
1174 1174
 
1175 1175
 				$result = $dbresult->fetch();
1176 1176
 				$dbresult->closeCursor();
1177
-				if (~(int)$result['permissions'] & $permissions) {
1177
+				if (~(int) $result['permissions'] & $permissions) {
1178 1178
 					$message = 'Setting permissions for %s failed,'
1179 1179
 						.' because the permissions exceed permissions granted to %s';
1180 1180
 					$message_t = $l->t('Setting permissions for %s failed, because the permissions exceed permissions granted to %s', array($itemSource, \OC_User::getUser()));
@@ -1207,7 +1207,7 @@  discard block
 block discarded – undo
1207 1207
 			$items = [];
1208 1208
 
1209 1209
 			// Check if permissions were removed
1210
-			if ((int)$rootItem['permissions'] & ~$permissions) {
1210
+			if ((int) $rootItem['permissions'] & ~$permissions) {
1211 1211
 				// If share permission is removed all reshares must be deleted
1212 1212
 				if (($rootItem['permissions'] & \OCP\Constants::PERMISSION_SHARE) && (~$permissions & \OCP\Constants::PERMISSION_SHARE)) {
1213 1213
 					// delete all shares, keep parent and group children
@@ -1260,14 +1260,14 @@  discard block
 block discarded – undo
1260 1260
 			 * Permissions were added
1261 1261
 			 * Update all USERGROUP shares. (So group shares where the user moved their mountpoint).
1262 1262
 			 */
1263
-			if ($permissions & ~(int)$rootItem['permissions']) {
1263
+			if ($permissions & ~(int) $rootItem['permissions']) {
1264 1264
 				$qb = $connection->getQueryBuilder();
1265 1265
 				$qb->select('id', 'permissions', 'item_type')
1266 1266
 					->from('share')
1267 1267
 					->where($qb->expr()->eq('parent', $qb->createParameter('parent')))
1268 1268
 					->andWhere($qb->expr()->eq('share_type', $qb->createParameter('share_type')))
1269 1269
 					->andWhere($qb->expr()->neq('permissions', $qb->createParameter('shareDeleted')))
1270
-					->setParameter(':parent', (int)$rootItem['id'])
1270
+					->setParameter(':parent', (int) $rootItem['id'])
1271 1271
 					->setParameter(':share_type', 2)
1272 1272
 					->setParameter(':shareDeleted', 0);
1273 1273
 				$result = $qb->execute();
@@ -1327,7 +1327,7 @@  discard block
 block discarded – undo
1327 1327
 		if ($defaultExpireDateEnforced && $shareTime === null) {
1328 1328
 			$items = self::getItemShared($itemType, $itemSource);
1329 1329
 			$firstItem = reset($items);
1330
-			$shareTime = (int)$firstItem['stime'];
1330
+			$shareTime = (int) $firstItem['stime'];
1331 1331
 		}
1332 1332
 
1333 1333
 		if ($defaultExpireDateEnforced) {
@@ -1335,9 +1335,9 @@  discard block
 block discarded – undo
1335 1335
 			$maxDate = new \DateTime();
1336 1336
 			$maxDate->setTimestamp($shareTime);
1337 1337
 			$maxDays = \OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
1338
-			$maxDate->add(new \DateInterval('P' . $maxDays . 'D'));
1338
+			$maxDate->add(new \DateInterval('P'.$maxDays.'D'));
1339 1339
 			if ($date > $maxDate) {
1340
-				$warning = 'Cannot set expiration date. Shares cannot expire later than ' . $maxDays . ' after they have been shared';
1340
+				$warning = 'Cannot set expiration date. Shares cannot expire later than '.$maxDays.' after they have been shared';
1341 1341
 				$warning_t = $l->t('Cannot set expiration date. Shares cannot expire later than %s after they have been shared', array($maxDays));
1342 1342
 				\OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN);
1343 1343
 				throw new \Exception($warning_t);
@@ -1517,7 +1517,7 @@  discard block
 block discarded – undo
1517 1517
 	 */
1518 1518
 	protected static function unshareItem(array $item, $newParent = null) {
1519 1519
 
1520
-		$shareType = (int)$item['share_type'];
1520
+		$shareType = (int) $item['share_type'];
1521 1521
 		$shareWith = null;
1522 1522
 		if ($shareType !== \OCP\Share::SHARE_TYPE_LINK) {
1523 1523
 			$shareWith = $item['share_with'];
@@ -1533,7 +1533,7 @@  discard block
 block discarded – undo
1533 1533
 			'itemParent'    => $item['parent'],
1534 1534
 			'uidOwner'      => $item['uid_owner'],
1535 1535
 		);
1536
-		if($item['item_type'] === 'file' || $item['item_type'] === 'folder') {
1536
+		if ($item['item_type'] === 'file' || $item['item_type'] === 'folder') {
1537 1537
 			$hookParams['fileSource'] = $item['file_source'];
1538 1538
 			$hookParams['fileTarget'] = $item['file_target'];
1539 1539
 		}
@@ -1543,7 +1543,7 @@  discard block
 block discarded – undo
1543 1543
 		$deletedShares[] = $hookParams;
1544 1544
 		$hookParams['deletedShares'] = $deletedShares;
1545 1545
 		\OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
1546
-		if ((int)$item['share_type'] === \OCP\Share::SHARE_TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
1546
+		if ((int) $item['share_type'] === \OCP\Share::SHARE_TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
1547 1547
 			list(, $remote) = Helper::splitUserRemote($item['share_with']);
1548 1548
 			self::sendRemoteUnshare($remote, $item['id'], $item['token']);
1549 1549
 		}
@@ -1704,7 +1704,7 @@  discard block
 block discarded – undo
1704 1704
 		// Get filesystem root to add it to the file target and remove from the
1705 1705
 		// file source, match file_source with the file cache
1706 1706
 		if ($itemType == 'file' || $itemType == 'folder') {
1707
-			if(!is_null($uidOwner)) {
1707
+			if (!is_null($uidOwner)) {
1708 1708
 				$root = \OC\Files\Filesystem::getRoot();
1709 1709
 			} else {
1710 1710
 				$root = '';
@@ -1844,7 +1844,7 @@  discard block
 block discarded – undo
1844 1844
 		$result = $query->execute($queryArgs);
1845 1845
 		if ($result === false) {
1846 1846
 			\OCP\Util::writeLog('OCP\Share',
1847
-				\OC_DB::getErrorMessage() . ', select=' . $select . ' where=',
1847
+				\OC_DB::getErrorMessage().', select='.$select.' where=',
1848 1848
 				\OCP\Util::ERROR);
1849 1849
 		}
1850 1850
 		$items = array();
@@ -1886,14 +1886,14 @@  discard block
 block discarded – undo
1886 1886
 						}
1887 1887
 						// Switch ids if sharing permission is granted on only
1888 1888
 						// one share to ensure correct parent is used if resharing
1889
-						if (~(int)$items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE
1890
-							&& (int)$row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
1889
+						if (~(int) $items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE
1890
+							&& (int) $row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
1891 1891
 							$items[$row['id']] = $items[$id];
1892 1892
 							$switchedItems[$id] = $row['id'];
1893 1893
 							unset($items[$id]);
1894 1894
 							$id = $row['id'];
1895 1895
 						}
1896
-						$items[$id]['permissions'] |= (int)$row['permissions'];
1896
+						$items[$id]['permissions'] |= (int) $row['permissions'];
1897 1897
 
1898 1898
 					}
1899 1899
 					continue;
@@ -1907,8 +1907,8 @@  discard block
 block discarded – undo
1907 1907
 					$query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
1908 1908
 					$parentResult = $query->execute(array($row['parent']));
1909 1909
 					if ($result === false) {
1910
-						\OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: ' .
1911
-							\OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where,
1910
+						\OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: '.
1911
+							\OC_DB::getErrorMessage().', select='.$select.' where='.$where,
1912 1912
 							\OCP\Util::ERROR);
1913 1913
 					} else {
1914 1914
 						$parentRow = $parentResult->fetchRow();
@@ -1918,7 +1918,7 @@  discard block
 block discarded – undo
1918 1918
 						$subPath = substr($row['path'], $pos);
1919 1919
 						$splitPath = explode('/', $subPath);
1920 1920
 						foreach (array_slice($splitPath, 2) as $pathPart) {
1921
-							$tmpPath = $tmpPath . '/' . $pathPart;
1921
+							$tmpPath = $tmpPath.'/'.$pathPart;
1922 1922
 						}
1923 1923
 						$row['path'] = $tmpPath;
1924 1924
 					}
@@ -1937,7 +1937,7 @@  discard block
 block discarded – undo
1937 1937
 				}
1938 1938
 			}
1939 1939
 
1940
-			if($checkExpireDate) {
1940
+			if ($checkExpireDate) {
1941 1941
 				if (self::expireItem($row)) {
1942 1942
 					continue;
1943 1943
 				}
@@ -1948,10 +1948,10 @@  discard block
 block discarded – undo
1948 1948
 			}
1949 1949
 			// Add display names to result
1950 1950
 			$row['share_with_displayname'] = $row['share_with'];
1951
-			if ( isset($row['share_with']) && $row['share_with'] != '' &&
1951
+			if (isset($row['share_with']) && $row['share_with'] != '' &&
1952 1952
 				$row['share_type'] === self::SHARE_TYPE_USER) {
1953 1953
 				$row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']);
1954
-			} else if(isset($row['share_with']) && $row['share_with'] != '' &&
1954
+			} else if (isset($row['share_with']) && $row['share_with'] != '' &&
1955 1955
 				$row['share_type'] === self::SHARE_TYPE_REMOTE) {
1956 1956
 				$addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']);
1957 1957
 				foreach ($addressBookEntries as $entry) {
@@ -1962,7 +1962,7 @@  discard block
 block discarded – undo
1962 1962
 					}
1963 1963
 				}
1964 1964
 			}
1965
-			if ( isset($row['uid_owner']) && $row['uid_owner'] != '') {
1965
+			if (isset($row['uid_owner']) && $row['uid_owner'] != '') {
1966 1966
 				$row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
1967 1967
 			}
1968 1968
 
@@ -2110,7 +2110,7 @@  discard block
 block discarded – undo
2110 2110
 				// for file/folder shares we need to compare file_source, otherwise we compare item_source
2111 2111
 				// only group shares if they already point to the same target, otherwise the file where shared
2112 2112
 				// before grouping of shares was added. In this case we don't group them toi avoid confusions
2113
-				if (( $fileSharing && $item['file_source'] === $r['file_source'] && $item['file_target'] === $r['file_target']) ||
2113
+				if (($fileSharing && $item['file_source'] === $r['file_source'] && $item['file_target'] === $r['file_target']) ||
2114 2114
 					(!$fileSharing && $item['item_source'] === $r['item_source'] && $item['item_target'] === $r['item_target'])) {
2115 2115
 					// add the first item to the list of grouped shares
2116 2116
 					if (!isset($result[$key]['grouped'])) {
@@ -2156,7 +2156,7 @@  discard block
 block discarded – undo
2156 2156
 		$groupItemTarget = $itemTarget = $fileSource = $parent = 0;
2157 2157
 
2158 2158
 		$result = self::checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate);
2159
-		if(!empty($result)) {
2159
+		if (!empty($result)) {
2160 2160
 			$parent = $result['parent'];
2161 2161
 			$itemSource = $result['itemSource'];
2162 2162
 			$fileSource = $result['fileSource'];
@@ -2240,11 +2240,11 @@  discard block
 block discarded – undo
2240 2240
 				$itemTarget = $sourceExists['item_target'];
2241 2241
 
2242 2242
 				// for group shares we don't need a additional entry if the target is the same
2243
-				if($isGroupShare && $groupItemTarget === $itemTarget) {
2243
+				if ($isGroupShare && $groupItemTarget === $itemTarget) {
2244 2244
 					continue;
2245 2245
 				}
2246 2246
 
2247
-			} elseif(!$sourceExists && !$isGroupShare)  {
2247
+			} elseif (!$sourceExists && !$isGroupShare) {
2248 2248
 
2249 2249
 				$itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user,
2250 2250
 					$uidOwner, $suggestedItemTarget, $parent);
@@ -2375,8 +2375,8 @@  discard block
 block discarded – undo
2375 2375
 
2376 2376
 		if ($checkReshare && $checkReshare['uid_owner'] !== \OC_User::getUser()) {
2377 2377
 			// Check if share permissions is granted
2378
-			if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
2379
-				if (~(int)$checkReshare['permissions'] & $permissions) {
2378
+			if (self::isResharingAllowed() && (int) $checkReshare['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
2379
+				if (~(int) $checkReshare['permissions'] & $permissions) {
2380 2380
 					$message = 'Sharing %s failed, because the permissions exceed permissions granted to %s';
2381 2381
 					$message_t = $l->t('Sharing %s failed, because the permissions exceed permissions granted to %s', array($itemSourceName, $uidOwner));
2382 2382
 
@@ -2388,7 +2388,7 @@  discard block
 block discarded – undo
2388 2388
 
2389 2389
 					$result['expirationDate'] = $expirationDate;
2390 2390
 					// $checkReshare['expiration'] could be null and then is always less than any value
2391
-					if(isset($checkReshare['expiration']) && $checkReshare['expiration'] < $expirationDate) {
2391
+					if (isset($checkReshare['expiration']) && $checkReshare['expiration'] < $expirationDate) {
2392 2392
 						$result['expirationDate'] = $checkReshare['expiration'];
2393 2393
 					}
2394 2394
 
@@ -2480,7 +2480,7 @@  discard block
 block discarded – undo
2480 2480
 
2481 2481
 		$id = false;
2482 2482
 		if ($result) {
2483
-			$id =  \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
2483
+			$id = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
2484 2484
 		}
2485 2485
 
2486 2486
 		return $id;
@@ -2520,8 +2520,8 @@  discard block
 block discarded – undo
2520 2520
 			return true;
2521 2521
 		}
2522 2522
 
2523
-		if ( \OC::$server->getSession()->exists('public_link_authenticated')
2524
-			&& \OC::$server->getSession()->get('public_link_authenticated') === (string)$linkItem['id'] ) {
2523
+		if (\OC::$server->getSession()->exists('public_link_authenticated')
2524
+			&& \OC::$server->getSession()->get('public_link_authenticated') === (string) $linkItem['id']) {
2525 2525
 			return true;
2526 2526
 		}
2527 2527
 
@@ -2623,7 +2623,7 @@  discard block
 block discarded – undo
2623 2623
 	 * @param array $parameters additional format parameters
2624 2624
 	 * @return array format result
2625 2625
 	 */
2626
-	private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE , $parameters = null) {
2626
+	private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE, $parameters = null) {
2627 2627
 		if ($format === self::FORMAT_NONE) {
2628 2628
 			return $items;
2629 2629
 		} else if ($format === self::FORMAT_STATUSES) {
@@ -2683,8 +2683,8 @@  discard block
 block discarded – undo
2683 2683
 			\OC::$server->getHTTPClientService()
2684 2684
 		);
2685 2685
 		while ($result['success'] === false && $try < 2) {
2686
-			$endpoint = $discoveryManager->getShareEndpoint($protocol . $remoteDomain);
2687
-			$result = \OC::$server->getHTTPHelper()->post($protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, $fields);
2686
+			$endpoint = $discoveryManager->getShareEndpoint($protocol.$remoteDomain);
2687
+			$result = \OC::$server->getHTTPHelper()->post($protocol.$remoteDomain.$endpoint.$urlSuffix.'?format='.self::RESPONSE_FORMAT, $fields);
2688 2688
 			$try++;
2689 2689
 			$protocol = 'http://';
2690 2690
 		}
@@ -2781,7 +2781,7 @@  discard block
 block discarded – undo
2781 2781
 	 * @return int
2782 2782
 	 */
2783 2783
 	public static function getExpireInterval() {
2784
-		return (int)\OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
2784
+		return (int) \OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
2785 2785
 	}
2786 2786
 
2787 2787
 	/**
Please login to merge, or discard this patch.
Indentation   +2743 added lines, -2743 removed lines patch added patch discarded remove patch
@@ -58,2780 +58,2780 @@
 block discarded – undo
58 58
  */
59 59
 class Share extends Constants {
60 60
 
61
-	/** CRUDS permissions (Create, Read, Update, Delete, Share) using a bitmask
62
-	 * Construct permissions for share() and setPermissions with Or (|) e.g.
63
-	 * Give user read and update permissions: PERMISSION_READ | PERMISSION_UPDATE
64
-	 *
65
-	 * Check if permission is granted with And (&) e.g. Check if delete is
66
-	 * granted: if ($permissions & PERMISSION_DELETE)
67
-	 *
68
-	 * Remove permissions with And (&) and Not (~) e.g. Remove the update
69
-	 * permission: $permissions &= ~PERMISSION_UPDATE
70
-	 *
71
-	 * Apps are required to handle permissions on their own, this class only
72
-	 * stores and manages the permissions of shares
73
-	 * @see lib/public/constants.php
74
-	 */
75
-
76
-	/**
77
-	 * Register a sharing backend class that implements OCP\Share_Backend for an item type
78
-	 * @param string $itemType Item type
79
-	 * @param string $class Backend class
80
-	 * @param string $collectionOf (optional) Depends on item type
81
-	 * @param array $supportedFileExtensions (optional) List of supported file extensions if this item type depends on files
82
-	 * @return boolean true if backend is registered or false if error
83
-	 */
84
-	public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) {
85
-		if (self::isEnabled()) {
86
-			if (!isset(self::$backendTypes[$itemType])) {
87
-				self::$backendTypes[$itemType] = array(
88
-					'class' => $class,
89
-					'collectionOf' => $collectionOf,
90
-					'supportedFileExtensions' => $supportedFileExtensions
91
-				);
92
-				if(count(self::$backendTypes) === 1) {
93
-					\OC_Util::addScript('core', 'shareconfigmodel');
94
-					\OC_Util::addScript('core', 'shareitemmodel');
95
-					\OC_Util::addScript('core', 'sharedialogresharerinfoview');
96
-					\OC_Util::addScript('core', 'sharedialoglinkshareview');
97
-					\OC_Util::addScript('core', 'sharedialogmailview');
98
-					\OC_Util::addScript('core', 'sharedialogexpirationview');
99
-					\OC_Util::addScript('core', 'sharedialogshareelistview');
100
-					\OC_Util::addScript('core', 'sharedialogview');
101
-					\OC_Util::addScript('core', 'share');
102
-					\OC_Util::addStyle('core', 'share');
103
-				}
104
-				return true;
105
-			}
106
-			\OCP\Util::writeLog('OCP\Share',
107
-				'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class']
108
-				.' is already registered for '.$itemType,
109
-				\OCP\Util::WARN);
110
-		}
111
-		return false;
112
-	}
113
-
114
-	/**
115
-	 * Check if the Share API is enabled
116
-	 * @return boolean true if enabled or false
117
-	 *
118
-	 * The Share API is enabled by default if not configured
119
-	 */
120
-	public static function isEnabled() {
121
-		if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_enabled', 'yes') == 'yes') {
122
-			return true;
123
-		}
124
-		return false;
125
-	}
126
-
127
-	/**
128
-	 * Find which users can access a shared item
129
-	 * @param string $path to the file
130
-	 * @param string $ownerUser owner of the file
131
-	 * @param boolean $includeOwner include owner to the list of users with access to the file
132
-	 * @param boolean $returnUserPaths Return an array with the user => path map
133
-	 * @param boolean $recursive take all parent folders into account (default true)
134
-	 * @return array
135
-	 * @note $path needs to be relative to user data dir, e.g. 'file.txt'
136
-	 *       not '/admin/data/file.txt'
137
-	 */
138
-	public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false, $recursive = true) {
139
-
140
-		Filesystem::initMountPoints($ownerUser);
141
-		$shares = $sharePaths = $fileTargets = array();
142
-		$publicShare = false;
143
-		$remoteShare = false;
144
-		$source = -1;
145
-		$cache = $mountPath = false;
146
-
147
-		$view = new \OC\Files\View('/' . $ownerUser . '/files');
148
-		$meta = $view->getFileInfo($path);
149
-		if ($meta) {
150
-			$path = substr($meta->getPath(), strlen('/' . $ownerUser . '/files'));
151
-		} else {
152
-			// if the file doesn't exists yet we start with the parent folder
153
-			$meta = $view->getFileInfo(dirname($path));
154
-		}
155
-
156
-		if($meta !== false) {
157
-			$source = $meta['fileid'];
158
-			$cache = new \OC\Files\Cache\Cache($meta['storage']);
159
-
160
-			$mountPath = $meta->getMountPoint()->getMountPoint();
161
-			if ($mountPath !== false) {
162
-				$mountPath = substr($mountPath, strlen('/' . $ownerUser . '/files'));
163
-			}
164
-		}
165
-
166
-		$paths = [];
167
-		while ($source !== -1) {
168
-			// Fetch all shares with another user
169
-			if (!$returnUserPaths) {
170
-				$query = \OC_DB::prepare(
171
-					'SELECT `share_with`, `file_source`, `file_target`
61
+    /** CRUDS permissions (Create, Read, Update, Delete, Share) using a bitmask
62
+     * Construct permissions for share() and setPermissions with Or (|) e.g.
63
+     * Give user read and update permissions: PERMISSION_READ | PERMISSION_UPDATE
64
+     *
65
+     * Check if permission is granted with And (&) e.g. Check if delete is
66
+     * granted: if ($permissions & PERMISSION_DELETE)
67
+     *
68
+     * Remove permissions with And (&) and Not (~) e.g. Remove the update
69
+     * permission: $permissions &= ~PERMISSION_UPDATE
70
+     *
71
+     * Apps are required to handle permissions on their own, this class only
72
+     * stores and manages the permissions of shares
73
+     * @see lib/public/constants.php
74
+     */
75
+
76
+    /**
77
+     * Register a sharing backend class that implements OCP\Share_Backend for an item type
78
+     * @param string $itemType Item type
79
+     * @param string $class Backend class
80
+     * @param string $collectionOf (optional) Depends on item type
81
+     * @param array $supportedFileExtensions (optional) List of supported file extensions if this item type depends on files
82
+     * @return boolean true if backend is registered or false if error
83
+     */
84
+    public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) {
85
+        if (self::isEnabled()) {
86
+            if (!isset(self::$backendTypes[$itemType])) {
87
+                self::$backendTypes[$itemType] = array(
88
+                    'class' => $class,
89
+                    'collectionOf' => $collectionOf,
90
+                    'supportedFileExtensions' => $supportedFileExtensions
91
+                );
92
+                if(count(self::$backendTypes) === 1) {
93
+                    \OC_Util::addScript('core', 'shareconfigmodel');
94
+                    \OC_Util::addScript('core', 'shareitemmodel');
95
+                    \OC_Util::addScript('core', 'sharedialogresharerinfoview');
96
+                    \OC_Util::addScript('core', 'sharedialoglinkshareview');
97
+                    \OC_Util::addScript('core', 'sharedialogmailview');
98
+                    \OC_Util::addScript('core', 'sharedialogexpirationview');
99
+                    \OC_Util::addScript('core', 'sharedialogshareelistview');
100
+                    \OC_Util::addScript('core', 'sharedialogview');
101
+                    \OC_Util::addScript('core', 'share');
102
+                    \OC_Util::addStyle('core', 'share');
103
+                }
104
+                return true;
105
+            }
106
+            \OCP\Util::writeLog('OCP\Share',
107
+                'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class']
108
+                .' is already registered for '.$itemType,
109
+                \OCP\Util::WARN);
110
+        }
111
+        return false;
112
+    }
113
+
114
+    /**
115
+     * Check if the Share API is enabled
116
+     * @return boolean true if enabled or false
117
+     *
118
+     * The Share API is enabled by default if not configured
119
+     */
120
+    public static function isEnabled() {
121
+        if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_enabled', 'yes') == 'yes') {
122
+            return true;
123
+        }
124
+        return false;
125
+    }
126
+
127
+    /**
128
+     * Find which users can access a shared item
129
+     * @param string $path to the file
130
+     * @param string $ownerUser owner of the file
131
+     * @param boolean $includeOwner include owner to the list of users with access to the file
132
+     * @param boolean $returnUserPaths Return an array with the user => path map
133
+     * @param boolean $recursive take all parent folders into account (default true)
134
+     * @return array
135
+     * @note $path needs to be relative to user data dir, e.g. 'file.txt'
136
+     *       not '/admin/data/file.txt'
137
+     */
138
+    public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false, $recursive = true) {
139
+
140
+        Filesystem::initMountPoints($ownerUser);
141
+        $shares = $sharePaths = $fileTargets = array();
142
+        $publicShare = false;
143
+        $remoteShare = false;
144
+        $source = -1;
145
+        $cache = $mountPath = false;
146
+
147
+        $view = new \OC\Files\View('/' . $ownerUser . '/files');
148
+        $meta = $view->getFileInfo($path);
149
+        if ($meta) {
150
+            $path = substr($meta->getPath(), strlen('/' . $ownerUser . '/files'));
151
+        } else {
152
+            // if the file doesn't exists yet we start with the parent folder
153
+            $meta = $view->getFileInfo(dirname($path));
154
+        }
155
+
156
+        if($meta !== false) {
157
+            $source = $meta['fileid'];
158
+            $cache = new \OC\Files\Cache\Cache($meta['storage']);
159
+
160
+            $mountPath = $meta->getMountPoint()->getMountPoint();
161
+            if ($mountPath !== false) {
162
+                $mountPath = substr($mountPath, strlen('/' . $ownerUser . '/files'));
163
+            }
164
+        }
165
+
166
+        $paths = [];
167
+        while ($source !== -1) {
168
+            // Fetch all shares with another user
169
+            if (!$returnUserPaths) {
170
+                $query = \OC_DB::prepare(
171
+                    'SELECT `share_with`, `file_source`, `file_target`
172 172
 					FROM
173 173
 					`*PREFIX*share`
174 174
 					WHERE
175 175
 					`item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'
176
-				);
177
-				$result = $query->execute(array($source, self::SHARE_TYPE_USER));
178
-			} else {
179
-				$query = \OC_DB::prepare(
180
-					'SELECT `share_with`, `file_source`, `file_target`
176
+                );
177
+                $result = $query->execute(array($source, self::SHARE_TYPE_USER));
178
+            } else {
179
+                $query = \OC_DB::prepare(
180
+                    'SELECT `share_with`, `file_source`, `file_target`
181 181
 				FROM
182 182
 				`*PREFIX*share`
183 183
 				WHERE
184 184
 				`item_source` = ? AND `share_type` IN (?, ?) AND `item_type` IN (\'file\', \'folder\')'
185
-				);
186
-				$result = $query->execute(array($source, self::SHARE_TYPE_USER, self::$shareTypeGroupUserUnique));
187
-			}
188
-
189
-			if (\OCP\DB::isError($result)) {
190
-				\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
191
-			} else {
192
-				while ($row = $result->fetchRow()) {
193
-					$shares[] = $row['share_with'];
194
-					if ($returnUserPaths) {
195
-						$fileTargets[(int) $row['file_source']][$row['share_with']] = $row;
196
-					}
197
-				}
198
-			}
199
-
200
-			// We also need to take group shares into account
201
-			$query = \OC_DB::prepare(
202
-				'SELECT `share_with`, `file_source`, `file_target`
185
+                );
186
+                $result = $query->execute(array($source, self::SHARE_TYPE_USER, self::$shareTypeGroupUserUnique));
187
+            }
188
+
189
+            if (\OCP\DB::isError($result)) {
190
+                \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
191
+            } else {
192
+                while ($row = $result->fetchRow()) {
193
+                    $shares[] = $row['share_with'];
194
+                    if ($returnUserPaths) {
195
+                        $fileTargets[(int) $row['file_source']][$row['share_with']] = $row;
196
+                    }
197
+                }
198
+            }
199
+
200
+            // We also need to take group shares into account
201
+            $query = \OC_DB::prepare(
202
+                'SELECT `share_with`, `file_source`, `file_target`
203 203
 				FROM
204 204
 				`*PREFIX*share`
205 205
 				WHERE
206 206
 				`item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'
207
-			);
208
-
209
-			$result = $query->execute(array($source, self::SHARE_TYPE_GROUP));
210
-
211
-			if (\OCP\DB::isError($result)) {
212
-				\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
213
-			} else {
214
-				while ($row = $result->fetchRow()) {
215
-					$usersInGroup = \OC_Group::usersInGroup($row['share_with']);
216
-					$shares = array_merge($shares, $usersInGroup);
217
-					if ($returnUserPaths) {
218
-						foreach ($usersInGroup as $user) {
219
-							if (!isset($fileTargets[(int) $row['file_source']][$user])) {
220
-								// When the user already has an entry for this file source
221
-								// the file is either shared directly with him as well, or
222
-								// he has an exception entry (because of naming conflict).
223
-								$fileTargets[(int) $row['file_source']][$user] = $row;
224
-							}
225
-						}
226
-					}
227
-				}
228
-			}
229
-
230
-			//check for public link shares
231
-			if (!$publicShare) {
232
-				$query = \OC_DB::prepare('
207
+            );
208
+
209
+            $result = $query->execute(array($source, self::SHARE_TYPE_GROUP));
210
+
211
+            if (\OCP\DB::isError($result)) {
212
+                \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
213
+            } else {
214
+                while ($row = $result->fetchRow()) {
215
+                    $usersInGroup = \OC_Group::usersInGroup($row['share_with']);
216
+                    $shares = array_merge($shares, $usersInGroup);
217
+                    if ($returnUserPaths) {
218
+                        foreach ($usersInGroup as $user) {
219
+                            if (!isset($fileTargets[(int) $row['file_source']][$user])) {
220
+                                // When the user already has an entry for this file source
221
+                                // the file is either shared directly with him as well, or
222
+                                // he has an exception entry (because of naming conflict).
223
+                                $fileTargets[(int) $row['file_source']][$user] = $row;
224
+                            }
225
+                        }
226
+                    }
227
+                }
228
+            }
229
+
230
+            //check for public link shares
231
+            if (!$publicShare) {
232
+                $query = \OC_DB::prepare('
233 233
 					SELECT `share_with`
234 234
 					FROM `*PREFIX*share`
235 235
 					WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')', 1
236
-				);
237
-
238
-				$result = $query->execute(array($source, self::SHARE_TYPE_LINK));
239
-
240
-				if (\OCP\DB::isError($result)) {
241
-					\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
242
-				} else {
243
-					if ($result->fetchRow()) {
244
-						$publicShare = true;
245
-					}
246
-				}
247
-			}
248
-
249
-			//check for remote share
250
-			if (!$remoteShare) {
251
-				$query = \OC_DB::prepare('
236
+                );
237
+
238
+                $result = $query->execute(array($source, self::SHARE_TYPE_LINK));
239
+
240
+                if (\OCP\DB::isError($result)) {
241
+                    \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
242
+                } else {
243
+                    if ($result->fetchRow()) {
244
+                        $publicShare = true;
245
+                    }
246
+                }
247
+            }
248
+
249
+            //check for remote share
250
+            if (!$remoteShare) {
251
+                $query = \OC_DB::prepare('
252 252
 					SELECT `share_with`
253 253
 					FROM `*PREFIX*share`
254 254
 					WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')', 1
255
-				);
256
-
257
-				$result = $query->execute(array($source, self::SHARE_TYPE_REMOTE));
258
-
259
-				if (\OCP\DB::isError($result)) {
260
-					\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
261
-				} else {
262
-					if ($result->fetchRow()) {
263
-						$remoteShare = true;
264
-					}
265
-				}
266
-			}
267
-
268
-			// let's get the parent for the next round
269
-			$meta = $cache->get((int)$source);
270
-			if ($recursive === true && $meta !== false) {
271
-				$paths[$source] = $meta['path'];
272
-				$source = (int)$meta['parent'];
273
-			} else {
274
-				$source = -1;
275
-			}
276
-		}
277
-
278
-		// Include owner in list of users, if requested
279
-		if ($includeOwner) {
280
-			$shares[] = $ownerUser;
281
-		}
282
-
283
-		if ($returnUserPaths) {
284
-			$fileTargetIDs = array_keys($fileTargets);
285
-			$fileTargetIDs = array_unique($fileTargetIDs);
286
-
287
-			if (!empty($fileTargetIDs)) {
288
-				$query = \OC_DB::prepare(
289
-					'SELECT `fileid`, `path`
255
+                );
256
+
257
+                $result = $query->execute(array($source, self::SHARE_TYPE_REMOTE));
258
+
259
+                if (\OCP\DB::isError($result)) {
260
+                    \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
261
+                } else {
262
+                    if ($result->fetchRow()) {
263
+                        $remoteShare = true;
264
+                    }
265
+                }
266
+            }
267
+
268
+            // let's get the parent for the next round
269
+            $meta = $cache->get((int)$source);
270
+            if ($recursive === true && $meta !== false) {
271
+                $paths[$source] = $meta['path'];
272
+                $source = (int)$meta['parent'];
273
+            } else {
274
+                $source = -1;
275
+            }
276
+        }
277
+
278
+        // Include owner in list of users, if requested
279
+        if ($includeOwner) {
280
+            $shares[] = $ownerUser;
281
+        }
282
+
283
+        if ($returnUserPaths) {
284
+            $fileTargetIDs = array_keys($fileTargets);
285
+            $fileTargetIDs = array_unique($fileTargetIDs);
286
+
287
+            if (!empty($fileTargetIDs)) {
288
+                $query = \OC_DB::prepare(
289
+                    'SELECT `fileid`, `path`
290 290
 					FROM `*PREFIX*filecache`
291 291
 					WHERE `fileid` IN (' . implode(',', $fileTargetIDs) . ')'
292
-				);
293
-				$result = $query->execute();
294
-
295
-				if (\OCP\DB::isError($result)) {
296
-					\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
297
-				} else {
298
-					while ($row = $result->fetchRow()) {
299
-						foreach ($fileTargets[$row['fileid']] as $uid => $shareData) {
300
-							if ($mountPath !== false) {
301
-								$sharedPath = $shareData['file_target'];
302
-								$sharedPath .= substr($path, strlen($mountPath) + strlen($paths[$row['fileid']]));
303
-								$sharePaths[$uid] = $sharedPath;
304
-							} else {
305
-								$sharedPath = $shareData['file_target'];
306
-								$sharedPath .= substr($path, strlen($row['path']) -5);
307
-								$sharePaths[$uid] = $sharedPath;
308
-							}
309
-						}
310
-					}
311
-				}
312
-			}
313
-
314
-			if ($includeOwner) {
315
-				$sharePaths[$ownerUser] = $path;
316
-			} else {
317
-				unset($sharePaths[$ownerUser]);
318
-			}
319
-
320
-			return $sharePaths;
321
-		}
322
-
323
-		return array('users' => array_unique($shares), 'public' => $publicShare, 'remote' => $remoteShare);
324
-	}
325
-
326
-	/**
327
-	 * Get the items of item type shared with the current user
328
-	 * @param string $itemType
329
-	 * @param int $format (optional) Format type must be defined by the backend
330
-	 * @param mixed $parameters (optional)
331
-	 * @param int $limit Number of items to return (optional) Returns all by default
332
-	 * @param boolean $includeCollections (optional)
333
-	 * @return mixed Return depends on format
334
-	 */
335
-	public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE,
336
-											  $parameters = null, $limit = -1, $includeCollections = false) {
337
-		return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
338
-			$parameters, $limit, $includeCollections);
339
-	}
340
-
341
-	/**
342
-	 * Get the items of item type shared with a user
343
-	 * @param string $itemType
344
-	 * @param string $user id for which user we want the shares
345
-	 * @param int $format (optional) Format type must be defined by the backend
346
-	 * @param mixed $parameters (optional)
347
-	 * @param int $limit Number of items to return (optional) Returns all by default
348
-	 * @param boolean $includeCollections (optional)
349
-	 * @return mixed Return depends on format
350
-	 */
351
-	public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE,
352
-												  $parameters = null, $limit = -1, $includeCollections = false) {
353
-		return self::getItems($itemType, null, self::$shareTypeUserAndGroups, $user, null, $format,
354
-			$parameters, $limit, $includeCollections);
355
-	}
356
-
357
-	/**
358
-	 * Get the item of item type shared with the current user
359
-	 * @param string $itemType
360
-	 * @param string $itemTarget
361
-	 * @param int $format (optional) Format type must be defined by the backend
362
-	 * @param mixed $parameters (optional)
363
-	 * @param boolean $includeCollections (optional)
364
-	 * @return mixed Return depends on format
365
-	 */
366
-	public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE,
367
-											 $parameters = null, $includeCollections = false) {
368
-		return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
369
-			$parameters, 1, $includeCollections);
370
-	}
371
-
372
-	/**
373
-	 * Get the item of item type shared with a given user by source
374
-	 * @param string $itemType
375
-	 * @param string $itemSource
376
-	 * @param string $user User to whom the item was shared
377
-	 * @param string $owner Owner of the share
378
-	 * @param int $shareType only look for a specific share type
379
-	 * @return array Return list of items with file_target, permissions and expiration
380
-	 */
381
-	public static function getItemSharedWithUser($itemType, $itemSource, $user, $owner = null, $shareType = null) {
382
-		$shares = array();
383
-		$fileDependent = false;
384
-
385
-		$where = 'WHERE';
386
-		$fileDependentWhere = '';
387
-		if ($itemType === 'file' || $itemType === 'folder') {
388
-			$fileDependent = true;
389
-			$column = 'file_source';
390
-			$fileDependentWhere = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
391
-			$fileDependentWhere .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
392
-		} else {
393
-			$column = 'item_source';
394
-		}
395
-
396
-		$select = self::createSelectStatement(self::FORMAT_NONE, $fileDependent);
397
-
398
-		$where .= ' `' . $column . '` = ? AND `item_type` = ? ';
399
-		$arguments = array($itemSource, $itemType);
400
-		// for link shares $user === null
401
-		if ($user !== null) {
402
-			$where .= ' AND `share_with` = ? ';
403
-			$arguments[] = $user;
404
-		}
405
-
406
-		if ($shareType !== null) {
407
-			$where .= ' AND `share_type` = ? ';
408
-			$arguments[] = $shareType;
409
-		}
410
-
411
-		if ($owner !== null) {
412
-			$where .= ' AND `uid_owner` = ? ';
413
-			$arguments[] = $owner;
414
-		}
415
-
416
-		$query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` '. $fileDependentWhere . $where);
417
-
418
-		$result = \OC_DB::executeAudited($query, $arguments);
419
-
420
-		while ($row = $result->fetchRow()) {
421
-			if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
422
-				continue;
423
-			}
424
-			if ($fileDependent && (int)$row['file_parent'] === -1) {
425
-				// if it is a mount point we need to get the path from the mount manager
426
-				$mountManager = \OC\Files\Filesystem::getMountManager();
427
-				$mountPoint = $mountManager->findByStorageId($row['storage_id']);
428
-				if (!empty($mountPoint)) {
429
-					$path = $mountPoint[0]->getMountPoint();
430
-					$path = trim($path, '/');
431
-					$path = substr($path, strlen($owner) + 1); //normalize path to 'files/foo.txt`
432
-					$row['path'] = $path;
433
-				} else {
434
-					\OC::$server->getLogger()->warning(
435
-						'Could not resolve mount point for ' . $row['storage_id'],
436
-						['app' => 'OCP\Share']
437
-					);
438
-				}
439
-			}
440
-			$shares[] = $row;
441
-		}
442
-
443
-		//if didn't found a result than let's look for a group share.
444
-		if(empty($shares) && $user !== null) {
445
-			$groups = \OC_Group::getUserGroups($user);
446
-
447
-			if (!empty($groups)) {
448
-				$where = $fileDependentWhere . ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)';
449
-				$arguments = array($itemSource, $itemType, $groups);
450
-				$types = array(null, null, IQueryBuilder::PARAM_STR_ARRAY);
451
-
452
-				if ($owner !== null) {
453
-					$where .= ' AND `uid_owner` = ?';
454
-					$arguments[] = $owner;
455
-					$types[] = null;
456
-				}
457
-
458
-				// TODO: inject connection, hopefully one day in the future when this
459
-				// class isn't static anymore...
460
-				$conn = \OC::$server->getDatabaseConnection();
461
-				$result = $conn->executeQuery(
462
-					'SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where,
463
-					$arguments,
464
-					$types
465
-				);
466
-
467
-				while ($row = $result->fetch()) {
468
-					$shares[] = $row;
469
-				}
470
-			}
471
-		}
472
-
473
-		return $shares;
474
-
475
-	}
476
-
477
-	/**
478
-	 * Get the item of item type shared with the current user by source
479
-	 * @param string $itemType
480
-	 * @param string $itemSource
481
-	 * @param int $format (optional) Format type must be defined by the backend
482
-	 * @param mixed $parameters
483
-	 * @param boolean $includeCollections
484
-	 * @param string $shareWith (optional) define against which user should be checked, default: current user
485
-	 * @return array
486
-	 */
487
-	public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE,
488
-													 $parameters = null, $includeCollections = false, $shareWith = null) {
489
-		$shareWith = ($shareWith === null) ? \OC_User::getUser() : $shareWith;
490
-		return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, $shareWith, null, $format,
491
-			$parameters, 1, $includeCollections, true);
492
-	}
493
-
494
-	/**
495
-	 * Get the item of item type shared by a link
496
-	 * @param string $itemType
497
-	 * @param string $itemSource
498
-	 * @param string $uidOwner Owner of link
499
-	 * @return array
500
-	 */
501
-	public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) {
502
-		return self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE,
503
-			null, 1);
504
-	}
505
-
506
-	/**
507
-	 * Based on the given token the share information will be returned - password protected shares will be verified
508
-	 * @param string $token
509
-	 * @param bool $checkPasswordProtection
510
-	 * @return array|boolean false will be returned in case the token is unknown or unauthorized
511
-	 */
512
-	public static function getShareByToken($token, $checkPasswordProtection = true) {
513
-		$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?', 1);
514
-		$result = $query->execute(array($token));
515
-		if ($result === false) {
516
-			\OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage() . ', token=' . $token, \OCP\Util::ERROR);
517
-		}
518
-		$row = $result->fetchRow();
519
-		if ($row === false) {
520
-			return false;
521
-		}
522
-		if (is_array($row) and self::expireItem($row)) {
523
-			return false;
524
-		}
525
-
526
-		// password protected shares need to be authenticated
527
-		if ($checkPasswordProtection && !\OCP\Share::checkPasswordProtectedShare($row)) {
528
-			return false;
529
-		}
530
-
531
-		return $row;
532
-	}
533
-
534
-	/**
535
-	 * resolves reshares down to the last real share
536
-	 * @param array $linkItem
537
-	 * @return array file owner
538
-	 */
539
-	public static function resolveReShare($linkItem)
540
-	{
541
-		if (isset($linkItem['parent'])) {
542
-			$parent = $linkItem['parent'];
543
-			while (isset($parent)) {
544
-				$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `id` = ?', 1);
545
-				$item = $query->execute(array($parent))->fetchRow();
546
-				if (isset($item['parent'])) {
547
-					$parent = $item['parent'];
548
-				} else {
549
-					return $item;
550
-				}
551
-			}
552
-		}
553
-		return $linkItem;
554
-	}
555
-
556
-
557
-	/**
558
-	 * Get the shared items of item type owned by the current user
559
-	 * @param string $itemType
560
-	 * @param int $format (optional) Format type must be defined by the backend
561
-	 * @param mixed $parameters
562
-	 * @param int $limit Number of items to return (optional) Returns all by default
563
-	 * @param boolean $includeCollections
564
-	 * @return mixed Return depends on format
565
-	 */
566
-	public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null,
567
-										  $limit = -1, $includeCollections = false) {
568
-		return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format,
569
-			$parameters, $limit, $includeCollections);
570
-	}
571
-
572
-	/**
573
-	 * Get the shared item of item type owned by the current user
574
-	 * @param string $itemType
575
-	 * @param string $itemSource
576
-	 * @param int $format (optional) Format type must be defined by the backend
577
-	 * @param mixed $parameters
578
-	 * @param boolean $includeCollections
579
-	 * @return mixed Return depends on format
580
-	 */
581
-	public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE,
582
-										 $parameters = null, $includeCollections = false) {
583
-		return self::getItems($itemType, $itemSource, null, null, \OC_User::getUser(), $format,
584
-			$parameters, -1, $includeCollections);
585
-	}
586
-
587
-	/**
588
-	 * Get all users an item is shared with
589
-	 * @param string $itemType
590
-	 * @param string $itemSource
591
-	 * @param string $uidOwner
592
-	 * @param boolean $includeCollections
593
-	 * @param boolean $checkExpireDate
594
-	 * @return array Return array of users
595
-	 */
596
-	public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections = false, $checkExpireDate = true) {
597
-
598
-		$users = array();
599
-		$items = self::getItems($itemType, $itemSource, null, null, $uidOwner, self::FORMAT_NONE, null, -1, $includeCollections, false, $checkExpireDate);
600
-		if ($items) {
601
-			foreach ($items as $item) {
602
-				if ((int)$item['share_type'] === self::SHARE_TYPE_USER) {
603
-					$users[] = $item['share_with'];
604
-				} else if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
605
-					$users = array_merge($users, \OC_Group::usersInGroup($item['share_with']));
606
-				}
607
-			}
608
-		}
609
-		return $users;
610
-	}
611
-
612
-	/**
613
-	 * Share an item with a user, group, or via private link
614
-	 * @param string $itemType
615
-	 * @param string $itemSource
616
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
617
-	 * @param string $shareWith User or group the item is being shared with
618
-	 * @param int $permissions CRUDS
619
-	 * @param string $itemSourceName
620
-	 * @param \DateTime $expirationDate
621
-	 * @param bool $passwordChanged
622
-	 * @return boolean|string Returns true on success or false on failure, Returns token on success for links
623
-	 * @throws \OC\HintException when the share type is remote and the shareWith is invalid
624
-	 * @throws \Exception
625
-	 */
626
-	public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null, \DateTime $expirationDate = null, $passwordChanged = null) {
627
-
628
-		$backend = self::getBackend($itemType);
629
-		$l = \OC::$server->getL10N('lib');
630
-
631
-		if ($backend->isShareTypeAllowed($shareType) === false) {
632
-			$message = 'Sharing %s failed, because the backend does not allow shares from type %i';
633
-			$message_t = $l->t('Sharing %s failed, because the backend does not allow shares from type %i', array($itemSourceName, $shareType));
634
-			\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareType), \OCP\Util::DEBUG);
635
-			throw new \Exception($message_t);
636
-		}
637
-
638
-		$uidOwner = \OC_User::getUser();
639
-		$shareWithinGroupOnly = self::shareWithGroupMembersOnly();
640
-
641
-		if (is_null($itemSourceName)) {
642
-			$itemSourceName = $itemSource;
643
-		}
644
-		$itemName = $itemSourceName;
645
-
646
-		// check if file can be shared
647
-		if ($itemType === 'file' or $itemType === 'folder') {
648
-			$path = \OC\Files\Filesystem::getPath($itemSource);
649
-			$itemName = $path;
650
-
651
-			// verify that the file exists before we try to share it
652
-			if (!$path) {
653
-				$message = 'Sharing %s failed, because the file does not exist';
654
-				$message_t = $l->t('Sharing %s failed, because the file does not exist', array($itemSourceName));
655
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG);
656
-				throw new \Exception($message_t);
657
-			}
658
-			// verify that the user has share permission
659
-			if (!\OC\Files\Filesystem::isSharable($path) || \OCP\Util::isSharingDisabledForUser()) {
660
-				$message = 'You are not allowed to share %s';
661
-				$message_t = $l->t('You are not allowed to share %s', [$path]);
662
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $path), \OCP\Util::DEBUG);
663
-				throw new \Exception($message_t);
664
-			}
665
-		}
666
-
667
-		//verify that we don't share a folder which already contains a share mount point
668
-		if ($itemType === 'folder') {
669
-			$path = '/' . $uidOwner . '/files' . \OC\Files\Filesystem::getPath($itemSource) . '/';
670
-			$mountManager = \OC\Files\Filesystem::getMountManager();
671
-			$mounts = $mountManager->findIn($path);
672
-			foreach ($mounts as $mount) {
673
-				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
674
-					$message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!';
675
-					\OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG);
676
-					throw new \Exception($message);
677
-				}
678
-
679
-			}
680
-		}
681
-
682
-		// single file shares should never have delete permissions
683
-		if ($itemType === 'file') {
684
-			$permissions = (int)$permissions & ~\OCP\Constants::PERMISSION_DELETE;
685
-		}
686
-
687
-		//Validate expirationDate
688
-		if ($expirationDate !== null) {
689
-			try {
690
-				/*
292
+                );
293
+                $result = $query->execute();
294
+
295
+                if (\OCP\DB::isError($result)) {
296
+                    \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage(), \OCP\Util::ERROR);
297
+                } else {
298
+                    while ($row = $result->fetchRow()) {
299
+                        foreach ($fileTargets[$row['fileid']] as $uid => $shareData) {
300
+                            if ($mountPath !== false) {
301
+                                $sharedPath = $shareData['file_target'];
302
+                                $sharedPath .= substr($path, strlen($mountPath) + strlen($paths[$row['fileid']]));
303
+                                $sharePaths[$uid] = $sharedPath;
304
+                            } else {
305
+                                $sharedPath = $shareData['file_target'];
306
+                                $sharedPath .= substr($path, strlen($row['path']) -5);
307
+                                $sharePaths[$uid] = $sharedPath;
308
+                            }
309
+                        }
310
+                    }
311
+                }
312
+            }
313
+
314
+            if ($includeOwner) {
315
+                $sharePaths[$ownerUser] = $path;
316
+            } else {
317
+                unset($sharePaths[$ownerUser]);
318
+            }
319
+
320
+            return $sharePaths;
321
+        }
322
+
323
+        return array('users' => array_unique($shares), 'public' => $publicShare, 'remote' => $remoteShare);
324
+    }
325
+
326
+    /**
327
+     * Get the items of item type shared with the current user
328
+     * @param string $itemType
329
+     * @param int $format (optional) Format type must be defined by the backend
330
+     * @param mixed $parameters (optional)
331
+     * @param int $limit Number of items to return (optional) Returns all by default
332
+     * @param boolean $includeCollections (optional)
333
+     * @return mixed Return depends on format
334
+     */
335
+    public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE,
336
+                                                $parameters = null, $limit = -1, $includeCollections = false) {
337
+        return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
338
+            $parameters, $limit, $includeCollections);
339
+    }
340
+
341
+    /**
342
+     * Get the items of item type shared with a user
343
+     * @param string $itemType
344
+     * @param string $user id for which user we want the shares
345
+     * @param int $format (optional) Format type must be defined by the backend
346
+     * @param mixed $parameters (optional)
347
+     * @param int $limit Number of items to return (optional) Returns all by default
348
+     * @param boolean $includeCollections (optional)
349
+     * @return mixed Return depends on format
350
+     */
351
+    public static function getItemsSharedWithUser($itemType, $user, $format = self::FORMAT_NONE,
352
+                                                    $parameters = null, $limit = -1, $includeCollections = false) {
353
+        return self::getItems($itemType, null, self::$shareTypeUserAndGroups, $user, null, $format,
354
+            $parameters, $limit, $includeCollections);
355
+    }
356
+
357
+    /**
358
+     * Get the item of item type shared with the current user
359
+     * @param string $itemType
360
+     * @param string $itemTarget
361
+     * @param int $format (optional) Format type must be defined by the backend
362
+     * @param mixed $parameters (optional)
363
+     * @param boolean $includeCollections (optional)
364
+     * @return mixed Return depends on format
365
+     */
366
+    public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE,
367
+                                                $parameters = null, $includeCollections = false) {
368
+        return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
369
+            $parameters, 1, $includeCollections);
370
+    }
371
+
372
+    /**
373
+     * Get the item of item type shared with a given user by source
374
+     * @param string $itemType
375
+     * @param string $itemSource
376
+     * @param string $user User to whom the item was shared
377
+     * @param string $owner Owner of the share
378
+     * @param int $shareType only look for a specific share type
379
+     * @return array Return list of items with file_target, permissions and expiration
380
+     */
381
+    public static function getItemSharedWithUser($itemType, $itemSource, $user, $owner = null, $shareType = null) {
382
+        $shares = array();
383
+        $fileDependent = false;
384
+
385
+        $where = 'WHERE';
386
+        $fileDependentWhere = '';
387
+        if ($itemType === 'file' || $itemType === 'folder') {
388
+            $fileDependent = true;
389
+            $column = 'file_source';
390
+            $fileDependentWhere = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
391
+            $fileDependentWhere .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
392
+        } else {
393
+            $column = 'item_source';
394
+        }
395
+
396
+        $select = self::createSelectStatement(self::FORMAT_NONE, $fileDependent);
397
+
398
+        $where .= ' `' . $column . '` = ? AND `item_type` = ? ';
399
+        $arguments = array($itemSource, $itemType);
400
+        // for link shares $user === null
401
+        if ($user !== null) {
402
+            $where .= ' AND `share_with` = ? ';
403
+            $arguments[] = $user;
404
+        }
405
+
406
+        if ($shareType !== null) {
407
+            $where .= ' AND `share_type` = ? ';
408
+            $arguments[] = $shareType;
409
+        }
410
+
411
+        if ($owner !== null) {
412
+            $where .= ' AND `uid_owner` = ? ';
413
+            $arguments[] = $owner;
414
+        }
415
+
416
+        $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` '. $fileDependentWhere . $where);
417
+
418
+        $result = \OC_DB::executeAudited($query, $arguments);
419
+
420
+        while ($row = $result->fetchRow()) {
421
+            if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
422
+                continue;
423
+            }
424
+            if ($fileDependent && (int)$row['file_parent'] === -1) {
425
+                // if it is a mount point we need to get the path from the mount manager
426
+                $mountManager = \OC\Files\Filesystem::getMountManager();
427
+                $mountPoint = $mountManager->findByStorageId($row['storage_id']);
428
+                if (!empty($mountPoint)) {
429
+                    $path = $mountPoint[0]->getMountPoint();
430
+                    $path = trim($path, '/');
431
+                    $path = substr($path, strlen($owner) + 1); //normalize path to 'files/foo.txt`
432
+                    $row['path'] = $path;
433
+                } else {
434
+                    \OC::$server->getLogger()->warning(
435
+                        'Could not resolve mount point for ' . $row['storage_id'],
436
+                        ['app' => 'OCP\Share']
437
+                    );
438
+                }
439
+            }
440
+            $shares[] = $row;
441
+        }
442
+
443
+        //if didn't found a result than let's look for a group share.
444
+        if(empty($shares) && $user !== null) {
445
+            $groups = \OC_Group::getUserGroups($user);
446
+
447
+            if (!empty($groups)) {
448
+                $where = $fileDependentWhere . ' WHERE `' . $column . '` = ? AND `item_type` = ? AND `share_with` in (?)';
449
+                $arguments = array($itemSource, $itemType, $groups);
450
+                $types = array(null, null, IQueryBuilder::PARAM_STR_ARRAY);
451
+
452
+                if ($owner !== null) {
453
+                    $where .= ' AND `uid_owner` = ?';
454
+                    $arguments[] = $owner;
455
+                    $types[] = null;
456
+                }
457
+
458
+                // TODO: inject connection, hopefully one day in the future when this
459
+                // class isn't static anymore...
460
+                $conn = \OC::$server->getDatabaseConnection();
461
+                $result = $conn->executeQuery(
462
+                    'SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where,
463
+                    $arguments,
464
+                    $types
465
+                );
466
+
467
+                while ($row = $result->fetch()) {
468
+                    $shares[] = $row;
469
+                }
470
+            }
471
+        }
472
+
473
+        return $shares;
474
+
475
+    }
476
+
477
+    /**
478
+     * Get the item of item type shared with the current user by source
479
+     * @param string $itemType
480
+     * @param string $itemSource
481
+     * @param int $format (optional) Format type must be defined by the backend
482
+     * @param mixed $parameters
483
+     * @param boolean $includeCollections
484
+     * @param string $shareWith (optional) define against which user should be checked, default: current user
485
+     * @return array
486
+     */
487
+    public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE,
488
+                                                        $parameters = null, $includeCollections = false, $shareWith = null) {
489
+        $shareWith = ($shareWith === null) ? \OC_User::getUser() : $shareWith;
490
+        return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, $shareWith, null, $format,
491
+            $parameters, 1, $includeCollections, true);
492
+    }
493
+
494
+    /**
495
+     * Get the item of item type shared by a link
496
+     * @param string $itemType
497
+     * @param string $itemSource
498
+     * @param string $uidOwner Owner of link
499
+     * @return array
500
+     */
501
+    public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) {
502
+        return self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE,
503
+            null, 1);
504
+    }
505
+
506
+    /**
507
+     * Based on the given token the share information will be returned - password protected shares will be verified
508
+     * @param string $token
509
+     * @param bool $checkPasswordProtection
510
+     * @return array|boolean false will be returned in case the token is unknown or unauthorized
511
+     */
512
+    public static function getShareByToken($token, $checkPasswordProtection = true) {
513
+        $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?', 1);
514
+        $result = $query->execute(array($token));
515
+        if ($result === false) {
516
+            \OCP\Util::writeLog('OCP\Share', \OC_DB::getErrorMessage() . ', token=' . $token, \OCP\Util::ERROR);
517
+        }
518
+        $row = $result->fetchRow();
519
+        if ($row === false) {
520
+            return false;
521
+        }
522
+        if (is_array($row) and self::expireItem($row)) {
523
+            return false;
524
+        }
525
+
526
+        // password protected shares need to be authenticated
527
+        if ($checkPasswordProtection && !\OCP\Share::checkPasswordProtectedShare($row)) {
528
+            return false;
529
+        }
530
+
531
+        return $row;
532
+    }
533
+
534
+    /**
535
+     * resolves reshares down to the last real share
536
+     * @param array $linkItem
537
+     * @return array file owner
538
+     */
539
+    public static function resolveReShare($linkItem)
540
+    {
541
+        if (isset($linkItem['parent'])) {
542
+            $parent = $linkItem['parent'];
543
+            while (isset($parent)) {
544
+                $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `id` = ?', 1);
545
+                $item = $query->execute(array($parent))->fetchRow();
546
+                if (isset($item['parent'])) {
547
+                    $parent = $item['parent'];
548
+                } else {
549
+                    return $item;
550
+                }
551
+            }
552
+        }
553
+        return $linkItem;
554
+    }
555
+
556
+
557
+    /**
558
+     * Get the shared items of item type owned by the current user
559
+     * @param string $itemType
560
+     * @param int $format (optional) Format type must be defined by the backend
561
+     * @param mixed $parameters
562
+     * @param int $limit Number of items to return (optional) Returns all by default
563
+     * @param boolean $includeCollections
564
+     * @return mixed Return depends on format
565
+     */
566
+    public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null,
567
+                                            $limit = -1, $includeCollections = false) {
568
+        return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format,
569
+            $parameters, $limit, $includeCollections);
570
+    }
571
+
572
+    /**
573
+     * Get the shared item of item type owned by the current user
574
+     * @param string $itemType
575
+     * @param string $itemSource
576
+     * @param int $format (optional) Format type must be defined by the backend
577
+     * @param mixed $parameters
578
+     * @param boolean $includeCollections
579
+     * @return mixed Return depends on format
580
+     */
581
+    public static function getItemShared($itemType, $itemSource, $format = self::FORMAT_NONE,
582
+                                            $parameters = null, $includeCollections = false) {
583
+        return self::getItems($itemType, $itemSource, null, null, \OC_User::getUser(), $format,
584
+            $parameters, -1, $includeCollections);
585
+    }
586
+
587
+    /**
588
+     * Get all users an item is shared with
589
+     * @param string $itemType
590
+     * @param string $itemSource
591
+     * @param string $uidOwner
592
+     * @param boolean $includeCollections
593
+     * @param boolean $checkExpireDate
594
+     * @return array Return array of users
595
+     */
596
+    public static function getUsersItemShared($itemType, $itemSource, $uidOwner, $includeCollections = false, $checkExpireDate = true) {
597
+
598
+        $users = array();
599
+        $items = self::getItems($itemType, $itemSource, null, null, $uidOwner, self::FORMAT_NONE, null, -1, $includeCollections, false, $checkExpireDate);
600
+        if ($items) {
601
+            foreach ($items as $item) {
602
+                if ((int)$item['share_type'] === self::SHARE_TYPE_USER) {
603
+                    $users[] = $item['share_with'];
604
+                } else if ((int)$item['share_type'] === self::SHARE_TYPE_GROUP) {
605
+                    $users = array_merge($users, \OC_Group::usersInGroup($item['share_with']));
606
+                }
607
+            }
608
+        }
609
+        return $users;
610
+    }
611
+
612
+    /**
613
+     * Share an item with a user, group, or via private link
614
+     * @param string $itemType
615
+     * @param string $itemSource
616
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
617
+     * @param string $shareWith User or group the item is being shared with
618
+     * @param int $permissions CRUDS
619
+     * @param string $itemSourceName
620
+     * @param \DateTime $expirationDate
621
+     * @param bool $passwordChanged
622
+     * @return boolean|string Returns true on success or false on failure, Returns token on success for links
623
+     * @throws \OC\HintException when the share type is remote and the shareWith is invalid
624
+     * @throws \Exception
625
+     */
626
+    public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null, \DateTime $expirationDate = null, $passwordChanged = null) {
627
+
628
+        $backend = self::getBackend($itemType);
629
+        $l = \OC::$server->getL10N('lib');
630
+
631
+        if ($backend->isShareTypeAllowed($shareType) === false) {
632
+            $message = 'Sharing %s failed, because the backend does not allow shares from type %i';
633
+            $message_t = $l->t('Sharing %s failed, because the backend does not allow shares from type %i', array($itemSourceName, $shareType));
634
+            \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareType), \OCP\Util::DEBUG);
635
+            throw new \Exception($message_t);
636
+        }
637
+
638
+        $uidOwner = \OC_User::getUser();
639
+        $shareWithinGroupOnly = self::shareWithGroupMembersOnly();
640
+
641
+        if (is_null($itemSourceName)) {
642
+            $itemSourceName = $itemSource;
643
+        }
644
+        $itemName = $itemSourceName;
645
+
646
+        // check if file can be shared
647
+        if ($itemType === 'file' or $itemType === 'folder') {
648
+            $path = \OC\Files\Filesystem::getPath($itemSource);
649
+            $itemName = $path;
650
+
651
+            // verify that the file exists before we try to share it
652
+            if (!$path) {
653
+                $message = 'Sharing %s failed, because the file does not exist';
654
+                $message_t = $l->t('Sharing %s failed, because the file does not exist', array($itemSourceName));
655
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG);
656
+                throw new \Exception($message_t);
657
+            }
658
+            // verify that the user has share permission
659
+            if (!\OC\Files\Filesystem::isSharable($path) || \OCP\Util::isSharingDisabledForUser()) {
660
+                $message = 'You are not allowed to share %s';
661
+                $message_t = $l->t('You are not allowed to share %s', [$path]);
662
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $path), \OCP\Util::DEBUG);
663
+                throw new \Exception($message_t);
664
+            }
665
+        }
666
+
667
+        //verify that we don't share a folder which already contains a share mount point
668
+        if ($itemType === 'folder') {
669
+            $path = '/' . $uidOwner . '/files' . \OC\Files\Filesystem::getPath($itemSource) . '/';
670
+            $mountManager = \OC\Files\Filesystem::getMountManager();
671
+            $mounts = $mountManager->findIn($path);
672
+            foreach ($mounts as $mount) {
673
+                if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
674
+                    $message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!';
675
+                    \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG);
676
+                    throw new \Exception($message);
677
+                }
678
+
679
+            }
680
+        }
681
+
682
+        // single file shares should never have delete permissions
683
+        if ($itemType === 'file') {
684
+            $permissions = (int)$permissions & ~\OCP\Constants::PERMISSION_DELETE;
685
+        }
686
+
687
+        //Validate expirationDate
688
+        if ($expirationDate !== null) {
689
+            try {
690
+                /*
691 691
 				 * Reuse the validateExpireDate.
692 692
 				 * We have to pass time() since the second arg is the time
693 693
 				 * the file was shared, since it is not shared yet we just use
694 694
 				 * the current time.
695 695
 				 */
696
-				$expirationDate = self::validateExpireDate($expirationDate->format('Y-m-d'), time(), $itemType, $itemSource);
697
-			} catch (\Exception $e) {
698
-				throw new \OC\HintException($e->getMessage(), $e->getMessage(), 404);
699
-			}
700
-		}
701
-
702
-		// Verify share type and sharing conditions are met
703
-		if ($shareType === self::SHARE_TYPE_USER) {
704
-			if ($shareWith == $uidOwner) {
705
-				$message = 'Sharing %s failed, because you can not share with yourself';
706
-				$message_t = $l->t('Sharing %s failed, because you can not share with yourself', [$itemName]);
707
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG);
708
-				throw new \Exception($message_t);
709
-			}
710
-			if (!\OC_User::userExists($shareWith)) {
711
-				$message = 'Sharing %s failed, because the user %s does not exist';
712
-				$message_t = $l->t('Sharing %s failed, because the user %s does not exist', array($itemSourceName, $shareWith));
713
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
714
-				throw new \Exception($message_t);
715
-			}
716
-			if ($shareWithinGroupOnly) {
717
-				$inGroup = array_intersect(\OC_Group::getUserGroups($uidOwner), \OC_Group::getUserGroups($shareWith));
718
-				if (empty($inGroup)) {
719
-					$message = 'Sharing %s failed, because the user '
720
-						.'%s is not a member of any groups that %s is a member of';
721
-					$message_t = $l->t('Sharing %s failed, because the user %s is not a member of any groups that %s is a member of', array($itemName, $shareWith, $uidOwner));
722
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemName, $shareWith, $uidOwner), \OCP\Util::DEBUG);
723
-					throw new \Exception($message_t);
724
-				}
725
-			}
726
-			// Check if the item source is already shared with the user, either from the same owner or a different user
727
-			if ($checkExists = self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups,
728
-				$shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
729
-				// Only allow the same share to occur again if it is the same
730
-				// owner and is not a user share, this use case is for increasing
731
-				// permissions for a specific user
732
-				if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
733
-					$message = 'Sharing %s failed, because this item is already shared with %s';
734
-					$message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith));
735
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
736
-					throw new \Exception($message_t);
737
-				}
738
-			}
739
-			if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_USER,
740
-				$shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
741
-				// Only allow the same share to occur again if it is the same
742
-				// owner and is not a user share, this use case is for increasing
743
-				// permissions for a specific user
744
-				if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
745
-					$message = 'Sharing %s failed, because this item is already shared with user %s';
746
-					$message_t = $l->t('Sharing %s failed, because this item is already shared with user %s', array($itemSourceName, $shareWith));
747
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::ERROR);
748
-					throw new \Exception($message_t);
749
-				}
750
-			}
751
-		} else if ($shareType === self::SHARE_TYPE_GROUP) {
752
-			if (!\OC_Group::groupExists($shareWith)) {
753
-				$message = 'Sharing %s failed, because the group %s does not exist';
754
-				$message_t = $l->t('Sharing %s failed, because the group %s does not exist', array($itemSourceName, $shareWith));
755
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
756
-				throw new \Exception($message_t);
757
-			}
758
-			if ($shareWithinGroupOnly && !\OC_Group::inGroup($uidOwner, $shareWith)) {
759
-				$message = 'Sharing %s failed, because '
760
-					.'%s is not a member of the group %s';
761
-				$message_t = $l->t('Sharing %s failed, because %s is not a member of the group %s', array($itemSourceName, $uidOwner, $shareWith));
762
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $uidOwner, $shareWith), \OCP\Util::DEBUG);
763
-				throw new \Exception($message_t);
764
-			}
765
-			// Check if the item source is already shared with the group, either from the same owner or a different user
766
-			// The check for each user in the group is done inside the put() function
767
-			if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_GROUP, $shareWith,
768
-				null, self::FORMAT_NONE, null, 1, true, true)) {
769
-
770
-				if ($checkExists['share_with'] === $shareWith && $checkExists['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
771
-					$message = 'Sharing %s failed, because this item is already shared with %s';
772
-					$message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith));
773
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
774
-					throw new \Exception($message_t);
775
-				}
776
-			}
777
-			// Convert share with into an array with the keys group and users
778
-			$group = $shareWith;
779
-			$shareWith = array();
780
-			$shareWith['group'] = $group;
781
-			$shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner));
782
-		} else if ($shareType === self::SHARE_TYPE_LINK) {
783
-			$updateExistingShare = false;
784
-			if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') == 'yes') {
785
-
786
-				// IF the password is changed via the old ajax endpoint verify it before deleting the old share
787
-				if ($passwordChanged === true) {
788
-					self::verifyPassword($shareWith);
789
-				}
790
-
791
-				// when updating a link share
792
-				// FIXME Don't delete link if we update it
793
-				if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null,
794
-					$uidOwner, self::FORMAT_NONE, null, 1)) {
795
-					// remember old token
796
-					$oldToken = $checkExists['token'];
797
-					$oldPermissions = $checkExists['permissions'];
798
-					//delete the old share
799
-					Helper::delete($checkExists['id']);
800
-					$updateExistingShare = true;
801
-				}
802
-
803
-				if ($passwordChanged === null) {
804
-					// Generate hash of password - same method as user passwords
805
-					if (is_string($shareWith) && $shareWith !== '') {
806
-						self::verifyPassword($shareWith);
807
-						$shareWith = \OC::$server->getHasher()->hash($shareWith);
808
-					} else {
809
-						// reuse the already set password, but only if we change permissions
810
-						// otherwise the user disabled the password protection
811
-						if ($checkExists && (int)$permissions !== (int)$oldPermissions) {
812
-							$shareWith = $checkExists['share_with'];
813
-						}
814
-					}
815
-				} else {
816
-					if ($passwordChanged === true) {
817
-						if (is_string($shareWith) && $shareWith !== '') {
818
-							self::verifyPassword($shareWith);
819
-							$shareWith = \OC::$server->getHasher()->hash($shareWith);
820
-						}
821
-					} else if ($updateExistingShare) {
822
-						$shareWith = $checkExists['share_with'];
823
-					}
824
-				}
825
-
826
-				if (\OCP\Util::isPublicLinkPasswordRequired() && empty($shareWith)) {
827
-					$message = 'You need to provide a password to create a public link, only protected links are allowed';
828
-					$message_t = $l->t('You need to provide a password to create a public link, only protected links are allowed');
829
-					\OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG);
830
-					throw new \Exception($message_t);
831
-				}
832
-
833
-				if ($updateExistingShare === false &&
834
-					self::isDefaultExpireDateEnabled() &&
835
-					empty($expirationDate)) {
836
-					$expirationDate = Helper::calcExpireDate();
837
-				}
838
-
839
-				// Generate token
840
-				if (isset($oldToken)) {
841
-					$token = $oldToken;
842
-				} else {
843
-					$token = \OC::$server->getSecureRandom()->generate(self::TOKEN_LENGTH,
844
-						\OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_UPPER.
845
-						\OCP\Security\ISecureRandom::CHAR_DIGITS
846
-					);
847
-				}
848
-				$result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions,
849
-					null, $token, $itemSourceName, $expirationDate);
850
-				if ($result) {
851
-					return $token;
852
-				} else {
853
-					return false;
854
-				}
855
-			}
856
-			$message = 'Sharing %s failed, because sharing with links is not allowed';
857
-			$message_t = $l->t('Sharing %s failed, because sharing with links is not allowed', array($itemSourceName));
858
-			\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG);
859
-			throw new \Exception($message_t);
860
-		} else if ($shareType === self::SHARE_TYPE_REMOTE) {
861
-
862
-			/*
696
+                $expirationDate = self::validateExpireDate($expirationDate->format('Y-m-d'), time(), $itemType, $itemSource);
697
+            } catch (\Exception $e) {
698
+                throw new \OC\HintException($e->getMessage(), $e->getMessage(), 404);
699
+            }
700
+        }
701
+
702
+        // Verify share type and sharing conditions are met
703
+        if ($shareType === self::SHARE_TYPE_USER) {
704
+            if ($shareWith == $uidOwner) {
705
+                $message = 'Sharing %s failed, because you can not share with yourself';
706
+                $message_t = $l->t('Sharing %s failed, because you can not share with yourself', [$itemName]);
707
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG);
708
+                throw new \Exception($message_t);
709
+            }
710
+            if (!\OC_User::userExists($shareWith)) {
711
+                $message = 'Sharing %s failed, because the user %s does not exist';
712
+                $message_t = $l->t('Sharing %s failed, because the user %s does not exist', array($itemSourceName, $shareWith));
713
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
714
+                throw new \Exception($message_t);
715
+            }
716
+            if ($shareWithinGroupOnly) {
717
+                $inGroup = array_intersect(\OC_Group::getUserGroups($uidOwner), \OC_Group::getUserGroups($shareWith));
718
+                if (empty($inGroup)) {
719
+                    $message = 'Sharing %s failed, because the user '
720
+                        .'%s is not a member of any groups that %s is a member of';
721
+                    $message_t = $l->t('Sharing %s failed, because the user %s is not a member of any groups that %s is a member of', array($itemName, $shareWith, $uidOwner));
722
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemName, $shareWith, $uidOwner), \OCP\Util::DEBUG);
723
+                    throw new \Exception($message_t);
724
+                }
725
+            }
726
+            // Check if the item source is already shared with the user, either from the same owner or a different user
727
+            if ($checkExists = self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups,
728
+                $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
729
+                // Only allow the same share to occur again if it is the same
730
+                // owner and is not a user share, this use case is for increasing
731
+                // permissions for a specific user
732
+                if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
733
+                    $message = 'Sharing %s failed, because this item is already shared with %s';
734
+                    $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith));
735
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
736
+                    throw new \Exception($message_t);
737
+                }
738
+            }
739
+            if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_USER,
740
+                $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) {
741
+                // Only allow the same share to occur again if it is the same
742
+                // owner and is not a user share, this use case is for increasing
743
+                // permissions for a specific user
744
+                if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) {
745
+                    $message = 'Sharing %s failed, because this item is already shared with user %s';
746
+                    $message_t = $l->t('Sharing %s failed, because this item is already shared with user %s', array($itemSourceName, $shareWith));
747
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::ERROR);
748
+                    throw new \Exception($message_t);
749
+                }
750
+            }
751
+        } else if ($shareType === self::SHARE_TYPE_GROUP) {
752
+            if (!\OC_Group::groupExists($shareWith)) {
753
+                $message = 'Sharing %s failed, because the group %s does not exist';
754
+                $message_t = $l->t('Sharing %s failed, because the group %s does not exist', array($itemSourceName, $shareWith));
755
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
756
+                throw new \Exception($message_t);
757
+            }
758
+            if ($shareWithinGroupOnly && !\OC_Group::inGroup($uidOwner, $shareWith)) {
759
+                $message = 'Sharing %s failed, because '
760
+                    .'%s is not a member of the group %s';
761
+                $message_t = $l->t('Sharing %s failed, because %s is not a member of the group %s', array($itemSourceName, $uidOwner, $shareWith));
762
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $uidOwner, $shareWith), \OCP\Util::DEBUG);
763
+                throw new \Exception($message_t);
764
+            }
765
+            // Check if the item source is already shared with the group, either from the same owner or a different user
766
+            // The check for each user in the group is done inside the put() function
767
+            if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_GROUP, $shareWith,
768
+                null, self::FORMAT_NONE, null, 1, true, true)) {
769
+
770
+                if ($checkExists['share_with'] === $shareWith && $checkExists['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
771
+                    $message = 'Sharing %s failed, because this item is already shared with %s';
772
+                    $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith));
773
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
774
+                    throw new \Exception($message_t);
775
+                }
776
+            }
777
+            // Convert share with into an array with the keys group and users
778
+            $group = $shareWith;
779
+            $shareWith = array();
780
+            $shareWith['group'] = $group;
781
+            $shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner));
782
+        } else if ($shareType === self::SHARE_TYPE_LINK) {
783
+            $updateExistingShare = false;
784
+            if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') == 'yes') {
785
+
786
+                // IF the password is changed via the old ajax endpoint verify it before deleting the old share
787
+                if ($passwordChanged === true) {
788
+                    self::verifyPassword($shareWith);
789
+                }
790
+
791
+                // when updating a link share
792
+                // FIXME Don't delete link if we update it
793
+                if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null,
794
+                    $uidOwner, self::FORMAT_NONE, null, 1)) {
795
+                    // remember old token
796
+                    $oldToken = $checkExists['token'];
797
+                    $oldPermissions = $checkExists['permissions'];
798
+                    //delete the old share
799
+                    Helper::delete($checkExists['id']);
800
+                    $updateExistingShare = true;
801
+                }
802
+
803
+                if ($passwordChanged === null) {
804
+                    // Generate hash of password - same method as user passwords
805
+                    if (is_string($shareWith) && $shareWith !== '') {
806
+                        self::verifyPassword($shareWith);
807
+                        $shareWith = \OC::$server->getHasher()->hash($shareWith);
808
+                    } else {
809
+                        // reuse the already set password, but only if we change permissions
810
+                        // otherwise the user disabled the password protection
811
+                        if ($checkExists && (int)$permissions !== (int)$oldPermissions) {
812
+                            $shareWith = $checkExists['share_with'];
813
+                        }
814
+                    }
815
+                } else {
816
+                    if ($passwordChanged === true) {
817
+                        if (is_string($shareWith) && $shareWith !== '') {
818
+                            self::verifyPassword($shareWith);
819
+                            $shareWith = \OC::$server->getHasher()->hash($shareWith);
820
+                        }
821
+                    } else if ($updateExistingShare) {
822
+                        $shareWith = $checkExists['share_with'];
823
+                    }
824
+                }
825
+
826
+                if (\OCP\Util::isPublicLinkPasswordRequired() && empty($shareWith)) {
827
+                    $message = 'You need to provide a password to create a public link, only protected links are allowed';
828
+                    $message_t = $l->t('You need to provide a password to create a public link, only protected links are allowed');
829
+                    \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG);
830
+                    throw new \Exception($message_t);
831
+                }
832
+
833
+                if ($updateExistingShare === false &&
834
+                    self::isDefaultExpireDateEnabled() &&
835
+                    empty($expirationDate)) {
836
+                    $expirationDate = Helper::calcExpireDate();
837
+                }
838
+
839
+                // Generate token
840
+                if (isset($oldToken)) {
841
+                    $token = $oldToken;
842
+                } else {
843
+                    $token = \OC::$server->getSecureRandom()->generate(self::TOKEN_LENGTH,
844
+                        \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_UPPER.
845
+                        \OCP\Security\ISecureRandom::CHAR_DIGITS
846
+                    );
847
+                }
848
+                $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions,
849
+                    null, $token, $itemSourceName, $expirationDate);
850
+                if ($result) {
851
+                    return $token;
852
+                } else {
853
+                    return false;
854
+                }
855
+            }
856
+            $message = 'Sharing %s failed, because sharing with links is not allowed';
857
+            $message_t = $l->t('Sharing %s failed, because sharing with links is not allowed', array($itemSourceName));
858
+            \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG);
859
+            throw new \Exception($message_t);
860
+        } else if ($shareType === self::SHARE_TYPE_REMOTE) {
861
+
862
+            /*
863 863
 			 * Check if file is not already shared with the remote user
864 864
 			 */
865
-			if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_REMOTE,
866
-				$shareWith, $uidOwner, self::FORMAT_NONE, null, 1, true, true)) {
867
-					$message = 'Sharing %s failed, because this item is already shared with %s';
868
-					$message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith));
869
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
870
-					throw new \Exception($message_t);
871
-			}
872
-
873
-			// don't allow federated shares if source and target server are the same
874
-			list($user, $remote) = Helper::splitUserRemote($shareWith);
875
-			$currentServer = self::removeProtocolFromUrl(\OC::$server->getURLGenerator()->getAbsoluteURL('/'));
876
-			$currentUser = \OC::$server->getUserSession()->getUser()->getUID();
877
-			if (Helper::isSameUserOnSameServer($user, $remote, $currentUser, $currentServer)) {
878
-				$message = 'Not allowed to create a federated share with the same user.';
879
-				$message_t = $l->t('Not allowed to create a federated share with the same user');
880
-				\OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG);
881
-				throw new \Exception($message_t);
882
-			}
883
-
884
-			$token = \OC::$server->getSecureRandom()->generate(self::TOKEN_LENGTH, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER .
885
-				\OCP\Security\ISecureRandom::CHAR_DIGITS);
886
-
887
-			$shareWith = $user . '@' . $remote;
888
-			$shareId = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName);
889
-
890
-			$send = false;
891
-			if ($shareId) {
892
-				$send = self::sendRemoteShare($token, $shareWith, $itemSourceName, $shareId, $uidOwner);
893
-			}
894
-
895
-			if ($send === false) {
896
-				$currentUser = \OC::$server->getUserSession()->getUser()->getUID();
897
-				self::unshare($itemType, $itemSource, $shareType, $shareWith, $currentUser);
898
-				$message_t = $l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', array($itemSourceName, $shareWith));
899
-				throw new \Exception($message_t);
900
-			}
901
-
902
-			return $send;
903
-		} else {
904
-			// Future share types need to include their own conditions
905
-			$message = 'Share type %s is not valid for %s';
906
-			$message_t = $l->t('Share type %s is not valid for %s', array($shareType, $itemSource));
907
-			\OCP\Util::writeLog('OCP\Share', sprintf($message, $shareType, $itemSource), \OCP\Util::DEBUG);
908
-			throw new \Exception($message_t);
909
-		}
910
-
911
-		// Put the item into the database
912
-		$result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName, $expirationDate);
913
-
914
-		return $result ? true : false;
915
-	}
916
-
917
-	/**
918
-	 * Unshare an item from a user, group, or delete a private link
919
-	 * @param string $itemType
920
-	 * @param string $itemSource
921
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
922
-	 * @param string $shareWith User or group the item is being shared with
923
-	 * @param string $owner owner of the share, if null the current user is used
924
-	 * @return boolean true on success or false on failure
925
-	 */
926
-	public static function unshare($itemType, $itemSource, $shareType, $shareWith, $owner = null) {
927
-
928
-		// check if it is a valid itemType
929
-		self::getBackend($itemType);
930
-
931
-		$items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith, $owner, $shareType);
932
-
933
-		$toDelete = array();
934
-		$newParent = null;
935
-		$currentUser = $owner ? $owner : \OC_User::getUser();
936
-		foreach ($items as $item) {
937
-			// delete the item with the expected share_type and owner
938
-			if ((int)$item['share_type'] === (int)$shareType && $item['uid_owner'] === $currentUser) {
939
-				$toDelete = $item;
940
-				// if there is more then one result we don't have to delete the children
941
-				// but update their parent. For group shares the new parent should always be
942
-				// the original group share and not the db entry with the unique name
943
-			} else if ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
944
-				$newParent = $item['parent'];
945
-			} else {
946
-				$newParent = $item['id'];
947
-			}
948
-		}
949
-
950
-		if (!empty($toDelete)) {
951
-			self::unshareItem($toDelete, $newParent);
952
-			return true;
953
-		}
954
-		return false;
955
-	}
956
-
957
-	/**
958
-	 * Unshare an item from all users, groups, and remove all links
959
-	 * @param string $itemType
960
-	 * @param string $itemSource
961
-	 * @return boolean true on success or false on failure
962
-	 */
963
-	public static function unshareAll($itemType, $itemSource) {
964
-		// Get all of the owners of shares of this item.
965
-		$query = \OC_DB::prepare( 'SELECT `uid_owner` from `*PREFIX*share` WHERE `item_type`=? AND `item_source`=?' );
966
-		$result = $query->execute(array($itemType, $itemSource));
967
-		$shares = array();
968
-		// Add each owner's shares to the array of all shares for this item.
969
-		while ($row = $result->fetchRow()) {
970
-			$shares = array_merge($shares, self::getItems($itemType, $itemSource, null, null, $row['uid_owner']));
971
-		}
972
-		if (!empty($shares)) {
973
-			// Pass all the vars we have for now, they may be useful
974
-			$hookParams = array(
975
-				'itemType' => $itemType,
976
-				'itemSource' => $itemSource,
977
-				'shares' => $shares,
978
-			);
979
-			\OC_Hook::emit('OCP\Share', 'pre_unshareAll', $hookParams);
980
-			foreach ($shares as $share) {
981
-				self::unshareItem($share);
982
-			}
983
-			\OC_Hook::emit('OCP\Share', 'post_unshareAll', $hookParams);
984
-			return true;
985
-		}
986
-		return false;
987
-	}
988
-
989
-	/**
990
-	 * Unshare an item shared with the current user
991
-	 * @param string $itemType
992
-	 * @param string $itemOrigin Item target or source
993
-	 * @param boolean $originIsSource true if $itemOrigin is the source, false if $itemOrigin is the target (optional)
994
-	 * @return boolean true on success or false on failure
995
-	 *
996
-	 * Unsharing from self is not allowed for items inside collections
997
-	 */
998
-	public static function unshareFromSelf($itemType, $itemOrigin, $originIsSource = false) {
999
-		$originType = ($originIsSource) ? 'source' : 'target';
1000
-		$uid = \OCP\User::getUser();
1001
-
1002
-		if ($itemType === 'file' || $itemType === 'folder') {
1003
-			$statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `file_' . $originType . '` = ?';
1004
-		} else {
1005
-			$statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `item_' . $originType . '` = ?';
1006
-		}
1007
-
1008
-		$query = \OCP\DB::prepare($statement);
1009
-		$result = $query->execute(array($itemType, $itemOrigin));
1010
-
1011
-		$shares = $result->fetchAll();
1012
-
1013
-		$listOfUnsharedItems = array();
1014
-
1015
-		$itemUnshared = false;
1016
-		foreach ($shares as $share) {
1017
-			if ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_USER &&
1018
-				$share['share_with'] === $uid) {
1019
-				$deletedShares = Helper::delete($share['id']);
1020
-				$shareTmp = array(
1021
-					'id' => $share['id'],
1022
-					'shareWith' => $share['share_with'],
1023
-					'itemTarget' => $share['item_target'],
1024
-					'itemType' => $share['item_type'],
1025
-					'shareType' => (int)$share['share_type'],
1026
-				);
1027
-				if (isset($share['file_target'])) {
1028
-					$shareTmp['fileTarget'] = $share['file_target'];
1029
-				}
1030
-				$listOfUnsharedItems = array_merge($listOfUnsharedItems, $deletedShares, array($shareTmp));
1031
-				$itemUnshared = true;
1032
-				break;
1033
-			} elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
1034
-				if (\OC_Group::inGroup($uid, $share['share_with'])) {
1035
-					$groupShare = $share;
1036
-				}
1037
-			} elseif ((int)$share['share_type'] === self::$shareTypeGroupUserUnique &&
1038
-				$share['share_with'] === $uid) {
1039
-				$uniqueGroupShare = $share;
1040
-			}
1041
-		}
1042
-
1043
-		if (!$itemUnshared && isset($groupShare) && !isset($uniqueGroupShare)) {
1044
-			$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share`'
1045
-				.' (`item_type`, `item_source`, `item_target`, `parent`, `share_type`,'
1046
-				.' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`, `file_target`)'
1047
-				.' VALUES (?,?,?,?,?,?,?,?,?,?,?)');
1048
-			$query->execute(array($groupShare['item_type'], $groupShare['item_source'], $groupShare['item_target'],
1049
-				$groupShare['id'], self::$shareTypeGroupUserUnique,
1050
-				\OC_User::getUser(), $groupShare['uid_owner'], 0, $groupShare['stime'], $groupShare['file_source'],
1051
-				$groupShare['file_target']));
1052
-			$shareTmp = array(
1053
-				'id' => $groupShare['id'],
1054
-				'shareWith' => $groupShare['share_with'],
1055
-				'itemTarget' => $groupShare['item_target'],
1056
-				'itemType' => $groupShare['item_type'],
1057
-				'shareType' => (int)$groupShare['share_type'],
1058
-			);
1059
-			if (isset($groupShare['file_target'])) {
1060
-				$shareTmp['fileTarget'] = $groupShare['file_target'];
1061
-			}
1062
-			$listOfUnsharedItems = array_merge($listOfUnsharedItems, [$shareTmp]);
1063
-			$itemUnshared = true;
1064
-		} elseif (!$itemUnshared && isset($uniqueGroupShare)) {
1065
-			$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?');
1066
-			$query->execute(array(0, $uniqueGroupShare['id']));
1067
-			$shareTmp = array(
1068
-				'id' => $uniqueGroupShare['id'],
1069
-				'shareWith' => $uniqueGroupShare['share_with'],
1070
-				'itemTarget' => $uniqueGroupShare['item_target'],
1071
-				'itemType' => $uniqueGroupShare['item_type'],
1072
-				'shareType' => (int)$uniqueGroupShare['share_type'],
1073
-			);
1074
-			if (isset($uniqueGroupShare['file_target'])) {
1075
-				$shareTmp['fileTarget'] = $uniqueGroupShare['file_target'];
1076
-			}
1077
-			$listOfUnsharedItems = array_merge($listOfUnsharedItems, [$shareTmp]);
1078
-			$itemUnshared = true;
1079
-		}
1080
-
1081
-		if ($itemUnshared) {
1082
-			\OC_Hook::emit('OCP\Share', 'post_unshareFromSelf',
1083
-				array('unsharedItems' => $listOfUnsharedItems, 'itemType' => $itemType));
1084
-		}
1085
-
1086
-		return $itemUnshared;
1087
-	}
1088
-
1089
-	/**
1090
-	 * sent status if users got informed by mail about share
1091
-	 * @param string $itemType
1092
-	 * @param string $itemSource
1093
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
1094
-	 * @param string $recipient with whom was the file shared
1095
-	 * @param boolean $status
1096
-	 */
1097
-	public static function setSendMailStatus($itemType, $itemSource, $shareType, $recipient, $status) {
1098
-		$status = $status ? 1 : 0;
1099
-
1100
-		$query = \OC_DB::prepare(
1101
-			'UPDATE `*PREFIX*share`
865
+            if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_REMOTE,
866
+                $shareWith, $uidOwner, self::FORMAT_NONE, null, 1, true, true)) {
867
+                    $message = 'Sharing %s failed, because this item is already shared with %s';
868
+                    $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith));
869
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
870
+                    throw new \Exception($message_t);
871
+            }
872
+
873
+            // don't allow federated shares if source and target server are the same
874
+            list($user, $remote) = Helper::splitUserRemote($shareWith);
875
+            $currentServer = self::removeProtocolFromUrl(\OC::$server->getURLGenerator()->getAbsoluteURL('/'));
876
+            $currentUser = \OC::$server->getUserSession()->getUser()->getUID();
877
+            if (Helper::isSameUserOnSameServer($user, $remote, $currentUser, $currentServer)) {
878
+                $message = 'Not allowed to create a federated share with the same user.';
879
+                $message_t = $l->t('Not allowed to create a federated share with the same user');
880
+                \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::DEBUG);
881
+                throw new \Exception($message_t);
882
+            }
883
+
884
+            $token = \OC::$server->getSecureRandom()->generate(self::TOKEN_LENGTH, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER .
885
+                \OCP\Security\ISecureRandom::CHAR_DIGITS);
886
+
887
+            $shareWith = $user . '@' . $remote;
888
+            $shareId = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName);
889
+
890
+            $send = false;
891
+            if ($shareId) {
892
+                $send = self::sendRemoteShare($token, $shareWith, $itemSourceName, $shareId, $uidOwner);
893
+            }
894
+
895
+            if ($send === false) {
896
+                $currentUser = \OC::$server->getUserSession()->getUser()->getUID();
897
+                self::unshare($itemType, $itemSource, $shareType, $shareWith, $currentUser);
898
+                $message_t = $l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', array($itemSourceName, $shareWith));
899
+                throw new \Exception($message_t);
900
+            }
901
+
902
+            return $send;
903
+        } else {
904
+            // Future share types need to include their own conditions
905
+            $message = 'Share type %s is not valid for %s';
906
+            $message_t = $l->t('Share type %s is not valid for %s', array($shareType, $itemSource));
907
+            \OCP\Util::writeLog('OCP\Share', sprintf($message, $shareType, $itemSource), \OCP\Util::DEBUG);
908
+            throw new \Exception($message_t);
909
+        }
910
+
911
+        // Put the item into the database
912
+        $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName, $expirationDate);
913
+
914
+        return $result ? true : false;
915
+    }
916
+
917
+    /**
918
+     * Unshare an item from a user, group, or delete a private link
919
+     * @param string $itemType
920
+     * @param string $itemSource
921
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
922
+     * @param string $shareWith User or group the item is being shared with
923
+     * @param string $owner owner of the share, if null the current user is used
924
+     * @return boolean true on success or false on failure
925
+     */
926
+    public static function unshare($itemType, $itemSource, $shareType, $shareWith, $owner = null) {
927
+
928
+        // check if it is a valid itemType
929
+        self::getBackend($itemType);
930
+
931
+        $items = self::getItemSharedWithUser($itemType, $itemSource, $shareWith, $owner, $shareType);
932
+
933
+        $toDelete = array();
934
+        $newParent = null;
935
+        $currentUser = $owner ? $owner : \OC_User::getUser();
936
+        foreach ($items as $item) {
937
+            // delete the item with the expected share_type and owner
938
+            if ((int)$item['share_type'] === (int)$shareType && $item['uid_owner'] === $currentUser) {
939
+                $toDelete = $item;
940
+                // if there is more then one result we don't have to delete the children
941
+                // but update their parent. For group shares the new parent should always be
942
+                // the original group share and not the db entry with the unique name
943
+            } else if ((int)$item['share_type'] === self::$shareTypeGroupUserUnique) {
944
+                $newParent = $item['parent'];
945
+            } else {
946
+                $newParent = $item['id'];
947
+            }
948
+        }
949
+
950
+        if (!empty($toDelete)) {
951
+            self::unshareItem($toDelete, $newParent);
952
+            return true;
953
+        }
954
+        return false;
955
+    }
956
+
957
+    /**
958
+     * Unshare an item from all users, groups, and remove all links
959
+     * @param string $itemType
960
+     * @param string $itemSource
961
+     * @return boolean true on success or false on failure
962
+     */
963
+    public static function unshareAll($itemType, $itemSource) {
964
+        // Get all of the owners of shares of this item.
965
+        $query = \OC_DB::prepare( 'SELECT `uid_owner` from `*PREFIX*share` WHERE `item_type`=? AND `item_source`=?' );
966
+        $result = $query->execute(array($itemType, $itemSource));
967
+        $shares = array();
968
+        // Add each owner's shares to the array of all shares for this item.
969
+        while ($row = $result->fetchRow()) {
970
+            $shares = array_merge($shares, self::getItems($itemType, $itemSource, null, null, $row['uid_owner']));
971
+        }
972
+        if (!empty($shares)) {
973
+            // Pass all the vars we have for now, they may be useful
974
+            $hookParams = array(
975
+                'itemType' => $itemType,
976
+                'itemSource' => $itemSource,
977
+                'shares' => $shares,
978
+            );
979
+            \OC_Hook::emit('OCP\Share', 'pre_unshareAll', $hookParams);
980
+            foreach ($shares as $share) {
981
+                self::unshareItem($share);
982
+            }
983
+            \OC_Hook::emit('OCP\Share', 'post_unshareAll', $hookParams);
984
+            return true;
985
+        }
986
+        return false;
987
+    }
988
+
989
+    /**
990
+     * Unshare an item shared with the current user
991
+     * @param string $itemType
992
+     * @param string $itemOrigin Item target or source
993
+     * @param boolean $originIsSource true if $itemOrigin is the source, false if $itemOrigin is the target (optional)
994
+     * @return boolean true on success or false on failure
995
+     *
996
+     * Unsharing from self is not allowed for items inside collections
997
+     */
998
+    public static function unshareFromSelf($itemType, $itemOrigin, $originIsSource = false) {
999
+        $originType = ($originIsSource) ? 'source' : 'target';
1000
+        $uid = \OCP\User::getUser();
1001
+
1002
+        if ($itemType === 'file' || $itemType === 'folder') {
1003
+            $statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `file_' . $originType . '` = ?';
1004
+        } else {
1005
+            $statement = 'SELECT * FROM `*PREFIX*share` WHERE `item_type` = ? and `item_' . $originType . '` = ?';
1006
+        }
1007
+
1008
+        $query = \OCP\DB::prepare($statement);
1009
+        $result = $query->execute(array($itemType, $itemOrigin));
1010
+
1011
+        $shares = $result->fetchAll();
1012
+
1013
+        $listOfUnsharedItems = array();
1014
+
1015
+        $itemUnshared = false;
1016
+        foreach ($shares as $share) {
1017
+            if ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_USER &&
1018
+                $share['share_with'] === $uid) {
1019
+                $deletedShares = Helper::delete($share['id']);
1020
+                $shareTmp = array(
1021
+                    'id' => $share['id'],
1022
+                    'shareWith' => $share['share_with'],
1023
+                    'itemTarget' => $share['item_target'],
1024
+                    'itemType' => $share['item_type'],
1025
+                    'shareType' => (int)$share['share_type'],
1026
+                );
1027
+                if (isset($share['file_target'])) {
1028
+                    $shareTmp['fileTarget'] = $share['file_target'];
1029
+                }
1030
+                $listOfUnsharedItems = array_merge($listOfUnsharedItems, $deletedShares, array($shareTmp));
1031
+                $itemUnshared = true;
1032
+                break;
1033
+            } elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
1034
+                if (\OC_Group::inGroup($uid, $share['share_with'])) {
1035
+                    $groupShare = $share;
1036
+                }
1037
+            } elseif ((int)$share['share_type'] === self::$shareTypeGroupUserUnique &&
1038
+                $share['share_with'] === $uid) {
1039
+                $uniqueGroupShare = $share;
1040
+            }
1041
+        }
1042
+
1043
+        if (!$itemUnshared && isset($groupShare) && !isset($uniqueGroupShare)) {
1044
+            $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share`'
1045
+                .' (`item_type`, `item_source`, `item_target`, `parent`, `share_type`,'
1046
+                .' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`, `file_target`)'
1047
+                .' VALUES (?,?,?,?,?,?,?,?,?,?,?)');
1048
+            $query->execute(array($groupShare['item_type'], $groupShare['item_source'], $groupShare['item_target'],
1049
+                $groupShare['id'], self::$shareTypeGroupUserUnique,
1050
+                \OC_User::getUser(), $groupShare['uid_owner'], 0, $groupShare['stime'], $groupShare['file_source'],
1051
+                $groupShare['file_target']));
1052
+            $shareTmp = array(
1053
+                'id' => $groupShare['id'],
1054
+                'shareWith' => $groupShare['share_with'],
1055
+                'itemTarget' => $groupShare['item_target'],
1056
+                'itemType' => $groupShare['item_type'],
1057
+                'shareType' => (int)$groupShare['share_type'],
1058
+            );
1059
+            if (isset($groupShare['file_target'])) {
1060
+                $shareTmp['fileTarget'] = $groupShare['file_target'];
1061
+            }
1062
+            $listOfUnsharedItems = array_merge($listOfUnsharedItems, [$shareTmp]);
1063
+            $itemUnshared = true;
1064
+        } elseif (!$itemUnshared && isset($uniqueGroupShare)) {
1065
+            $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = ? WHERE `id` = ?');
1066
+            $query->execute(array(0, $uniqueGroupShare['id']));
1067
+            $shareTmp = array(
1068
+                'id' => $uniqueGroupShare['id'],
1069
+                'shareWith' => $uniqueGroupShare['share_with'],
1070
+                'itemTarget' => $uniqueGroupShare['item_target'],
1071
+                'itemType' => $uniqueGroupShare['item_type'],
1072
+                'shareType' => (int)$uniqueGroupShare['share_type'],
1073
+            );
1074
+            if (isset($uniqueGroupShare['file_target'])) {
1075
+                $shareTmp['fileTarget'] = $uniqueGroupShare['file_target'];
1076
+            }
1077
+            $listOfUnsharedItems = array_merge($listOfUnsharedItems, [$shareTmp]);
1078
+            $itemUnshared = true;
1079
+        }
1080
+
1081
+        if ($itemUnshared) {
1082
+            \OC_Hook::emit('OCP\Share', 'post_unshareFromSelf',
1083
+                array('unsharedItems' => $listOfUnsharedItems, 'itemType' => $itemType));
1084
+        }
1085
+
1086
+        return $itemUnshared;
1087
+    }
1088
+
1089
+    /**
1090
+     * sent status if users got informed by mail about share
1091
+     * @param string $itemType
1092
+     * @param string $itemSource
1093
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
1094
+     * @param string $recipient with whom was the file shared
1095
+     * @param boolean $status
1096
+     */
1097
+    public static function setSendMailStatus($itemType, $itemSource, $shareType, $recipient, $status) {
1098
+        $status = $status ? 1 : 0;
1099
+
1100
+        $query = \OC_DB::prepare(
1101
+            'UPDATE `*PREFIX*share`
1102 1102
 					SET `mail_send` = ?
1103 1103
 					WHERE `item_type` = ? AND `item_source` = ? AND `share_type` = ? AND `share_with` = ?');
1104 1104
 
1105
-		$result = $query->execute(array($status, $itemType, $itemSource, $shareType, $recipient));
1106
-
1107
-		if($result === false) {
1108
-			\OCP\Util::writeLog('OCP\Share', 'Couldn\'t set send mail status', \OCP\Util::ERROR);
1109
-		}
1110
-	}
1111
-
1112
-	/**
1113
-	 * Set the permissions of an item for a specific user or group
1114
-	 * @param string $itemType
1115
-	 * @param string $itemSource
1116
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
1117
-	 * @param string $shareWith User or group the item is being shared with
1118
-	 * @param int $permissions CRUDS permissions
1119
-	 * @return boolean true on success or false on failure
1120
-	 * @throws \Exception when trying to grant more permissions then the user has himself
1121
-	 */
1122
-	public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) {
1123
-		$l = \OC::$server->getL10N('lib');
1124
-		$connection = \OC::$server->getDatabaseConnection();
1125
-
1126
-		$intArrayToLiteralArray = function($intArray, $eb) {
1127
-			return array_map(function($int) use ($eb) {
1128
-				return $eb->literal((int)$int, 'integer');
1129
-			}, $intArray);
1130
-		};
1131
-		$sanitizeItem = function($item) {
1132
-			$item['id'] = (int)$item['id'];
1133
-			$item['premissions'] = (int)$item['permissions'];
1134
-			return $item;
1135
-		};
1136
-
1137
-		if ($rootItem = self::getItems($itemType, $itemSource, $shareType, $shareWith,
1138
-			\OC_User::getUser(), self::FORMAT_NONE, null, 1, false)) {
1139
-			// Check if this item is a reshare and verify that the permissions
1140
-			// granted don't exceed the parent shared item
1141
-			if (isset($rootItem['parent'])) {
1142
-				$qb = $connection->getQueryBuilder();
1143
-				$qb->select('permissions')
1144
-					->from('share')
1145
-					->where($qb->expr()->eq('id', $qb->createParameter('id')))
1146
-					->setParameter(':id', $rootItem['parent']);
1147
-				$dbresult = $qb->execute();
1148
-
1149
-				$result = $dbresult->fetch();
1150
-				$dbresult->closeCursor();
1151
-				if (~(int)$result['permissions'] & $permissions) {
1152
-					$message = 'Setting permissions for %s failed,'
1153
-						.' because the permissions exceed permissions granted to %s';
1154
-					$message_t = $l->t('Setting permissions for %s failed, because the permissions exceed permissions granted to %s', array($itemSource, \OC_User::getUser()));
1155
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSource, \OC_User::getUser()), \OCP\Util::DEBUG);
1156
-					throw new \Exception($message_t);
1157
-				}
1158
-			}
1159
-			$qb = $connection->getQueryBuilder();
1160
-			$qb->update('share')
1161
-				->set('permissions', $qb->createParameter('permissions'))
1162
-				->where($qb->expr()->eq('id', $qb->createParameter('id')))
1163
-				->setParameter(':id', $rootItem['id'])
1164
-				->setParameter(':permissions', $permissions);
1165
-			$qb->execute();
1166
-			if ($itemType === 'file' || $itemType === 'folder') {
1167
-				\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
1168
-					'itemType' => $itemType,
1169
-					'itemSource' => $itemSource,
1170
-					'shareType' => $shareType,
1171
-					'shareWith' => $shareWith,
1172
-					'uidOwner' => \OC_User::getUser(),
1173
-					'permissions' => $permissions,
1174
-					'path' => $rootItem['path'],
1175
-					'share' => $rootItem
1176
-				));
1177
-			}
1178
-
1179
-			// Share id's to update with the new permissions
1180
-			$ids = [];
1181
-			$items = [];
1182
-
1183
-			// Check if permissions were removed
1184
-			if ((int)$rootItem['permissions'] & ~$permissions) {
1185
-				// If share permission is removed all reshares must be deleted
1186
-				if (($rootItem['permissions'] & \OCP\Constants::PERMISSION_SHARE) && (~$permissions & \OCP\Constants::PERMISSION_SHARE)) {
1187
-					// delete all shares, keep parent and group children
1188
-					Helper::delete($rootItem['id'], true, null, null, true);
1189
-				}
1190
-
1191
-				// Remove permission from all children
1192
-				$parents = [$rootItem['id']];
1193
-				while (!empty($parents)) {
1194
-					$parents = $intArrayToLiteralArray($parents, $qb->expr());
1195
-					$qb = $connection->getQueryBuilder();
1196
-					$qb->select('id', 'permissions', 'item_type')
1197
-						->from('share')
1198
-						->where($qb->expr()->in('parent', $parents));
1199
-					$result = $qb->execute();
1200
-					// Reset parents array, only go through loop again if
1201
-					// items are found that need permissions removed
1202
-					$parents = [];
1203
-					while ($item = $result->fetch()) {
1204
-						$item = $sanitizeItem($item);
1205
-
1206
-						$items[] = $item;
1207
-						// Check if permissions need to be removed
1208
-						if ($item['permissions'] & ~$permissions) {
1209
-							// Add to list of items that need permissions removed
1210
-							$ids[] = $item['id'];
1211
-							$parents[] = $item['id'];
1212
-						}
1213
-					}
1214
-					$result->closeCursor();
1215
-				}
1216
-
1217
-				// Remove the permissions for all reshares of this item
1218
-				if (!empty($ids)) {
1219
-					$ids = "'".implode("','", $ids)."'";
1220
-					// TODO this should be done with Doctrine platform objects
1221
-					if (\OC::$server->getConfig()->getSystemValue("dbtype") === 'oci') {
1222
-						$andOp = 'BITAND(`permissions`, ?)';
1223
-					} else {
1224
-						$andOp = '`permissions` & ?';
1225
-					}
1226
-					$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = '.$andOp
1227
-						.' WHERE `id` IN ('.$ids.')');
1228
-					$query->execute(array($permissions));
1229
-				}
1230
-
1231
-			}
1232
-
1233
-			/*
1105
+        $result = $query->execute(array($status, $itemType, $itemSource, $shareType, $recipient));
1106
+
1107
+        if($result === false) {
1108
+            \OCP\Util::writeLog('OCP\Share', 'Couldn\'t set send mail status', \OCP\Util::ERROR);
1109
+        }
1110
+    }
1111
+
1112
+    /**
1113
+     * Set the permissions of an item for a specific user or group
1114
+     * @param string $itemType
1115
+     * @param string $itemSource
1116
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
1117
+     * @param string $shareWith User or group the item is being shared with
1118
+     * @param int $permissions CRUDS permissions
1119
+     * @return boolean true on success or false on failure
1120
+     * @throws \Exception when trying to grant more permissions then the user has himself
1121
+     */
1122
+    public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) {
1123
+        $l = \OC::$server->getL10N('lib');
1124
+        $connection = \OC::$server->getDatabaseConnection();
1125
+
1126
+        $intArrayToLiteralArray = function($intArray, $eb) {
1127
+            return array_map(function($int) use ($eb) {
1128
+                return $eb->literal((int)$int, 'integer');
1129
+            }, $intArray);
1130
+        };
1131
+        $sanitizeItem = function($item) {
1132
+            $item['id'] = (int)$item['id'];
1133
+            $item['premissions'] = (int)$item['permissions'];
1134
+            return $item;
1135
+        };
1136
+
1137
+        if ($rootItem = self::getItems($itemType, $itemSource, $shareType, $shareWith,
1138
+            \OC_User::getUser(), self::FORMAT_NONE, null, 1, false)) {
1139
+            // Check if this item is a reshare and verify that the permissions
1140
+            // granted don't exceed the parent shared item
1141
+            if (isset($rootItem['parent'])) {
1142
+                $qb = $connection->getQueryBuilder();
1143
+                $qb->select('permissions')
1144
+                    ->from('share')
1145
+                    ->where($qb->expr()->eq('id', $qb->createParameter('id')))
1146
+                    ->setParameter(':id', $rootItem['parent']);
1147
+                $dbresult = $qb->execute();
1148
+
1149
+                $result = $dbresult->fetch();
1150
+                $dbresult->closeCursor();
1151
+                if (~(int)$result['permissions'] & $permissions) {
1152
+                    $message = 'Setting permissions for %s failed,'
1153
+                        .' because the permissions exceed permissions granted to %s';
1154
+                    $message_t = $l->t('Setting permissions for %s failed, because the permissions exceed permissions granted to %s', array($itemSource, \OC_User::getUser()));
1155
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSource, \OC_User::getUser()), \OCP\Util::DEBUG);
1156
+                    throw new \Exception($message_t);
1157
+                }
1158
+            }
1159
+            $qb = $connection->getQueryBuilder();
1160
+            $qb->update('share')
1161
+                ->set('permissions', $qb->createParameter('permissions'))
1162
+                ->where($qb->expr()->eq('id', $qb->createParameter('id')))
1163
+                ->setParameter(':id', $rootItem['id'])
1164
+                ->setParameter(':permissions', $permissions);
1165
+            $qb->execute();
1166
+            if ($itemType === 'file' || $itemType === 'folder') {
1167
+                \OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
1168
+                    'itemType' => $itemType,
1169
+                    'itemSource' => $itemSource,
1170
+                    'shareType' => $shareType,
1171
+                    'shareWith' => $shareWith,
1172
+                    'uidOwner' => \OC_User::getUser(),
1173
+                    'permissions' => $permissions,
1174
+                    'path' => $rootItem['path'],
1175
+                    'share' => $rootItem
1176
+                ));
1177
+            }
1178
+
1179
+            // Share id's to update with the new permissions
1180
+            $ids = [];
1181
+            $items = [];
1182
+
1183
+            // Check if permissions were removed
1184
+            if ((int)$rootItem['permissions'] & ~$permissions) {
1185
+                // If share permission is removed all reshares must be deleted
1186
+                if (($rootItem['permissions'] & \OCP\Constants::PERMISSION_SHARE) && (~$permissions & \OCP\Constants::PERMISSION_SHARE)) {
1187
+                    // delete all shares, keep parent and group children
1188
+                    Helper::delete($rootItem['id'], true, null, null, true);
1189
+                }
1190
+
1191
+                // Remove permission from all children
1192
+                $parents = [$rootItem['id']];
1193
+                while (!empty($parents)) {
1194
+                    $parents = $intArrayToLiteralArray($parents, $qb->expr());
1195
+                    $qb = $connection->getQueryBuilder();
1196
+                    $qb->select('id', 'permissions', 'item_type')
1197
+                        ->from('share')
1198
+                        ->where($qb->expr()->in('parent', $parents));
1199
+                    $result = $qb->execute();
1200
+                    // Reset parents array, only go through loop again if
1201
+                    // items are found that need permissions removed
1202
+                    $parents = [];
1203
+                    while ($item = $result->fetch()) {
1204
+                        $item = $sanitizeItem($item);
1205
+
1206
+                        $items[] = $item;
1207
+                        // Check if permissions need to be removed
1208
+                        if ($item['permissions'] & ~$permissions) {
1209
+                            // Add to list of items that need permissions removed
1210
+                            $ids[] = $item['id'];
1211
+                            $parents[] = $item['id'];
1212
+                        }
1213
+                    }
1214
+                    $result->closeCursor();
1215
+                }
1216
+
1217
+                // Remove the permissions for all reshares of this item
1218
+                if (!empty($ids)) {
1219
+                    $ids = "'".implode("','", $ids)."'";
1220
+                    // TODO this should be done with Doctrine platform objects
1221
+                    if (\OC::$server->getConfig()->getSystemValue("dbtype") === 'oci') {
1222
+                        $andOp = 'BITAND(`permissions`, ?)';
1223
+                    } else {
1224
+                        $andOp = '`permissions` & ?';
1225
+                    }
1226
+                    $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `permissions` = '.$andOp
1227
+                        .' WHERE `id` IN ('.$ids.')');
1228
+                    $query->execute(array($permissions));
1229
+                }
1230
+
1231
+            }
1232
+
1233
+            /*
1234 1234
 			 * Permissions were added
1235 1235
 			 * Update all USERGROUP shares. (So group shares where the user moved their mountpoint).
1236 1236
 			 */
1237
-			if ($permissions & ~(int)$rootItem['permissions']) {
1238
-				$qb = $connection->getQueryBuilder();
1239
-				$qb->select('id', 'permissions', 'item_type')
1240
-					->from('share')
1241
-					->where($qb->expr()->eq('parent', $qb->createParameter('parent')))
1242
-					->andWhere($qb->expr()->eq('share_type', $qb->createParameter('share_type')))
1243
-					->andWhere($qb->expr()->neq('permissions', $qb->createParameter('shareDeleted')))
1244
-					->setParameter(':parent', (int)$rootItem['id'])
1245
-					->setParameter(':share_type', 2)
1246
-					->setParameter(':shareDeleted', 0);
1247
-				$result = $qb->execute();
1248
-
1249
-				$ids = [];
1250
-				while ($item = $result->fetch()) {
1251
-					$item = $sanitizeItem($item);
1252
-					$items[] = $item;
1253
-					$ids[] = $item['id'];
1254
-				}
1255
-				$result->closeCursor();
1256
-
1257
-				// Add permssions for all USERGROUP shares of this item
1258
-				if (!empty($ids)) {
1259
-					$ids = $intArrayToLiteralArray($ids, $qb->expr());
1260
-
1261
-					$qb = $connection->getQueryBuilder();
1262
-					$qb->update('share')
1263
-						->set('permissions', $qb->createParameter('permissions'))
1264
-						->where($qb->expr()->in('id', $ids))
1265
-						->setParameter(':permissions', $permissions);
1266
-					$qb->execute();
1267
-				}
1268
-			}
1269
-
1270
-			foreach ($items as $item) {
1271
-				\OC_Hook::emit('OCP\Share', 'post_update_permissions', ['share' => $item]);
1272
-			}
1273
-
1274
-			return true;
1275
-		}
1276
-		$message = 'Setting permissions for %s failed, because the item was not found';
1277
-		$message_t = $l->t('Setting permissions for %s failed, because the item was not found', array($itemSource));
1278
-
1279
-		\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSource), \OCP\Util::DEBUG);
1280
-		throw new \Exception($message_t);
1281
-	}
1282
-
1283
-	/**
1284
-	 * validate expiration date if it meets all constraints
1285
-	 *
1286
-	 * @param string $expireDate well formatted date string, e.g. "DD-MM-YYYY"
1287
-	 * @param string $shareTime timestamp when the file was shared
1288
-	 * @param string $itemType
1289
-	 * @param string $itemSource
1290
-	 * @return \DateTime validated date
1291
-	 * @throws \Exception when the expire date is in the past or further in the future then the enforced date
1292
-	 */
1293
-	private static function validateExpireDate($expireDate, $shareTime, $itemType, $itemSource) {
1294
-		$l = \OC::$server->getL10N('lib');
1295
-		$date = new \DateTime($expireDate);
1296
-		$today = new \DateTime('now');
1297
-
1298
-		// if the user doesn't provide a share time we need to get it from the database
1299
-		// fall-back mode to keep API stable, because the $shareTime parameter was added later
1300
-		$defaultExpireDateEnforced = \OCP\Util::isDefaultExpireDateEnforced();
1301
-		if ($defaultExpireDateEnforced && $shareTime === null) {
1302
-			$items = self::getItemShared($itemType, $itemSource);
1303
-			$firstItem = reset($items);
1304
-			$shareTime = (int)$firstItem['stime'];
1305
-		}
1306
-
1307
-		if ($defaultExpireDateEnforced) {
1308
-			// initialize max date with share time
1309
-			$maxDate = new \DateTime();
1310
-			$maxDate->setTimestamp($shareTime);
1311
-			$maxDays = \OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
1312
-			$maxDate->add(new \DateInterval('P' . $maxDays . 'D'));
1313
-			if ($date > $maxDate) {
1314
-				$warning = 'Cannot set expiration date. Shares cannot expire later than ' . $maxDays . ' after they have been shared';
1315
-				$warning_t = $l->t('Cannot set expiration date. Shares cannot expire later than %s after they have been shared', array($maxDays));
1316
-				\OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN);
1317
-				throw new \Exception($warning_t);
1318
-			}
1319
-		}
1320
-
1321
-		if ($date < $today) {
1322
-			$message = 'Cannot set expiration date. Expiration date is in the past';
1323
-			$message_t = $l->t('Cannot set expiration date. Expiration date is in the past');
1324
-			\OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::WARN);
1325
-			throw new \Exception($message_t);
1326
-		}
1327
-
1328
-		return $date;
1329
-	}
1330
-
1331
-	/**
1332
-	 * Set expiration date for a share
1333
-	 * @param string $itemType
1334
-	 * @param string $itemSource
1335
-	 * @param string $date expiration date
1336
-	 * @param int $shareTime timestamp from when the file was shared
1337
-	 * @return boolean
1338
-	 * @throws \Exception when the expire date is not set, in the past or further in the future then the enforced date
1339
-	 */
1340
-	public static function setExpirationDate($itemType, $itemSource, $date, $shareTime = null) {
1341
-		$user = \OC_User::getUser();
1342
-		$l = \OC::$server->getL10N('lib');
1343
-
1344
-		if ($date == '') {
1345
-			if (\OCP\Util::isDefaultExpireDateEnforced()) {
1346
-				$warning = 'Cannot clear expiration date. Shares are required to have an expiration date.';
1347
-				$warning_t = $l->t('Cannot clear expiration date. Shares are required to have an expiration date.');
1348
-				\OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN);
1349
-				throw new \Exception($warning_t);
1350
-			} else {
1351
-				$date = null;
1352
-			}
1353
-		} else {
1354
-			$date = self::validateExpireDate($date, $shareTime, $itemType, $itemSource);
1355
-		}
1356
-		$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `item_type` = ? AND `item_source` = ?  AND `uid_owner` = ? AND `share_type` = ?');
1357
-		$query->bindValue(1, $date, 'datetime');
1358
-		$query->bindValue(2, $itemType);
1359
-		$query->bindValue(3, $itemSource);
1360
-		$query->bindValue(4, $user);
1361
-		$query->bindValue(5, \OCP\Share::SHARE_TYPE_LINK);
1362
-
1363
-		$query->execute();
1364
-
1365
-		\OC_Hook::emit('OCP\Share', 'post_set_expiration_date', array(
1366
-			'itemType' => $itemType,
1367
-			'itemSource' => $itemSource,
1368
-			'date' => $date,
1369
-			'uidOwner' => $user
1370
-		));
1371
-
1372
-		return true;
1373
-	}
1374
-
1375
-	/**
1376
-	 * Retrieve the owner of a connection
1377
-	 *
1378
-	 * @param IDBConnection $connection
1379
-	 * @param int $shareId
1380
-	 * @throws \Exception
1381
-	 * @return string uid of share owner
1382
-	 */
1383
-	private static function getShareOwner(IDBConnection $connection, $shareId) {
1384
-		$qb = $connection->getQueryBuilder();
1385
-
1386
-		$qb->select('uid_owner')
1387
-			->from('share')
1388
-			->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
1389
-			->setParameter(':shareId', $shareId);
1390
-		$result = $qb->execute();
1391
-		$result = $result->fetch();
1392
-
1393
-		if (empty($result)) {
1394
-			throw new \Exception('Share not found');
1395
-		}
1396
-
1397
-		return $result['uid_owner'];
1398
-	}
1399
-
1400
-	/**
1401
-	 * Set password for a public link share
1402
-	 *
1403
-	 * @param IUserSession $userSession
1404
-	 * @param IDBConnection $connection
1405
-	 * @param IConfig $config
1406
-	 * @param int $shareId
1407
-	 * @param string $password
1408
-	 * @throws \Exception
1409
-	 * @return boolean
1410
-	 */
1411
-	public static function setPassword(IUserSession $userSession,
1412
-	                                   IDBConnection $connection,
1413
-	                                   IConfig $config,
1414
-	                                   $shareId, $password) {
1415
-		$user = $userSession->getUser();
1416
-		if (is_null($user)) {
1417
-			throw new \Exception("User not logged in");
1418
-		}
1419
-
1420
-		$uid = self::getShareOwner($connection, $shareId);
1421
-
1422
-		if ($uid !== $user->getUID()) {
1423
-			throw new \Exception('Cannot update share of a different user');
1424
-		}
1425
-
1426
-		if ($password === '') {
1427
-			$password = null;
1428
-		}
1429
-
1430
-		//If passwords are enforced the password can't be null
1431
-		if (self::enforcePassword($config) && is_null($password)) {
1432
-			throw new \Exception('Cannot remove password');
1433
-		}
1434
-
1435
-		self::verifyPassword($password);
1436
-
1437
-		$qb = $connection->getQueryBuilder();
1438
-		$qb->update('share')
1439
-			->set('share_with', $qb->createParameter('pass'))
1440
-			->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
1441
-			->setParameter(':pass', is_null($password) ? null : \OC::$server->getHasher()->hash($password))
1442
-			->setParameter(':shareId', $shareId);
1443
-
1444
-		$qb->execute();
1445
-
1446
-		return true;
1447
-	}
1448
-
1449
-	/**
1450
-	 * Checks whether a share has expired, calls unshareItem() if yes.
1451
-	 * @param array $item Share data (usually database row)
1452
-	 * @return boolean True if item was expired, false otherwise.
1453
-	 */
1454
-	protected static function expireItem(array $item) {
1455
-
1456
-		$result = false;
1457
-
1458
-		// only use default expiration date for link shares
1459
-		if ((int) $item['share_type'] === self::SHARE_TYPE_LINK) {
1460
-
1461
-			// calculate expiration date
1462
-			if (!empty($item['expiration'])) {
1463
-				$userDefinedExpire = new \DateTime($item['expiration']);
1464
-				$expires = $userDefinedExpire->getTimestamp();
1465
-			} else {
1466
-				$expires = null;
1467
-			}
1468
-
1469
-
1470
-			// get default expiration settings
1471
-			$defaultSettings = Helper::getDefaultExpireSetting();
1472
-			$expires = Helper::calculateExpireDate($defaultSettings, $item['stime'], $expires);
1473
-
1474
-
1475
-			if (is_int($expires)) {
1476
-				$now = time();
1477
-				if ($now > $expires) {
1478
-					self::unshareItem($item);
1479
-					$result = true;
1480
-				}
1481
-			}
1482
-		}
1483
-		return $result;
1484
-	}
1485
-
1486
-	/**
1487
-	 * Unshares a share given a share data array
1488
-	 * @param array $item Share data (usually database row)
1489
-	 * @param int $newParent parent ID
1490
-	 * @return null
1491
-	 */
1492
-	protected static function unshareItem(array $item, $newParent = null) {
1493
-
1494
-		$shareType = (int)$item['share_type'];
1495
-		$shareWith = null;
1496
-		if ($shareType !== \OCP\Share::SHARE_TYPE_LINK) {
1497
-			$shareWith = $item['share_with'];
1498
-		}
1499
-
1500
-		// Pass all the vars we have for now, they may be useful
1501
-		$hookParams = array(
1502
-			'id'            => $item['id'],
1503
-			'itemType'      => $item['item_type'],
1504
-			'itemSource'    => $item['item_source'],
1505
-			'shareType'     => $shareType,
1506
-			'shareWith'     => $shareWith,
1507
-			'itemParent'    => $item['parent'],
1508
-			'uidOwner'      => $item['uid_owner'],
1509
-		);
1510
-		if($item['item_type'] === 'file' || $item['item_type'] === 'folder') {
1511
-			$hookParams['fileSource'] = $item['file_source'];
1512
-			$hookParams['fileTarget'] = $item['file_target'];
1513
-		}
1514
-
1515
-		\OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams);
1516
-		$deletedShares = Helper::delete($item['id'], false, null, $newParent);
1517
-		$deletedShares[] = $hookParams;
1518
-		$hookParams['deletedShares'] = $deletedShares;
1519
-		\OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
1520
-		if ((int)$item['share_type'] === \OCP\Share::SHARE_TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
1521
-			list(, $remote) = Helper::splitUserRemote($item['share_with']);
1522
-			self::sendRemoteUnshare($remote, $item['id'], $item['token']);
1523
-		}
1524
-	}
1525
-
1526
-	/**
1527
-	 * Get the backend class for the specified item type
1528
-	 * @param string $itemType
1529
-	 * @throws \Exception
1530
-	 * @return \OCP\Share_Backend
1531
-	 */
1532
-	public static function getBackend($itemType) {
1533
-		$l = \OC::$server->getL10N('lib');
1534
-		if (isset(self::$backends[$itemType])) {
1535
-			return self::$backends[$itemType];
1536
-		} else if (isset(self::$backendTypes[$itemType]['class'])) {
1537
-			$class = self::$backendTypes[$itemType]['class'];
1538
-			if (class_exists($class)) {
1539
-				self::$backends[$itemType] = new $class;
1540
-				if (!(self::$backends[$itemType] instanceof \OCP\Share_Backend)) {
1541
-					$message = 'Sharing backend %s must implement the interface OCP\Share_Backend';
1542
-					$message_t = $l->t('Sharing backend %s must implement the interface OCP\Share_Backend', array($class));
1543
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $class), \OCP\Util::ERROR);
1544
-					throw new \Exception($message_t);
1545
-				}
1546
-				return self::$backends[$itemType];
1547
-			} else {
1548
-				$message = 'Sharing backend %s not found';
1549
-				$message_t = $l->t('Sharing backend %s not found', array($class));
1550
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $class), \OCP\Util::ERROR);
1551
-				throw new \Exception($message_t);
1552
-			}
1553
-		}
1554
-		$message = 'Sharing backend for %s not found';
1555
-		$message_t = $l->t('Sharing backend for %s not found', array($itemType));
1556
-		\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemType), \OCP\Util::ERROR);
1557
-		throw new \Exception($message_t);
1558
-	}
1559
-
1560
-	/**
1561
-	 * Check if resharing is allowed
1562
-	 * @return boolean true if allowed or false
1563
-	 *
1564
-	 * Resharing is allowed by default if not configured
1565
-	 */
1566
-	public static function isResharingAllowed() {
1567
-		if (!isset(self::$isResharingAllowed)) {
1568
-			if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_resharing', 'yes') == 'yes') {
1569
-				self::$isResharingAllowed = true;
1570
-			} else {
1571
-				self::$isResharingAllowed = false;
1572
-			}
1573
-		}
1574
-		return self::$isResharingAllowed;
1575
-	}
1576
-
1577
-	/**
1578
-	 * Get a list of collection item types for the specified item type
1579
-	 * @param string $itemType
1580
-	 * @return array
1581
-	 */
1582
-	private static function getCollectionItemTypes($itemType) {
1583
-		$collectionTypes = array($itemType);
1584
-		foreach (self::$backendTypes as $type => $backend) {
1585
-			if (in_array($backend['collectionOf'], $collectionTypes)) {
1586
-				$collectionTypes[] = $type;
1587
-			}
1588
-		}
1589
-		// TODO Add option for collections to be collection of themselves, only 'folder' does it now...
1590
-		if (isset(self::$backendTypes[$itemType]) && (!self::getBackend($itemType) instanceof \OCP\Share_Backend_Collection || $itemType != 'folder')) {
1591
-			unset($collectionTypes[0]);
1592
-		}
1593
-		// Return array if collections were found or the item type is a
1594
-		// collection itself - collections can be inside collections
1595
-		if (count($collectionTypes) > 0) {
1596
-			return $collectionTypes;
1597
-		}
1598
-		return false;
1599
-	}
1600
-
1601
-	/**
1602
-	 * Get the owners of items shared with a user.
1603
-	 *
1604
-	 * @param string $user The user the items are shared with.
1605
-	 * @param string $type The type of the items shared with the user.
1606
-	 * @param boolean $includeCollections Include collection item types (optional)
1607
-	 * @param boolean $includeOwner include owner in the list of users the item is shared with (optional)
1608
-	 * @return array
1609
-	 */
1610
-	public static function getSharedItemsOwners($user, $type, $includeCollections = false, $includeOwner = false) {
1611
-		// First, we find out if $type is part of a collection (and if that collection is part of
1612
-		// another one and so on).
1613
-		$collectionTypes = array();
1614
-		if (!$includeCollections || !$collectionTypes = self::getCollectionItemTypes($type)) {
1615
-			$collectionTypes[] = $type;
1616
-		}
1617
-
1618
-		// Of these collection types, along with our original $type, we make a
1619
-		// list of the ones for which a sharing backend has been registered.
1620
-		// FIXME: Ideally, we wouldn't need to nest getItemsSharedWith in this loop but just call it
1621
-		// with its $includeCollections parameter set to true. Unfortunately, this fails currently.
1622
-		$allMaybeSharedItems = array();
1623
-		foreach ($collectionTypes as $collectionType) {
1624
-			if (isset(self::$backends[$collectionType])) {
1625
-				$allMaybeSharedItems[$collectionType] = self::getItemsSharedWithUser(
1626
-					$collectionType,
1627
-					$user,
1628
-					self::FORMAT_NONE
1629
-				);
1630
-			}
1631
-		}
1632
-
1633
-		$owners = array();
1634
-		if ($includeOwner) {
1635
-			$owners[] = $user;
1636
-		}
1637
-
1638
-		// We take a look at all shared items of the given $type (or of the collections it is part of)
1639
-		// and find out their owners. Then, we gather the tags for the original $type from all owners,
1640
-		// and return them as elements of a list that look like "Tag (owner)".
1641
-		foreach ($allMaybeSharedItems as $collectionType => $maybeSharedItems) {
1642
-			foreach ($maybeSharedItems as $sharedItem) {
1643
-				if (isset($sharedItem['id'])) { //workaround for https://github.com/owncloud/core/issues/2814
1644
-					$owners[] = $sharedItem['uid_owner'];
1645
-				}
1646
-			}
1647
-		}
1648
-
1649
-		return $owners;
1650
-	}
1651
-
1652
-	/**
1653
-	 * Get shared items from the database
1654
-	 * @param string $itemType
1655
-	 * @param string $item Item source or target (optional)
1656
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
1657
-	 * @param string $shareWith User or group the item is being shared with
1658
-	 * @param string $uidOwner User that is the owner of shared items (optional)
1659
-	 * @param int $format Format to convert items to with formatItems() (optional)
1660
-	 * @param mixed $parameters to pass to formatItems() (optional)
1661
-	 * @param int $limit Number of items to return, -1 to return all matches (optional)
1662
-	 * @param boolean $includeCollections Include collection item types (optional)
1663
-	 * @param boolean $itemShareWithBySource (optional)
1664
-	 * @param boolean $checkExpireDate
1665
-	 * @return array
1666
-	 *
1667
-	 * See public functions getItem(s)... for parameter usage
1668
-	 *
1669
-	 */
1670
-	public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null,
1671
-									$uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1,
1672
-									$includeCollections = false, $itemShareWithBySource = false, $checkExpireDate  = true) {
1673
-		if (!self::isEnabled()) {
1674
-			return array();
1675
-		}
1676
-		$backend = self::getBackend($itemType);
1677
-		$collectionTypes = false;
1678
-		// Get filesystem root to add it to the file target and remove from the
1679
-		// file source, match file_source with the file cache
1680
-		if ($itemType == 'file' || $itemType == 'folder') {
1681
-			if(!is_null($uidOwner)) {
1682
-				$root = \OC\Files\Filesystem::getRoot();
1683
-			} else {
1684
-				$root = '';
1685
-			}
1686
-			$where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
1687
-			if (!isset($item)) {
1688
-				$where .= ' AND `file_target` IS NOT NULL ';
1689
-			}
1690
-			$where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
1691
-			$fileDependent = true;
1692
-			$queryArgs = array();
1693
-		} else {
1694
-			$fileDependent = false;
1695
-			$root = '';
1696
-			$collectionTypes = self::getCollectionItemTypes($itemType);
1697
-			if ($includeCollections && !isset($item) && $collectionTypes) {
1698
-				// If includeCollections is true, find collections of this item type, e.g. a music album contains songs
1699
-				if (!in_array($itemType, $collectionTypes)) {
1700
-					$itemTypes = array_merge(array($itemType), $collectionTypes);
1701
-				} else {
1702
-					$itemTypes = $collectionTypes;
1703
-				}
1704
-				$placeholders = join(',', array_fill(0, count($itemTypes), '?'));
1705
-				$where = ' WHERE `item_type` IN ('.$placeholders.'))';
1706
-				$queryArgs = $itemTypes;
1707
-			} else {
1708
-				$where = ' WHERE `item_type` = ?';
1709
-				$queryArgs = array($itemType);
1710
-			}
1711
-		}
1712
-		if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
1713
-			$where .= ' AND `share_type` != ?';
1714
-			$queryArgs[] = self::SHARE_TYPE_LINK;
1715
-		}
1716
-		if (isset($shareType)) {
1717
-			// Include all user and group items
1718
-			if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
1719
-				$where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) ';
1720
-				$queryArgs[] = self::SHARE_TYPE_USER;
1721
-				$queryArgs[] = self::$shareTypeGroupUserUnique;
1722
-				$queryArgs[] = $shareWith;
1723
-				$groups = \OC_Group::getUserGroups($shareWith);
1724
-				if (!empty($groups)) {
1725
-					$placeholders = join(',', array_fill(0, count($groups), '?'));
1726
-					$where .= ' OR (`share_type` = ? AND `share_with` IN ('.$placeholders.')) ';
1727
-					$queryArgs[] = self::SHARE_TYPE_GROUP;
1728
-					$queryArgs = array_merge($queryArgs, $groups);
1729
-				}
1730
-				$where .= ')';
1731
-				// Don't include own group shares
1732
-				$where .= ' AND `uid_owner` != ?';
1733
-				$queryArgs[] = $shareWith;
1734
-			} else {
1735
-				$where .= ' AND `share_type` = ?';
1736
-				$queryArgs[] = $shareType;
1737
-				if (isset($shareWith)) {
1738
-					$where .= ' AND `share_with` = ?';
1739
-					$queryArgs[] = $shareWith;
1740
-				}
1741
-			}
1742
-		}
1743
-		if (isset($uidOwner)) {
1744
-			$where .= ' AND `uid_owner` = ?';
1745
-			$queryArgs[] = $uidOwner;
1746
-			if (!isset($shareType)) {
1747
-				// Prevent unique user targets for group shares from being selected
1748
-				$where .= ' AND `share_type` != ?';
1749
-				$queryArgs[] = self::$shareTypeGroupUserUnique;
1750
-			}
1751
-			if ($fileDependent) {
1752
-				$column = 'file_source';
1753
-			} else {
1754
-				$column = 'item_source';
1755
-			}
1756
-		} else {
1757
-			if ($fileDependent) {
1758
-				$column = 'file_target';
1759
-			} else {
1760
-				$column = 'item_target';
1761
-			}
1762
-		}
1763
-		if (isset($item)) {
1764
-			$collectionTypes = self::getCollectionItemTypes($itemType);
1765
-			if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
1766
-				$where .= ' AND (';
1767
-			} else {
1768
-				$where .= ' AND';
1769
-			}
1770
-			// If looking for own shared items, check item_source else check item_target
1771
-			if (isset($uidOwner) || $itemShareWithBySource) {
1772
-				// If item type is a file, file source needs to be checked in case the item was converted
1773
-				if ($fileDependent) {
1774
-					$where .= ' `file_source` = ?';
1775
-					$column = 'file_source';
1776
-				} else {
1777
-					$where .= ' `item_source` = ?';
1778
-					$column = 'item_source';
1779
-				}
1780
-			} else {
1781
-				if ($fileDependent) {
1782
-					$where .= ' `file_target` = ?';
1783
-					$item = \OC\Files\Filesystem::normalizePath($item);
1784
-				} else {
1785
-					$where .= ' `item_target` = ?';
1786
-				}
1787
-			}
1788
-			$queryArgs[] = $item;
1789
-			if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
1790
-				$placeholders = join(',', array_fill(0, count($collectionTypes), '?'));
1791
-				$where .= ' OR `item_type` IN ('.$placeholders.'))';
1792
-				$queryArgs = array_merge($queryArgs, $collectionTypes);
1793
-			}
1794
-		}
1795
-
1796
-		if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) {
1797
-			// Make sure the unique user target is returned if it exists,
1798
-			// unique targets should follow the group share in the database
1799
-			// If the limit is not 1, the filtering can be done later
1800
-			$where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
1801
-		} else {
1802
-			$where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
1803
-		}
1804
-
1805
-		if ($limit != -1 && !$includeCollections) {
1806
-			// The limit must be at least 3, because filtering needs to be done
1807
-			if ($limit < 3) {
1808
-				$queryLimit = 3;
1809
-			} else {
1810
-				$queryLimit = $limit;
1811
-			}
1812
-		} else {
1813
-			$queryLimit = null;
1814
-		}
1815
-		$select = self::createSelectStatement($format, $fileDependent, $uidOwner);
1816
-		$root = strlen($root);
1817
-		$query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit);
1818
-		$result = $query->execute($queryArgs);
1819
-		if ($result === false) {
1820
-			\OCP\Util::writeLog('OCP\Share',
1821
-				\OC_DB::getErrorMessage() . ', select=' . $select . ' where=',
1822
-				\OCP\Util::ERROR);
1823
-		}
1824
-		$items = array();
1825
-		$targets = array();
1826
-		$switchedItems = array();
1827
-		$mounts = array();
1828
-		while ($row = $result->fetchRow()) {
1829
-			self::transformDBResults($row);
1830
-			// Filter out duplicate group shares for users with unique targets
1831
-			if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
1832
-				continue;
1833
-			}
1834
-			if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
1835
-				$row['share_type'] = self::SHARE_TYPE_GROUP;
1836
-				$row['unique_name'] = true; // remember that we use a unique name for this user
1837
-				$row['share_with'] = $items[$row['parent']]['share_with'];
1838
-				// if the group share was unshared from the user we keep the permission, otherwise
1839
-				// we take the permission from the parent because this is always the up-to-date
1840
-				// permission for the group share
1841
-				if ($row['permissions'] > 0) {
1842
-					$row['permissions'] = $items[$row['parent']]['permissions'];
1843
-				}
1844
-				// Remove the parent group share
1845
-				unset($items[$row['parent']]);
1846
-				if ($row['permissions'] == 0) {
1847
-					continue;
1848
-				}
1849
-			} else if (!isset($uidOwner)) {
1850
-				// Check if the same target already exists
1851
-				if (isset($targets[$row['id']])) {
1852
-					// Check if the same owner shared with the user twice
1853
-					// through a group and user share - this is allowed
1854
-					$id = $targets[$row['id']];
1855
-					if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
1856
-						// Switch to group share type to ensure resharing conditions aren't bypassed
1857
-						if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) {
1858
-							$items[$id]['share_type'] = self::SHARE_TYPE_GROUP;
1859
-							$items[$id]['share_with'] = $row['share_with'];
1860
-						}
1861
-						// Switch ids if sharing permission is granted on only
1862
-						// one share to ensure correct parent is used if resharing
1863
-						if (~(int)$items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE
1864
-							&& (int)$row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
1865
-							$items[$row['id']] = $items[$id];
1866
-							$switchedItems[$id] = $row['id'];
1867
-							unset($items[$id]);
1868
-							$id = $row['id'];
1869
-						}
1870
-						$items[$id]['permissions'] |= (int)$row['permissions'];
1871
-
1872
-					}
1873
-					continue;
1874
-				} elseif (!empty($row['parent'])) {
1875
-					$targets[$row['parent']] = $row['id'];
1876
-				}
1877
-			}
1878
-			// Remove root from file source paths if retrieving own shared items
1879
-			if (isset($uidOwner) && isset($row['path'])) {
1880
-				if (isset($row['parent'])) {
1881
-					$query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
1882
-					$parentResult = $query->execute(array($row['parent']));
1883
-					if ($result === false) {
1884
-						\OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: ' .
1885
-							\OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where,
1886
-							\OCP\Util::ERROR);
1887
-					} else {
1888
-						$parentRow = $parentResult->fetchRow();
1889
-						$tmpPath = $parentRow['file_target'];
1890
-						// find the right position where the row path continues from the target path
1891
-						$pos = strrpos($row['path'], $parentRow['file_target']);
1892
-						$subPath = substr($row['path'], $pos);
1893
-						$splitPath = explode('/', $subPath);
1894
-						foreach (array_slice($splitPath, 2) as $pathPart) {
1895
-							$tmpPath = $tmpPath . '/' . $pathPart;
1896
-						}
1897
-						$row['path'] = $tmpPath;
1898
-					}
1899
-				} else {
1900
-					if (!isset($mounts[$row['storage']])) {
1901
-						$mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']);
1902
-						if (is_array($mountPoints) && !empty($mountPoints)) {
1903
-							$mounts[$row['storage']] = current($mountPoints);
1904
-						}
1905
-					}
1906
-					if (!empty($mounts[$row['storage']])) {
1907
-						$path = $mounts[$row['storage']]->getMountPoint().$row['path'];
1908
-						$relPath = substr($path, $root); // path relative to data/user
1909
-						$row['path'] = rtrim($relPath, '/');
1910
-					}
1911
-				}
1912
-			}
1913
-
1914
-			if($checkExpireDate) {
1915
-				if (self::expireItem($row)) {
1916
-					continue;
1917
-				}
1918
-			}
1919
-			// Check if resharing is allowed, if not remove share permission
1920
-			if (isset($row['permissions']) && (!self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser())) {
1921
-				$row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE;
1922
-			}
1923
-			// Add display names to result
1924
-			$row['share_with_displayname'] = $row['share_with'];
1925
-			if ( isset($row['share_with']) && $row['share_with'] != '' &&
1926
-				$row['share_type'] === self::SHARE_TYPE_USER) {
1927
-				$row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']);
1928
-			} else if(isset($row['share_with']) && $row['share_with'] != '' &&
1929
-				$row['share_type'] === self::SHARE_TYPE_REMOTE) {
1930
-				$addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']);
1931
-				foreach ($addressBookEntries as $entry) {
1932
-					foreach ($entry['CLOUD'] as $cloudID) {
1933
-						if ($cloudID === $row['share_with']) {
1934
-							$row['share_with_displayname'] = $entry['FN'];
1935
-						}
1936
-					}
1937
-				}
1938
-			}
1939
-			if ( isset($row['uid_owner']) && $row['uid_owner'] != '') {
1940
-				$row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
1941
-			}
1942
-
1943
-			if ($row['permissions'] > 0) {
1944
-				$items[$row['id']] = $row;
1945
-			}
1946
-
1947
-		}
1948
-
1949
-		// group items if we are looking for items shared with the current user
1950
-		if (isset($shareWith) && $shareWith === \OCP\User::getUser()) {
1951
-			$items = self::groupItems($items, $itemType);
1952
-		}
1953
-
1954
-		if (!empty($items)) {
1955
-			$collectionItems = array();
1956
-			foreach ($items as &$row) {
1957
-				// Return only the item instead of a 2-dimensional array
1958
-				if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) {
1959
-					if ($format == self::FORMAT_NONE) {
1960
-						return $row;
1961
-					} else {
1962
-						break;
1963
-					}
1964
-				}
1965
-				// Check if this is a collection of the requested item type
1966
-				if ($includeCollections && $collectionTypes && $row['item_type'] !== 'folder' && in_array($row['item_type'], $collectionTypes)) {
1967
-					if (($collectionBackend = self::getBackend($row['item_type']))
1968
-						&& $collectionBackend instanceof \OCP\Share_Backend_Collection) {
1969
-						// Collections can be inside collections, check if the item is a collection
1970
-						if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) {
1971
-							$collectionItems[] = $row;
1972
-						} else {
1973
-							$collection = array();
1974
-							$collection['item_type'] = $row['item_type'];
1975
-							if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
1976
-								$collection['path'] = basename($row['path']);
1977
-							}
1978
-							$row['collection'] = $collection;
1979
-							// Fetch all of the children sources
1980
-							$children = $collectionBackend->getChildren($row[$column]);
1981
-							foreach ($children as $child) {
1982
-								$childItem = $row;
1983
-								$childItem['item_type'] = $itemType;
1984
-								if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') {
1985
-									$childItem['item_source'] = $child['source'];
1986
-									$childItem['item_target'] = $child['target'];
1987
-								}
1988
-								if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
1989
-									if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
1990
-										$childItem['file_source'] = $child['source'];
1991
-									} else { // TODO is this really needed if we already know that we use the file backend?
1992
-										$meta = \OC\Files\Filesystem::getFileInfo($child['file_path']);
1993
-										$childItem['file_source'] = $meta['fileid'];
1994
-									}
1995
-									$childItem['file_target'] =
1996
-										\OC\Files\Filesystem::normalizePath($child['file_path']);
1997
-								}
1998
-								if (isset($item)) {
1999
-									if ($childItem[$column] == $item) {
2000
-										// Return only the item instead of a 2-dimensional array
2001
-										if ($limit == 1) {
2002
-											if ($format == self::FORMAT_NONE) {
2003
-												return $childItem;
2004
-											} else {
2005
-												// Unset the items array and break out of both loops
2006
-												$items = array();
2007
-												$items[] = $childItem;
2008
-												break 2;
2009
-											}
2010
-										} else {
2011
-											$collectionItems[] = $childItem;
2012
-										}
2013
-									}
2014
-								} else {
2015
-									$collectionItems[] = $childItem;
2016
-								}
2017
-							}
2018
-						}
2019
-					}
2020
-					// Remove collection item
2021
-					$toRemove = $row['id'];
2022
-					if (array_key_exists($toRemove, $switchedItems)) {
2023
-						$toRemove = $switchedItems[$toRemove];
2024
-					}
2025
-					unset($items[$toRemove]);
2026
-				} elseif ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) {
2027
-					// FIXME: Thats a dirty hack to improve file sharing performance,
2028
-					// see github issue #10588 for more details
2029
-					// Need to find a solution which works for all back-ends
2030
-					$collectionBackend = self::getBackend($row['item_type']);
2031
-					$sharedParents = $collectionBackend->getParents($row['item_source']);
2032
-					foreach ($sharedParents as $parent) {
2033
-						$collectionItems[] = $parent;
2034
-					}
2035
-				}
2036
-			}
2037
-			if (!empty($collectionItems)) {
2038
-				$collectionItems = array_unique($collectionItems, SORT_REGULAR);
2039
-				$items = array_merge($items, $collectionItems);
2040
-			}
2041
-
2042
-			// filter out invalid items, these can appear when subshare entries exist
2043
-			// for a group in which the requested user isn't a member any more
2044
-			$items = array_filter($items, function($item) {
2045
-				return $item['share_type'] !== self::$shareTypeGroupUserUnique;
2046
-			});
2047
-
2048
-			return self::formatResult($items, $column, $backend, $format, $parameters);
2049
-		} elseif ($includeCollections && $collectionTypes && in_array('folder', $collectionTypes)) {
2050
-			// FIXME: Thats a dirty hack to improve file sharing performance,
2051
-			// see github issue #10588 for more details
2052
-			// Need to find a solution which works for all back-ends
2053
-			$collectionItems = array();
2054
-			$collectionBackend = self::getBackend('folder');
2055
-			$sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner);
2056
-			foreach ($sharedParents as $parent) {
2057
-				$collectionItems[] = $parent;
2058
-			}
2059
-			if ($limit === 1) {
2060
-				return reset($collectionItems);
2061
-			}
2062
-			return self::formatResult($collectionItems, $column, $backend, $format, $parameters);
2063
-		}
2064
-
2065
-		return array();
2066
-	}
2067
-
2068
-	/**
2069
-	 * group items with link to the same source
2070
-	 *
2071
-	 * @param array $items
2072
-	 * @param string $itemType
2073
-	 * @return array of grouped items
2074
-	 */
2075
-	protected static function groupItems($items, $itemType) {
2076
-
2077
-		$fileSharing = ($itemType === 'file' || $itemType === 'folder') ? true : false;
2078
-
2079
-		$result = array();
2080
-
2081
-		foreach ($items as $item) {
2082
-			$grouped = false;
2083
-			foreach ($result as $key => $r) {
2084
-				// for file/folder shares we need to compare file_source, otherwise we compare item_source
2085
-				// only group shares if they already point to the same target, otherwise the file where shared
2086
-				// before grouping of shares was added. In this case we don't group them toi avoid confusions
2087
-				if (( $fileSharing && $item['file_source'] === $r['file_source'] && $item['file_target'] === $r['file_target']) ||
2088
-					(!$fileSharing && $item['item_source'] === $r['item_source'] && $item['item_target'] === $r['item_target'])) {
2089
-					// add the first item to the list of grouped shares
2090
-					if (!isset($result[$key]['grouped'])) {
2091
-						$result[$key]['grouped'][] = $result[$key];
2092
-					}
2093
-					$result[$key]['permissions'] = (int) $item['permissions'] | (int) $r['permissions'];
2094
-					$result[$key]['grouped'][] = $item;
2095
-					$grouped = true;
2096
-					break;
2097
-				}
2098
-			}
2099
-
2100
-			if (!$grouped) {
2101
-				$result[] = $item;
2102
-			}
2103
-
2104
-		}
2105
-
2106
-		return $result;
2107
-	}
2108
-
2109
-	/**
2110
-	 * Put shared item into the database
2111
-	 * @param string $itemType Item type
2112
-	 * @param string $itemSource Item source
2113
-	 * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
2114
-	 * @param string $shareWith User or group the item is being shared with
2115
-	 * @param string $uidOwner User that is the owner of shared item
2116
-	 * @param int $permissions CRUDS permissions
2117
-	 * @param boolean|array $parentFolder Parent folder target (optional)
2118
-	 * @param string $token (optional)
2119
-	 * @param string $itemSourceName name of the source item (optional)
2120
-	 * @param \DateTime $expirationDate (optional)
2121
-	 * @throws \Exception
2122
-	 * @return mixed id of the new share or false
2123
-	 */
2124
-	private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
2125
-								$permissions, $parentFolder = null, $token = null, $itemSourceName = null, \DateTime $expirationDate = null) {
2126
-
2127
-		$queriesToExecute = array();
2128
-		$suggestedItemTarget = null;
2129
-		$groupFileTarget = $fileTarget = $suggestedFileTarget = $filePath = '';
2130
-		$groupItemTarget = $itemTarget = $fileSource = $parent = 0;
2131
-
2132
-		$result = self::checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate);
2133
-		if(!empty($result)) {
2134
-			$parent = $result['parent'];
2135
-			$itemSource = $result['itemSource'];
2136
-			$fileSource = $result['fileSource'];
2137
-			$suggestedItemTarget = $result['suggestedItemTarget'];
2138
-			$suggestedFileTarget = $result['suggestedFileTarget'];
2139
-			$filePath = $result['filePath'];
2140
-		}
2141
-
2142
-		$isGroupShare = false;
2143
-		if ($shareType == self::SHARE_TYPE_GROUP) {
2144
-			$isGroupShare = true;
2145
-			if (isset($shareWith['users'])) {
2146
-				$users = $shareWith['users'];
2147
-			} else {
2148
-				$users = \OC_Group::usersInGroup($shareWith['group']);
2149
-			}
2150
-			// remove current user from list
2151
-			if (in_array(\OCP\User::getUser(), $users)) {
2152
-				unset($users[array_search(\OCP\User::getUser(), $users)]);
2153
-			}
2154
-			$groupItemTarget = Helper::generateTarget($itemType, $itemSource,
2155
-				$shareType, $shareWith['group'], $uidOwner, $suggestedItemTarget);
2156
-			$groupFileTarget = Helper::generateTarget($itemType, $itemSource,
2157
-				$shareType, $shareWith['group'], $uidOwner, $filePath);
2158
-
2159
-			// add group share to table and remember the id as parent
2160
-			$queriesToExecute['groupShare'] = array(
2161
-				'itemType'			=> $itemType,
2162
-				'itemSource'		=> $itemSource,
2163
-				'itemTarget'		=> $groupItemTarget,
2164
-				'shareType'			=> $shareType,
2165
-				'shareWith'			=> $shareWith['group'],
2166
-				'uidOwner'			=> $uidOwner,
2167
-				'permissions'		=> $permissions,
2168
-				'shareTime'			=> time(),
2169
-				'fileSource'		=> $fileSource,
2170
-				'fileTarget'		=> $groupFileTarget,
2171
-				'token'				=> $token,
2172
-				'parent'			=> $parent,
2173
-				'expiration'		=> $expirationDate,
2174
-			);
2175
-
2176
-		} else {
2177
-			$users = array($shareWith);
2178
-			$itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
2179
-				$suggestedItemTarget);
2180
-		}
2181
-
2182
-		$run = true;
2183
-		$error = '';
2184
-		$preHookData = array(
2185
-			'itemType' => $itemType,
2186
-			'itemSource' => $itemSource,
2187
-			'shareType' => $shareType,
2188
-			'uidOwner' => $uidOwner,
2189
-			'permissions' => $permissions,
2190
-			'fileSource' => $fileSource,
2191
-			'expiration' => $expirationDate,
2192
-			'token' => $token,
2193
-			'run' => &$run,
2194
-			'error' => &$error
2195
-		);
2196
-
2197
-		$preHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget;
2198
-		$preHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith;
2199
-
2200
-		\OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData);
2201
-
2202
-		if ($run === false) {
2203
-			throw new \Exception($error);
2204
-		}
2205
-
2206
-		foreach ($users as $user) {
2207
-			$sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource;
2208
-			$sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user);
2209
-
2210
-			$userShareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType;
2211
-
2212
-			if ($sourceExists && $sourceExists['item_source'] === $itemSource) {
2213
-				$fileTarget = $sourceExists['file_target'];
2214
-				$itemTarget = $sourceExists['item_target'];
2215
-
2216
-				// for group shares we don't need a additional entry if the target is the same
2217
-				if($isGroupShare && $groupItemTarget === $itemTarget) {
2218
-					continue;
2219
-				}
2220
-
2221
-			} elseif(!$sourceExists && !$isGroupShare)  {
2222
-
2223
-				$itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user,
2224
-					$uidOwner, $suggestedItemTarget, $parent);
2225
-				if (isset($fileSource)) {
2226
-					if ($parentFolder) {
2227
-						if ($parentFolder === true) {
2228
-							$fileTarget = Helper::generateTarget('file', $filePath, $userShareType, $user,
2229
-								$uidOwner, $suggestedFileTarget, $parent);
2230
-							if ($fileTarget != $groupFileTarget) {
2231
-								$parentFolders[$user]['folder'] = $fileTarget;
2232
-							}
2233
-						} else if (isset($parentFolder[$user])) {
2234
-							$fileTarget = $parentFolder[$user]['folder'].$itemSource;
2235
-							$parent = $parentFolder[$user]['id'];
2236
-						}
2237
-					} else {
2238
-						$fileTarget = Helper::generateTarget('file', $filePath, $userShareType,
2239
-							$user, $uidOwner, $suggestedFileTarget, $parent);
2240
-					}
2241
-				} else {
2242
-					$fileTarget = null;
2243
-				}
2244
-
2245
-			} else {
2246
-
2247
-				// group share which doesn't exists until now, check if we need a unique target for this user
2248
-
2249
-				$itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $user,
2250
-					$uidOwner, $suggestedItemTarget, $parent);
2251
-
2252
-				// do we also need a file target
2253
-				if (isset($fileSource)) {
2254
-					$fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $user,
2255
-						$uidOwner, $suggestedFileTarget, $parent);
2256
-				} else {
2257
-					$fileTarget = null;
2258
-				}
2259
-
2260
-				if (($itemTarget === $groupItemTarget) &&
2261
-					(!isset($fileSource) || $fileTarget === $groupFileTarget)) {
2262
-					continue;
2263
-				}
2264
-			}
2265
-
2266
-			$queriesToExecute[] = array(
2267
-				'itemType'			=> $itemType,
2268
-				'itemSource'		=> $itemSource,
2269
-				'itemTarget'		=> $itemTarget,
2270
-				'shareType'			=> $userShareType,
2271
-				'shareWith'			=> $user,
2272
-				'uidOwner'			=> $uidOwner,
2273
-				'permissions'		=> $permissions,
2274
-				'shareTime'			=> time(),
2275
-				'fileSource'		=> $fileSource,
2276
-				'fileTarget'		=> $fileTarget,
2277
-				'token'				=> $token,
2278
-				'parent'			=> $parent,
2279
-				'expiration'		=> $expirationDate,
2280
-			);
2281
-
2282
-		}
2283
-
2284
-		$id = false;
2285
-		if ($isGroupShare) {
2286
-			$id = self::insertShare($queriesToExecute['groupShare']);
2287
-			// Save this id, any extra rows for this group share will need to reference it
2288
-			$parent = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
2289
-			unset($queriesToExecute['groupShare']);
2290
-		}
2291
-
2292
-		foreach ($queriesToExecute as $shareQuery) {
2293
-			$shareQuery['parent'] = $parent;
2294
-			$id = self::insertShare($shareQuery);
2295
-		}
2296
-
2297
-		$postHookData = array(
2298
-			'itemType' => $itemType,
2299
-			'itemSource' => $itemSource,
2300
-			'parent' => $parent,
2301
-			'shareType' => $shareType,
2302
-			'uidOwner' => $uidOwner,
2303
-			'permissions' => $permissions,
2304
-			'fileSource' => $fileSource,
2305
-			'id' => $parent,
2306
-			'token' => $token,
2307
-			'expirationDate' => $expirationDate,
2308
-		);
2309
-
2310
-		$postHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith;
2311
-		$postHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget;
2312
-		$postHookData['fileTarget'] = ($isGroupShare) ? $groupFileTarget : $fileTarget;
2313
-
2314
-		\OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
2315
-
2316
-
2317
-		return $id ? $id : false;
2318
-	}
2319
-
2320
-	/**
2321
-	 * @param string $itemType
2322
-	 * @param string $itemSource
2323
-	 * @param int $shareType
2324
-	 * @param string $shareWith
2325
-	 * @param string $uidOwner
2326
-	 * @param int $permissions
2327
-	 * @param string|null $itemSourceName
2328
-	 * @param null|\DateTime $expirationDate
2329
-	 */
2330
-	private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) {
2331
-		$backend = self::getBackend($itemType);
2332
-
2333
-		$l = \OC::$server->getL10N('lib');
2334
-		$result = array();
2335
-
2336
-		$column = ($itemType === 'file' || $itemType === 'folder') ? 'file_source' : 'item_source';
2337
-
2338
-		$checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true);
2339
-		if ($checkReshare) {
2340
-			// Check if attempting to share back to owner
2341
-			if ($checkReshare['uid_owner'] == $shareWith && $shareType == self::SHARE_TYPE_USER) {
2342
-				$message = 'Sharing %s failed, because the user %s is the original sharer';
2343
-				$message_t = $l->t('Sharing failed, because the user %s is the original sharer', [$shareWith]);
2344
-
2345
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
2346
-				throw new \Exception($message_t);
2347
-			}
2348
-		}
2349
-
2350
-		if ($checkReshare && $checkReshare['uid_owner'] !== \OC_User::getUser()) {
2351
-			// Check if share permissions is granted
2352
-			if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
2353
-				if (~(int)$checkReshare['permissions'] & $permissions) {
2354
-					$message = 'Sharing %s failed, because the permissions exceed permissions granted to %s';
2355
-					$message_t = $l->t('Sharing %s failed, because the permissions exceed permissions granted to %s', array($itemSourceName, $uidOwner));
2356
-
2357
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $uidOwner), \OCP\Util::DEBUG);
2358
-					throw new \Exception($message_t);
2359
-				} else {
2360
-					// TODO Don't check if inside folder
2361
-					$result['parent'] = $checkReshare['id'];
2362
-
2363
-					$result['expirationDate'] = $expirationDate;
2364
-					// $checkReshare['expiration'] could be null and then is always less than any value
2365
-					if(isset($checkReshare['expiration']) && $checkReshare['expiration'] < $expirationDate) {
2366
-						$result['expirationDate'] = $checkReshare['expiration'];
2367
-					}
2368
-
2369
-					// only suggest the same name as new target if it is a reshare of the
2370
-					// same file/folder and not the reshare of a child
2371
-					if ($checkReshare[$column] === $itemSource) {
2372
-						$result['filePath'] = $checkReshare['file_target'];
2373
-						$result['itemSource'] = $checkReshare['item_source'];
2374
-						$result['fileSource'] = $checkReshare['file_source'];
2375
-						$result['suggestedItemTarget'] = $checkReshare['item_target'];
2376
-						$result['suggestedFileTarget'] = $checkReshare['file_target'];
2377
-					} else {
2378
-						$result['filePath'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $backend->getFilePath($itemSource, $uidOwner) : null;
2379
-						$result['suggestedItemTarget'] = null;
2380
-						$result['suggestedFileTarget'] = null;
2381
-						$result['itemSource'] = $itemSource;
2382
-						$result['fileSource'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $itemSource : null;
2383
-					}
2384
-				}
2385
-			} else {
2386
-				$message = 'Sharing %s failed, because resharing is not allowed';
2387
-				$message_t = $l->t('Sharing %s failed, because resharing is not allowed', array($itemSourceName));
2388
-
2389
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG);
2390
-				throw new \Exception($message_t);
2391
-			}
2392
-		} else {
2393
-			$result['parent'] = null;
2394
-			$result['suggestedItemTarget'] = null;
2395
-			$result['suggestedFileTarget'] = null;
2396
-			$result['itemSource'] = $itemSource;
2397
-			$result['expirationDate'] = $expirationDate;
2398
-			if (!$backend->isValidSource($itemSource, $uidOwner)) {
2399
-				$message = 'Sharing %s failed, because the sharing backend for '
2400
-					.'%s could not find its source';
2401
-				$message_t = $l->t('Sharing %s failed, because the sharing backend for %s could not find its source', array($itemSource, $itemType));
2402
-				\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSource, $itemType), \OCP\Util::DEBUG);
2403
-				throw new \Exception($message_t);
2404
-			}
2405
-			if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
2406
-				$result['filePath'] = $backend->getFilePath($itemSource, $uidOwner);
2407
-				if ($itemType == 'file' || $itemType == 'folder') {
2408
-					$result['fileSource'] = $itemSource;
2409
-				} else {
2410
-					$meta = \OC\Files\Filesystem::getFileInfo($result['filePath']);
2411
-					$result['fileSource'] = $meta['fileid'];
2412
-				}
2413
-				if ($result['fileSource'] == -1) {
2414
-					$message = 'Sharing %s failed, because the file could not be found in the file cache';
2415
-					$message_t = $l->t('Sharing %s failed, because the file could not be found in the file cache', array($itemSource));
2416
-
2417
-					\OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSource), \OCP\Util::DEBUG);
2418
-					throw new \Exception($message_t);
2419
-				}
2420
-			} else {
2421
-				$result['filePath'] = null;
2422
-				$result['fileSource'] = null;
2423
-			}
2424
-		}
2425
-
2426
-		return $result;
2427
-	}
2428
-
2429
-	/**
2430
-	 *
2431
-	 * @param array $shareData
2432
-	 * @return mixed false in case of a failure or the id of the new share
2433
-	 */
2434
-	private static function insertShare(array $shareData) {
2435
-
2436
-		$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
2437
-			.' `item_type`, `item_source`, `item_target`, `share_type`,'
2438
-			.' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
2439
-			.' `file_target`, `token`, `parent`, `expiration`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)');
2440
-		$query->bindValue(1, $shareData['itemType']);
2441
-		$query->bindValue(2, $shareData['itemSource']);
2442
-		$query->bindValue(3, $shareData['itemTarget']);
2443
-		$query->bindValue(4, $shareData['shareType']);
2444
-		$query->bindValue(5, $shareData['shareWith']);
2445
-		$query->bindValue(6, $shareData['uidOwner']);
2446
-		$query->bindValue(7, $shareData['permissions']);
2447
-		$query->bindValue(8, $shareData['shareTime']);
2448
-		$query->bindValue(9, $shareData['fileSource']);
2449
-		$query->bindValue(10, $shareData['fileTarget']);
2450
-		$query->bindValue(11, $shareData['token']);
2451
-		$query->bindValue(12, $shareData['parent']);
2452
-		$query->bindValue(13, $shareData['expiration'], 'datetime');
2453
-		$result = $query->execute();
2454
-
2455
-		$id = false;
2456
-		if ($result) {
2457
-			$id =  \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
2458
-		}
2459
-
2460
-		return $id;
2461
-
2462
-	}
2463
-
2464
-	/**
2465
-	 * Delete all shares with type SHARE_TYPE_LINK
2466
-	 */
2467
-	public static function removeAllLinkShares() {
2468
-		// Delete any link shares
2469
-		$query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ?');
2470
-		$result = $query->execute(array(self::SHARE_TYPE_LINK));
2471
-		while ($item = $result->fetchRow()) {
2472
-			Helper::delete($item['id']);
2473
-		}
2474
-	}
2475
-
2476
-	/**
2477
-	 * In case a password protected link is not yet authenticated this function will return false
2478
-	 *
2479
-	 * @param array $linkItem
2480
-	 * @return boolean
2481
-	 */
2482
-	public static function checkPasswordProtectedShare(array $linkItem) {
2483
-		if (!isset($linkItem['share_with'])) {
2484
-			return true;
2485
-		}
2486
-		if (!isset($linkItem['share_type'])) {
2487
-			return true;
2488
-		}
2489
-		if (!isset($linkItem['id'])) {
2490
-			return true;
2491
-		}
2492
-
2493
-		if ($linkItem['share_type'] != \OCP\Share::SHARE_TYPE_LINK) {
2494
-			return true;
2495
-		}
2496
-
2497
-		if ( \OC::$server->getSession()->exists('public_link_authenticated')
2498
-			&& \OC::$server->getSession()->get('public_link_authenticated') === (string)$linkItem['id'] ) {
2499
-			return true;
2500
-		}
2501
-
2502
-		return false;
2503
-	}
2504
-
2505
-	/**
2506
-	 * construct select statement
2507
-	 * @param int $format
2508
-	 * @param boolean $fileDependent ist it a file/folder share or a generla share
2509
-	 * @param string $uidOwner
2510
-	 * @return string select statement
2511
-	 */
2512
-	private static function createSelectStatement($format, $fileDependent, $uidOwner = null) {
2513
-		$select = '*';
2514
-		if ($format == self::FORMAT_STATUSES) {
2515
-			if ($fileDependent) {
2516
-				$select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `storage`, '
2517
-					. '`share_with`, `uid_owner` , `file_source`, `stime`, `*PREFIX*share`.`permissions`, '
2518
-					. '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`, '
2519
-					. '`uid_initiator`';
2520
-			} else {
2521
-				$select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`';
2522
-			}
2523
-		} else {
2524
-			if (isset($uidOwner)) {
2525
-				if ($fileDependent) {
2526
-					$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,'
2527
-						. ' `share_type`, `share_with`, `file_source`, `file_target`, `path`, `*PREFIX*share`.`permissions`, `stime`,'
2528
-						. ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`, '
2529
-						. '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`';
2530
-				} else {
2531
-					$select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,'
2532
-						. ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`';
2533
-				}
2534
-			} else {
2535
-				if ($fileDependent) {
2536
-					if ($format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) {
2537
-						$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, '
2538
-							. '`share_type`, `share_with`, `file_source`, `path`, `file_target`, `stime`, '
2539
-							. '`*PREFIX*share`.`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, '
2540
-							. '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`';
2541
-					} else {
2542
-						$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,'
2543
-							. '`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,'
2544
-							. '`file_source`, `path`, `file_target`, `*PREFIX*share`.`permissions`,'
2545
-						    . '`stime`, `expiration`, `token`, `storage`, `mail_send`,'
2546
-							. '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`';
2547
-					}
2548
-				}
2549
-			}
2550
-		}
2551
-		return $select;
2552
-	}
2553
-
2554
-
2555
-	/**
2556
-	 * transform db results
2557
-	 * @param array $row result
2558
-	 */
2559
-	private static function transformDBResults(&$row) {
2560
-		if (isset($row['id'])) {
2561
-			$row['id'] = (int) $row['id'];
2562
-		}
2563
-		if (isset($row['share_type'])) {
2564
-			$row['share_type'] = (int) $row['share_type'];
2565
-		}
2566
-		if (isset($row['parent'])) {
2567
-			$row['parent'] = (int) $row['parent'];
2568
-		}
2569
-		if (isset($row['file_parent'])) {
2570
-			$row['file_parent'] = (int) $row['file_parent'];
2571
-		}
2572
-		if (isset($row['file_source'])) {
2573
-			$row['file_source'] = (int) $row['file_source'];
2574
-		}
2575
-		if (isset($row['permissions'])) {
2576
-			$row['permissions'] = (int) $row['permissions'];
2577
-		}
2578
-		if (isset($row['storage'])) {
2579
-			$row['storage'] = (int) $row['storage'];
2580
-		}
2581
-		if (isset($row['stime'])) {
2582
-			$row['stime'] = (int) $row['stime'];
2583
-		}
2584
-		if (isset($row['expiration']) && $row['share_type'] !== self::SHARE_TYPE_LINK) {
2585
-			// discard expiration date for non-link shares, which might have been
2586
-			// set by ancient bugs
2587
-			$row['expiration'] = null;
2588
-		}
2589
-	}
2590
-
2591
-	/**
2592
-	 * format result
2593
-	 * @param array $items result
2594
-	 * @param string $column is it a file share or a general share ('file_target' or 'item_target')
2595
-	 * @param \OCP\Share_Backend $backend sharing backend
2596
-	 * @param int $format
2597
-	 * @param array $parameters additional format parameters
2598
-	 * @return array format result
2599
-	 */
2600
-	private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE , $parameters = null) {
2601
-		if ($format === self::FORMAT_NONE) {
2602
-			return $items;
2603
-		} else if ($format === self::FORMAT_STATUSES) {
2604
-			$statuses = array();
2605
-			foreach ($items as $item) {
2606
-				if ($item['share_type'] === self::SHARE_TYPE_LINK) {
2607
-					if ($item['uid_initiator'] !== \OC::$server->getUserSession()->getUser()->getUID()) {
2608
-						continue;
2609
-					}
2610
-					$statuses[$item[$column]]['link'] = true;
2611
-				} else if (!isset($statuses[$item[$column]])) {
2612
-					$statuses[$item[$column]]['link'] = false;
2613
-				}
2614
-				if (!empty($item['file_target'])) {
2615
-					$statuses[$item[$column]]['path'] = $item['path'];
2616
-				}
2617
-			}
2618
-			return $statuses;
2619
-		} else {
2620
-			return $backend->formatItems($items, $format, $parameters);
2621
-		}
2622
-	}
2623
-
2624
-	/**
2625
-	 * remove protocol from URL
2626
-	 *
2627
-	 * @param string $url
2628
-	 * @return string
2629
-	 */
2630
-	public static function removeProtocolFromUrl($url) {
2631
-		if (strpos($url, 'https://') === 0) {
2632
-			return substr($url, strlen('https://'));
2633
-		} else if (strpos($url, 'http://') === 0) {
2634
-			return substr($url, strlen('http://'));
2635
-		}
2636
-
2637
-		return $url;
2638
-	}
2639
-
2640
-	/**
2641
-	 * try http post first with https and then with http as a fallback
2642
-	 *
2643
-	 * @param string $remoteDomain
2644
-	 * @param string $urlSuffix
2645
-	 * @param array $fields post parameters
2646
-	 * @return array
2647
-	 */
2648
-	private static function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) {
2649
-		$protocol = 'https://';
2650
-		$result = [
2651
-			'success' => false,
2652
-			'result' => '',
2653
-		];
2654
-		$try = 0;
2655
-		$discoveryManager = new DiscoveryManager(
2656
-			\OC::$server->getMemCacheFactory(),
2657
-			\OC::$server->getHTTPClientService()
2658
-		);
2659
-		while ($result['success'] === false && $try < 2) {
2660
-			$endpoint = $discoveryManager->getShareEndpoint($protocol . $remoteDomain);
2661
-			$result = \OC::$server->getHTTPHelper()->post($protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, $fields);
2662
-			$try++;
2663
-			$protocol = 'http://';
2664
-		}
2665
-
2666
-		return $result;
2667
-	}
2668
-
2669
-	/**
2670
-	 * send server-to-server share to remote server
2671
-	 *
2672
-	 * @param string $token
2673
-	 * @param string $shareWith
2674
-	 * @param string $name
2675
-	 * @param int $remote_id
2676
-	 * @param string $owner
2677
-	 * @return bool
2678
-	 */
2679
-	private static function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner) {
2680
-
2681
-		list($user, $remote) = Helper::splitUserRemote($shareWith);
2682
-
2683
-		if ($user && $remote) {
2684
-			$url = $remote;
2685
-
2686
-			$local = \OC::$server->getURLGenerator()->getAbsoluteURL('/');
2687
-
2688
-			$fields = array(
2689
-				'shareWith' => $user,
2690
-				'token' => $token,
2691
-				'name' => $name,
2692
-				'remoteId' => $remote_id,
2693
-				'owner' => $owner,
2694
-				'remote' => $local,
2695
-			);
2696
-
2697
-			$url = self::removeProtocolFromUrl($url);
2698
-			$result = self::tryHttpPostToShareEndpoint($url, '', $fields);
2699
-			$status = json_decode($result['result'], true);
2700
-
2701
-			if ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)) {
2702
-				\OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
2703
-				return true;
2704
-			}
2705
-
2706
-		}
2707
-
2708
-		return false;
2709
-	}
2710
-
2711
-	/**
2712
-	 * send server-to-server unshare to remote server
2713
-	 *
2714
-	 * @param string $remote url
2715
-	 * @param int $id share id
2716
-	 * @param string $token
2717
-	 * @return bool
2718
-	 */
2719
-	private static function sendRemoteUnshare($remote, $id, $token) {
2720
-		$url = rtrim($remote, '/');
2721
-		$fields = array('token' => $token, 'format' => 'json');
2722
-		$url = self::removeProtocolFromUrl($url);
2723
-		$result = self::tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields);
2724
-		$status = json_decode($result['result'], true);
2725
-
2726
-		return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200));
2727
-	}
2728
-
2729
-	/**
2730
-	 * check if user can only share with group members
2731
-	 * @return bool
2732
-	 */
2733
-	public static function shareWithGroupMembersOnly() {
2734
-		$value = \OC::$server->getAppConfig()->getValue('core', 'shareapi_only_share_with_group_members', 'no');
2735
-		return ($value === 'yes') ? true : false;
2736
-	}
2737
-
2738
-	/**
2739
-	 * @return bool
2740
-	 */
2741
-	public static function isDefaultExpireDateEnabled() {
2742
-		$defaultExpireDateEnabled = \OCP\Config::getAppValue('core', 'shareapi_default_expire_date', 'no');
2743
-		return ($defaultExpireDateEnabled === "yes") ? true : false;
2744
-	}
2745
-
2746
-	/**
2747
-	 * @return bool
2748
-	 */
2749
-	public static function enforceDefaultExpireDate() {
2750
-		$enforceDefaultExpireDate = \OCP\Config::getAppValue('core', 'shareapi_enforce_expire_date', 'no');
2751
-		return ($enforceDefaultExpireDate === "yes") ? true : false;
2752
-	}
2753
-
2754
-	/**
2755
-	 * @return int
2756
-	 */
2757
-	public static function getExpireInterval() {
2758
-		return (int)\OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
2759
-	}
2760
-
2761
-	/**
2762
-	 * Checks whether the given path is reachable for the given owner
2763
-	 *
2764
-	 * @param string $path path relative to files
2765
-	 * @param string $ownerStorageId storage id of the owner
2766
-	 *
2767
-	 * @return boolean true if file is reachable, false otherwise
2768
-	 */
2769
-	private static function isFileReachable($path, $ownerStorageId) {
2770
-		// if outside the home storage, file is always considered reachable
2771
-		if (!(substr($ownerStorageId, 0, 6) === 'home::' ||
2772
-			substr($ownerStorageId, 0, 13) === 'object::user:'
2773
-		)) {
2774
-			return true;
2775
-		}
2776
-
2777
-		// if inside the home storage, the file has to be under "/files/"
2778
-		$path = ltrim($path, '/');
2779
-		if (substr($path, 0, 6) === 'files/') {
2780
-			return true;
2781
-		}
2782
-
2783
-		return false;
2784
-	}
2785
-
2786
-	/**
2787
-	 * @param IConfig $config
2788
-	 * @return bool 
2789
-	 */
2790
-	public static function enforcePassword(IConfig $config) {
2791
-		$enforcePassword = $config->getAppValue('core', 'shareapi_enforce_links_password', 'no');
2792
-		return ($enforcePassword === "yes") ? true : false;
2793
-	}
2794
-
2795
-	/**
2796
-	 * Get all share entries, including non-unique group items
2797
-	 *
2798
-	 * @param string $owner
2799
-	 * @return array
2800
-	 */
2801
-	public static function getAllSharesForOwner($owner) {
2802
-		$query = 'SELECT * FROM `*PREFIX*share` WHERE `uid_owner` = ?';
2803
-		$result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$owner]);
2804
-		return $result->fetchAll();
2805
-	}
2806
-
2807
-	/**
2808
-	 * Get all share entries, including non-unique group items for a file
2809
-	 *
2810
-	 * @param int $id
2811
-	 * @return array
2812
-	 */
2813
-	public static function getAllSharesForFileId($id) {
2814
-		$query = 'SELECT * FROM `*PREFIX*share` WHERE `file_source` = ?';
2815
-		$result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$id]);
2816
-		return $result->fetchAll();
2817
-	}
2818
-
2819
-	/**
2820
-	 * @param string $password
2821
-	 * @throws \Exception
2822
-	 */
2823
-	private static function verifyPassword($password) {
2824
-
2825
-		$accepted = true;
2826
-		$message = '';
2827
-		\OCP\Util::emitHook('\OC\Share', 'verifyPassword', [
2828
-			'password' => $password,
2829
-			'accepted' => &$accepted,
2830
-			'message' => &$message
2831
-		]);
2832
-
2833
-		if (!$accepted) {
2834
-			throw new \Exception($message);
2835
-		}
2836
-	}
1237
+            if ($permissions & ~(int)$rootItem['permissions']) {
1238
+                $qb = $connection->getQueryBuilder();
1239
+                $qb->select('id', 'permissions', 'item_type')
1240
+                    ->from('share')
1241
+                    ->where($qb->expr()->eq('parent', $qb->createParameter('parent')))
1242
+                    ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('share_type')))
1243
+                    ->andWhere($qb->expr()->neq('permissions', $qb->createParameter('shareDeleted')))
1244
+                    ->setParameter(':parent', (int)$rootItem['id'])
1245
+                    ->setParameter(':share_type', 2)
1246
+                    ->setParameter(':shareDeleted', 0);
1247
+                $result = $qb->execute();
1248
+
1249
+                $ids = [];
1250
+                while ($item = $result->fetch()) {
1251
+                    $item = $sanitizeItem($item);
1252
+                    $items[] = $item;
1253
+                    $ids[] = $item['id'];
1254
+                }
1255
+                $result->closeCursor();
1256
+
1257
+                // Add permssions for all USERGROUP shares of this item
1258
+                if (!empty($ids)) {
1259
+                    $ids = $intArrayToLiteralArray($ids, $qb->expr());
1260
+
1261
+                    $qb = $connection->getQueryBuilder();
1262
+                    $qb->update('share')
1263
+                        ->set('permissions', $qb->createParameter('permissions'))
1264
+                        ->where($qb->expr()->in('id', $ids))
1265
+                        ->setParameter(':permissions', $permissions);
1266
+                    $qb->execute();
1267
+                }
1268
+            }
1269
+
1270
+            foreach ($items as $item) {
1271
+                \OC_Hook::emit('OCP\Share', 'post_update_permissions', ['share' => $item]);
1272
+            }
1273
+
1274
+            return true;
1275
+        }
1276
+        $message = 'Setting permissions for %s failed, because the item was not found';
1277
+        $message_t = $l->t('Setting permissions for %s failed, because the item was not found', array($itemSource));
1278
+
1279
+        \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSource), \OCP\Util::DEBUG);
1280
+        throw new \Exception($message_t);
1281
+    }
1282
+
1283
+    /**
1284
+     * validate expiration date if it meets all constraints
1285
+     *
1286
+     * @param string $expireDate well formatted date string, e.g. "DD-MM-YYYY"
1287
+     * @param string $shareTime timestamp when the file was shared
1288
+     * @param string $itemType
1289
+     * @param string $itemSource
1290
+     * @return \DateTime validated date
1291
+     * @throws \Exception when the expire date is in the past or further in the future then the enforced date
1292
+     */
1293
+    private static function validateExpireDate($expireDate, $shareTime, $itemType, $itemSource) {
1294
+        $l = \OC::$server->getL10N('lib');
1295
+        $date = new \DateTime($expireDate);
1296
+        $today = new \DateTime('now');
1297
+
1298
+        // if the user doesn't provide a share time we need to get it from the database
1299
+        // fall-back mode to keep API stable, because the $shareTime parameter was added later
1300
+        $defaultExpireDateEnforced = \OCP\Util::isDefaultExpireDateEnforced();
1301
+        if ($defaultExpireDateEnforced && $shareTime === null) {
1302
+            $items = self::getItemShared($itemType, $itemSource);
1303
+            $firstItem = reset($items);
1304
+            $shareTime = (int)$firstItem['stime'];
1305
+        }
1306
+
1307
+        if ($defaultExpireDateEnforced) {
1308
+            // initialize max date with share time
1309
+            $maxDate = new \DateTime();
1310
+            $maxDate->setTimestamp($shareTime);
1311
+            $maxDays = \OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
1312
+            $maxDate->add(new \DateInterval('P' . $maxDays . 'D'));
1313
+            if ($date > $maxDate) {
1314
+                $warning = 'Cannot set expiration date. Shares cannot expire later than ' . $maxDays . ' after they have been shared';
1315
+                $warning_t = $l->t('Cannot set expiration date. Shares cannot expire later than %s after they have been shared', array($maxDays));
1316
+                \OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN);
1317
+                throw new \Exception($warning_t);
1318
+            }
1319
+        }
1320
+
1321
+        if ($date < $today) {
1322
+            $message = 'Cannot set expiration date. Expiration date is in the past';
1323
+            $message_t = $l->t('Cannot set expiration date. Expiration date is in the past');
1324
+            \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::WARN);
1325
+            throw new \Exception($message_t);
1326
+        }
1327
+
1328
+        return $date;
1329
+    }
1330
+
1331
+    /**
1332
+     * Set expiration date for a share
1333
+     * @param string $itemType
1334
+     * @param string $itemSource
1335
+     * @param string $date expiration date
1336
+     * @param int $shareTime timestamp from when the file was shared
1337
+     * @return boolean
1338
+     * @throws \Exception when the expire date is not set, in the past or further in the future then the enforced date
1339
+     */
1340
+    public static function setExpirationDate($itemType, $itemSource, $date, $shareTime = null) {
1341
+        $user = \OC_User::getUser();
1342
+        $l = \OC::$server->getL10N('lib');
1343
+
1344
+        if ($date == '') {
1345
+            if (\OCP\Util::isDefaultExpireDateEnforced()) {
1346
+                $warning = 'Cannot clear expiration date. Shares are required to have an expiration date.';
1347
+                $warning_t = $l->t('Cannot clear expiration date. Shares are required to have an expiration date.');
1348
+                \OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN);
1349
+                throw new \Exception($warning_t);
1350
+            } else {
1351
+                $date = null;
1352
+            }
1353
+        } else {
1354
+            $date = self::validateExpireDate($date, $shareTime, $itemType, $itemSource);
1355
+        }
1356
+        $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `item_type` = ? AND `item_source` = ?  AND `uid_owner` = ? AND `share_type` = ?');
1357
+        $query->bindValue(1, $date, 'datetime');
1358
+        $query->bindValue(2, $itemType);
1359
+        $query->bindValue(3, $itemSource);
1360
+        $query->bindValue(4, $user);
1361
+        $query->bindValue(5, \OCP\Share::SHARE_TYPE_LINK);
1362
+
1363
+        $query->execute();
1364
+
1365
+        \OC_Hook::emit('OCP\Share', 'post_set_expiration_date', array(
1366
+            'itemType' => $itemType,
1367
+            'itemSource' => $itemSource,
1368
+            'date' => $date,
1369
+            'uidOwner' => $user
1370
+        ));
1371
+
1372
+        return true;
1373
+    }
1374
+
1375
+    /**
1376
+     * Retrieve the owner of a connection
1377
+     *
1378
+     * @param IDBConnection $connection
1379
+     * @param int $shareId
1380
+     * @throws \Exception
1381
+     * @return string uid of share owner
1382
+     */
1383
+    private static function getShareOwner(IDBConnection $connection, $shareId) {
1384
+        $qb = $connection->getQueryBuilder();
1385
+
1386
+        $qb->select('uid_owner')
1387
+            ->from('share')
1388
+            ->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
1389
+            ->setParameter(':shareId', $shareId);
1390
+        $result = $qb->execute();
1391
+        $result = $result->fetch();
1392
+
1393
+        if (empty($result)) {
1394
+            throw new \Exception('Share not found');
1395
+        }
1396
+
1397
+        return $result['uid_owner'];
1398
+    }
1399
+
1400
+    /**
1401
+     * Set password for a public link share
1402
+     *
1403
+     * @param IUserSession $userSession
1404
+     * @param IDBConnection $connection
1405
+     * @param IConfig $config
1406
+     * @param int $shareId
1407
+     * @param string $password
1408
+     * @throws \Exception
1409
+     * @return boolean
1410
+     */
1411
+    public static function setPassword(IUserSession $userSession,
1412
+                                        IDBConnection $connection,
1413
+                                        IConfig $config,
1414
+                                        $shareId, $password) {
1415
+        $user = $userSession->getUser();
1416
+        if (is_null($user)) {
1417
+            throw new \Exception("User not logged in");
1418
+        }
1419
+
1420
+        $uid = self::getShareOwner($connection, $shareId);
1421
+
1422
+        if ($uid !== $user->getUID()) {
1423
+            throw new \Exception('Cannot update share of a different user');
1424
+        }
1425
+
1426
+        if ($password === '') {
1427
+            $password = null;
1428
+        }
1429
+
1430
+        //If passwords are enforced the password can't be null
1431
+        if (self::enforcePassword($config) && is_null($password)) {
1432
+            throw new \Exception('Cannot remove password');
1433
+        }
1434
+
1435
+        self::verifyPassword($password);
1436
+
1437
+        $qb = $connection->getQueryBuilder();
1438
+        $qb->update('share')
1439
+            ->set('share_with', $qb->createParameter('pass'))
1440
+            ->where($qb->expr()->eq('id', $qb->createParameter('shareId')))
1441
+            ->setParameter(':pass', is_null($password) ? null : \OC::$server->getHasher()->hash($password))
1442
+            ->setParameter(':shareId', $shareId);
1443
+
1444
+        $qb->execute();
1445
+
1446
+        return true;
1447
+    }
1448
+
1449
+    /**
1450
+     * Checks whether a share has expired, calls unshareItem() if yes.
1451
+     * @param array $item Share data (usually database row)
1452
+     * @return boolean True if item was expired, false otherwise.
1453
+     */
1454
+    protected static function expireItem(array $item) {
1455
+
1456
+        $result = false;
1457
+
1458
+        // only use default expiration date for link shares
1459
+        if ((int) $item['share_type'] === self::SHARE_TYPE_LINK) {
1460
+
1461
+            // calculate expiration date
1462
+            if (!empty($item['expiration'])) {
1463
+                $userDefinedExpire = new \DateTime($item['expiration']);
1464
+                $expires = $userDefinedExpire->getTimestamp();
1465
+            } else {
1466
+                $expires = null;
1467
+            }
1468
+
1469
+
1470
+            // get default expiration settings
1471
+            $defaultSettings = Helper::getDefaultExpireSetting();
1472
+            $expires = Helper::calculateExpireDate($defaultSettings, $item['stime'], $expires);
1473
+
1474
+
1475
+            if (is_int($expires)) {
1476
+                $now = time();
1477
+                if ($now > $expires) {
1478
+                    self::unshareItem($item);
1479
+                    $result = true;
1480
+                }
1481
+            }
1482
+        }
1483
+        return $result;
1484
+    }
1485
+
1486
+    /**
1487
+     * Unshares a share given a share data array
1488
+     * @param array $item Share data (usually database row)
1489
+     * @param int $newParent parent ID
1490
+     * @return null
1491
+     */
1492
+    protected static function unshareItem(array $item, $newParent = null) {
1493
+
1494
+        $shareType = (int)$item['share_type'];
1495
+        $shareWith = null;
1496
+        if ($shareType !== \OCP\Share::SHARE_TYPE_LINK) {
1497
+            $shareWith = $item['share_with'];
1498
+        }
1499
+
1500
+        // Pass all the vars we have for now, they may be useful
1501
+        $hookParams = array(
1502
+            'id'            => $item['id'],
1503
+            'itemType'      => $item['item_type'],
1504
+            'itemSource'    => $item['item_source'],
1505
+            'shareType'     => $shareType,
1506
+            'shareWith'     => $shareWith,
1507
+            'itemParent'    => $item['parent'],
1508
+            'uidOwner'      => $item['uid_owner'],
1509
+        );
1510
+        if($item['item_type'] === 'file' || $item['item_type'] === 'folder') {
1511
+            $hookParams['fileSource'] = $item['file_source'];
1512
+            $hookParams['fileTarget'] = $item['file_target'];
1513
+        }
1514
+
1515
+        \OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams);
1516
+        $deletedShares = Helper::delete($item['id'], false, null, $newParent);
1517
+        $deletedShares[] = $hookParams;
1518
+        $hookParams['deletedShares'] = $deletedShares;
1519
+        \OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
1520
+        if ((int)$item['share_type'] === \OCP\Share::SHARE_TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) {
1521
+            list(, $remote) = Helper::splitUserRemote($item['share_with']);
1522
+            self::sendRemoteUnshare($remote, $item['id'], $item['token']);
1523
+        }
1524
+    }
1525
+
1526
+    /**
1527
+     * Get the backend class for the specified item type
1528
+     * @param string $itemType
1529
+     * @throws \Exception
1530
+     * @return \OCP\Share_Backend
1531
+     */
1532
+    public static function getBackend($itemType) {
1533
+        $l = \OC::$server->getL10N('lib');
1534
+        if (isset(self::$backends[$itemType])) {
1535
+            return self::$backends[$itemType];
1536
+        } else if (isset(self::$backendTypes[$itemType]['class'])) {
1537
+            $class = self::$backendTypes[$itemType]['class'];
1538
+            if (class_exists($class)) {
1539
+                self::$backends[$itemType] = new $class;
1540
+                if (!(self::$backends[$itemType] instanceof \OCP\Share_Backend)) {
1541
+                    $message = 'Sharing backend %s must implement the interface OCP\Share_Backend';
1542
+                    $message_t = $l->t('Sharing backend %s must implement the interface OCP\Share_Backend', array($class));
1543
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $class), \OCP\Util::ERROR);
1544
+                    throw new \Exception($message_t);
1545
+                }
1546
+                return self::$backends[$itemType];
1547
+            } else {
1548
+                $message = 'Sharing backend %s not found';
1549
+                $message_t = $l->t('Sharing backend %s not found', array($class));
1550
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $class), \OCP\Util::ERROR);
1551
+                throw new \Exception($message_t);
1552
+            }
1553
+        }
1554
+        $message = 'Sharing backend for %s not found';
1555
+        $message_t = $l->t('Sharing backend for %s not found', array($itemType));
1556
+        \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemType), \OCP\Util::ERROR);
1557
+        throw new \Exception($message_t);
1558
+    }
1559
+
1560
+    /**
1561
+     * Check if resharing is allowed
1562
+     * @return boolean true if allowed or false
1563
+     *
1564
+     * Resharing is allowed by default if not configured
1565
+     */
1566
+    public static function isResharingAllowed() {
1567
+        if (!isset(self::$isResharingAllowed)) {
1568
+            if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_resharing', 'yes') == 'yes') {
1569
+                self::$isResharingAllowed = true;
1570
+            } else {
1571
+                self::$isResharingAllowed = false;
1572
+            }
1573
+        }
1574
+        return self::$isResharingAllowed;
1575
+    }
1576
+
1577
+    /**
1578
+     * Get a list of collection item types for the specified item type
1579
+     * @param string $itemType
1580
+     * @return array
1581
+     */
1582
+    private static function getCollectionItemTypes($itemType) {
1583
+        $collectionTypes = array($itemType);
1584
+        foreach (self::$backendTypes as $type => $backend) {
1585
+            if (in_array($backend['collectionOf'], $collectionTypes)) {
1586
+                $collectionTypes[] = $type;
1587
+            }
1588
+        }
1589
+        // TODO Add option for collections to be collection of themselves, only 'folder' does it now...
1590
+        if (isset(self::$backendTypes[$itemType]) && (!self::getBackend($itemType) instanceof \OCP\Share_Backend_Collection || $itemType != 'folder')) {
1591
+            unset($collectionTypes[0]);
1592
+        }
1593
+        // Return array if collections were found or the item type is a
1594
+        // collection itself - collections can be inside collections
1595
+        if (count($collectionTypes) > 0) {
1596
+            return $collectionTypes;
1597
+        }
1598
+        return false;
1599
+    }
1600
+
1601
+    /**
1602
+     * Get the owners of items shared with a user.
1603
+     *
1604
+     * @param string $user The user the items are shared with.
1605
+     * @param string $type The type of the items shared with the user.
1606
+     * @param boolean $includeCollections Include collection item types (optional)
1607
+     * @param boolean $includeOwner include owner in the list of users the item is shared with (optional)
1608
+     * @return array
1609
+     */
1610
+    public static function getSharedItemsOwners($user, $type, $includeCollections = false, $includeOwner = false) {
1611
+        // First, we find out if $type is part of a collection (and if that collection is part of
1612
+        // another one and so on).
1613
+        $collectionTypes = array();
1614
+        if (!$includeCollections || !$collectionTypes = self::getCollectionItemTypes($type)) {
1615
+            $collectionTypes[] = $type;
1616
+        }
1617
+
1618
+        // Of these collection types, along with our original $type, we make a
1619
+        // list of the ones for which a sharing backend has been registered.
1620
+        // FIXME: Ideally, we wouldn't need to nest getItemsSharedWith in this loop but just call it
1621
+        // with its $includeCollections parameter set to true. Unfortunately, this fails currently.
1622
+        $allMaybeSharedItems = array();
1623
+        foreach ($collectionTypes as $collectionType) {
1624
+            if (isset(self::$backends[$collectionType])) {
1625
+                $allMaybeSharedItems[$collectionType] = self::getItemsSharedWithUser(
1626
+                    $collectionType,
1627
+                    $user,
1628
+                    self::FORMAT_NONE
1629
+                );
1630
+            }
1631
+        }
1632
+
1633
+        $owners = array();
1634
+        if ($includeOwner) {
1635
+            $owners[] = $user;
1636
+        }
1637
+
1638
+        // We take a look at all shared items of the given $type (or of the collections it is part of)
1639
+        // and find out their owners. Then, we gather the tags for the original $type from all owners,
1640
+        // and return them as elements of a list that look like "Tag (owner)".
1641
+        foreach ($allMaybeSharedItems as $collectionType => $maybeSharedItems) {
1642
+            foreach ($maybeSharedItems as $sharedItem) {
1643
+                if (isset($sharedItem['id'])) { //workaround for https://github.com/owncloud/core/issues/2814
1644
+                    $owners[] = $sharedItem['uid_owner'];
1645
+                }
1646
+            }
1647
+        }
1648
+
1649
+        return $owners;
1650
+    }
1651
+
1652
+    /**
1653
+     * Get shared items from the database
1654
+     * @param string $itemType
1655
+     * @param string $item Item source or target (optional)
1656
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
1657
+     * @param string $shareWith User or group the item is being shared with
1658
+     * @param string $uidOwner User that is the owner of shared items (optional)
1659
+     * @param int $format Format to convert items to with formatItems() (optional)
1660
+     * @param mixed $parameters to pass to formatItems() (optional)
1661
+     * @param int $limit Number of items to return, -1 to return all matches (optional)
1662
+     * @param boolean $includeCollections Include collection item types (optional)
1663
+     * @param boolean $itemShareWithBySource (optional)
1664
+     * @param boolean $checkExpireDate
1665
+     * @return array
1666
+     *
1667
+     * See public functions getItem(s)... for parameter usage
1668
+     *
1669
+     */
1670
+    public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null,
1671
+                                    $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1,
1672
+                                    $includeCollections = false, $itemShareWithBySource = false, $checkExpireDate  = true) {
1673
+        if (!self::isEnabled()) {
1674
+            return array();
1675
+        }
1676
+        $backend = self::getBackend($itemType);
1677
+        $collectionTypes = false;
1678
+        // Get filesystem root to add it to the file target and remove from the
1679
+        // file source, match file_source with the file cache
1680
+        if ($itemType == 'file' || $itemType == 'folder') {
1681
+            if(!is_null($uidOwner)) {
1682
+                $root = \OC\Files\Filesystem::getRoot();
1683
+            } else {
1684
+                $root = '';
1685
+            }
1686
+            $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
1687
+            if (!isset($item)) {
1688
+                $where .= ' AND `file_target` IS NOT NULL ';
1689
+            }
1690
+            $where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
1691
+            $fileDependent = true;
1692
+            $queryArgs = array();
1693
+        } else {
1694
+            $fileDependent = false;
1695
+            $root = '';
1696
+            $collectionTypes = self::getCollectionItemTypes($itemType);
1697
+            if ($includeCollections && !isset($item) && $collectionTypes) {
1698
+                // If includeCollections is true, find collections of this item type, e.g. a music album contains songs
1699
+                if (!in_array($itemType, $collectionTypes)) {
1700
+                    $itemTypes = array_merge(array($itemType), $collectionTypes);
1701
+                } else {
1702
+                    $itemTypes = $collectionTypes;
1703
+                }
1704
+                $placeholders = join(',', array_fill(0, count($itemTypes), '?'));
1705
+                $where = ' WHERE `item_type` IN ('.$placeholders.'))';
1706
+                $queryArgs = $itemTypes;
1707
+            } else {
1708
+                $where = ' WHERE `item_type` = ?';
1709
+                $queryArgs = array($itemType);
1710
+            }
1711
+        }
1712
+        if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
1713
+            $where .= ' AND `share_type` != ?';
1714
+            $queryArgs[] = self::SHARE_TYPE_LINK;
1715
+        }
1716
+        if (isset($shareType)) {
1717
+            // Include all user and group items
1718
+            if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
1719
+                $where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) ';
1720
+                $queryArgs[] = self::SHARE_TYPE_USER;
1721
+                $queryArgs[] = self::$shareTypeGroupUserUnique;
1722
+                $queryArgs[] = $shareWith;
1723
+                $groups = \OC_Group::getUserGroups($shareWith);
1724
+                if (!empty($groups)) {
1725
+                    $placeholders = join(',', array_fill(0, count($groups), '?'));
1726
+                    $where .= ' OR (`share_type` = ? AND `share_with` IN ('.$placeholders.')) ';
1727
+                    $queryArgs[] = self::SHARE_TYPE_GROUP;
1728
+                    $queryArgs = array_merge($queryArgs, $groups);
1729
+                }
1730
+                $where .= ')';
1731
+                // Don't include own group shares
1732
+                $where .= ' AND `uid_owner` != ?';
1733
+                $queryArgs[] = $shareWith;
1734
+            } else {
1735
+                $where .= ' AND `share_type` = ?';
1736
+                $queryArgs[] = $shareType;
1737
+                if (isset($shareWith)) {
1738
+                    $where .= ' AND `share_with` = ?';
1739
+                    $queryArgs[] = $shareWith;
1740
+                }
1741
+            }
1742
+        }
1743
+        if (isset($uidOwner)) {
1744
+            $where .= ' AND `uid_owner` = ?';
1745
+            $queryArgs[] = $uidOwner;
1746
+            if (!isset($shareType)) {
1747
+                // Prevent unique user targets for group shares from being selected
1748
+                $where .= ' AND `share_type` != ?';
1749
+                $queryArgs[] = self::$shareTypeGroupUserUnique;
1750
+            }
1751
+            if ($fileDependent) {
1752
+                $column = 'file_source';
1753
+            } else {
1754
+                $column = 'item_source';
1755
+            }
1756
+        } else {
1757
+            if ($fileDependent) {
1758
+                $column = 'file_target';
1759
+            } else {
1760
+                $column = 'item_target';
1761
+            }
1762
+        }
1763
+        if (isset($item)) {
1764
+            $collectionTypes = self::getCollectionItemTypes($itemType);
1765
+            if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
1766
+                $where .= ' AND (';
1767
+            } else {
1768
+                $where .= ' AND';
1769
+            }
1770
+            // If looking for own shared items, check item_source else check item_target
1771
+            if (isset($uidOwner) || $itemShareWithBySource) {
1772
+                // If item type is a file, file source needs to be checked in case the item was converted
1773
+                if ($fileDependent) {
1774
+                    $where .= ' `file_source` = ?';
1775
+                    $column = 'file_source';
1776
+                } else {
1777
+                    $where .= ' `item_source` = ?';
1778
+                    $column = 'item_source';
1779
+                }
1780
+            } else {
1781
+                if ($fileDependent) {
1782
+                    $where .= ' `file_target` = ?';
1783
+                    $item = \OC\Files\Filesystem::normalizePath($item);
1784
+                } else {
1785
+                    $where .= ' `item_target` = ?';
1786
+                }
1787
+            }
1788
+            $queryArgs[] = $item;
1789
+            if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) {
1790
+                $placeholders = join(',', array_fill(0, count($collectionTypes), '?'));
1791
+                $where .= ' OR `item_type` IN ('.$placeholders.'))';
1792
+                $queryArgs = array_merge($queryArgs, $collectionTypes);
1793
+            }
1794
+        }
1795
+
1796
+        if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) {
1797
+            // Make sure the unique user target is returned if it exists,
1798
+            // unique targets should follow the group share in the database
1799
+            // If the limit is not 1, the filtering can be done later
1800
+            $where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
1801
+        } else {
1802
+            $where .= ' ORDER BY `*PREFIX*share`.`id` ASC';
1803
+        }
1804
+
1805
+        if ($limit != -1 && !$includeCollections) {
1806
+            // The limit must be at least 3, because filtering needs to be done
1807
+            if ($limit < 3) {
1808
+                $queryLimit = 3;
1809
+            } else {
1810
+                $queryLimit = $limit;
1811
+            }
1812
+        } else {
1813
+            $queryLimit = null;
1814
+        }
1815
+        $select = self::createSelectStatement($format, $fileDependent, $uidOwner);
1816
+        $root = strlen($root);
1817
+        $query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit);
1818
+        $result = $query->execute($queryArgs);
1819
+        if ($result === false) {
1820
+            \OCP\Util::writeLog('OCP\Share',
1821
+                \OC_DB::getErrorMessage() . ', select=' . $select . ' where=',
1822
+                \OCP\Util::ERROR);
1823
+        }
1824
+        $items = array();
1825
+        $targets = array();
1826
+        $switchedItems = array();
1827
+        $mounts = array();
1828
+        while ($row = $result->fetchRow()) {
1829
+            self::transformDBResults($row);
1830
+            // Filter out duplicate group shares for users with unique targets
1831
+            if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
1832
+                continue;
1833
+            }
1834
+            if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
1835
+                $row['share_type'] = self::SHARE_TYPE_GROUP;
1836
+                $row['unique_name'] = true; // remember that we use a unique name for this user
1837
+                $row['share_with'] = $items[$row['parent']]['share_with'];
1838
+                // if the group share was unshared from the user we keep the permission, otherwise
1839
+                // we take the permission from the parent because this is always the up-to-date
1840
+                // permission for the group share
1841
+                if ($row['permissions'] > 0) {
1842
+                    $row['permissions'] = $items[$row['parent']]['permissions'];
1843
+                }
1844
+                // Remove the parent group share
1845
+                unset($items[$row['parent']]);
1846
+                if ($row['permissions'] == 0) {
1847
+                    continue;
1848
+                }
1849
+            } else if (!isset($uidOwner)) {
1850
+                // Check if the same target already exists
1851
+                if (isset($targets[$row['id']])) {
1852
+                    // Check if the same owner shared with the user twice
1853
+                    // through a group and user share - this is allowed
1854
+                    $id = $targets[$row['id']];
1855
+                    if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
1856
+                        // Switch to group share type to ensure resharing conditions aren't bypassed
1857
+                        if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) {
1858
+                            $items[$id]['share_type'] = self::SHARE_TYPE_GROUP;
1859
+                            $items[$id]['share_with'] = $row['share_with'];
1860
+                        }
1861
+                        // Switch ids if sharing permission is granted on only
1862
+                        // one share to ensure correct parent is used if resharing
1863
+                        if (~(int)$items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE
1864
+                            && (int)$row['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
1865
+                            $items[$row['id']] = $items[$id];
1866
+                            $switchedItems[$id] = $row['id'];
1867
+                            unset($items[$id]);
1868
+                            $id = $row['id'];
1869
+                        }
1870
+                        $items[$id]['permissions'] |= (int)$row['permissions'];
1871
+
1872
+                    }
1873
+                    continue;
1874
+                } elseif (!empty($row['parent'])) {
1875
+                    $targets[$row['parent']] = $row['id'];
1876
+                }
1877
+            }
1878
+            // Remove root from file source paths if retrieving own shared items
1879
+            if (isset($uidOwner) && isset($row['path'])) {
1880
+                if (isset($row['parent'])) {
1881
+                    $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?');
1882
+                    $parentResult = $query->execute(array($row['parent']));
1883
+                    if ($result === false) {
1884
+                        \OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: ' .
1885
+                            \OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where,
1886
+                            \OCP\Util::ERROR);
1887
+                    } else {
1888
+                        $parentRow = $parentResult->fetchRow();
1889
+                        $tmpPath = $parentRow['file_target'];
1890
+                        // find the right position where the row path continues from the target path
1891
+                        $pos = strrpos($row['path'], $parentRow['file_target']);
1892
+                        $subPath = substr($row['path'], $pos);
1893
+                        $splitPath = explode('/', $subPath);
1894
+                        foreach (array_slice($splitPath, 2) as $pathPart) {
1895
+                            $tmpPath = $tmpPath . '/' . $pathPart;
1896
+                        }
1897
+                        $row['path'] = $tmpPath;
1898
+                    }
1899
+                } else {
1900
+                    if (!isset($mounts[$row['storage']])) {
1901
+                        $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']);
1902
+                        if (is_array($mountPoints) && !empty($mountPoints)) {
1903
+                            $mounts[$row['storage']] = current($mountPoints);
1904
+                        }
1905
+                    }
1906
+                    if (!empty($mounts[$row['storage']])) {
1907
+                        $path = $mounts[$row['storage']]->getMountPoint().$row['path'];
1908
+                        $relPath = substr($path, $root); // path relative to data/user
1909
+                        $row['path'] = rtrim($relPath, '/');
1910
+                    }
1911
+                }
1912
+            }
1913
+
1914
+            if($checkExpireDate) {
1915
+                if (self::expireItem($row)) {
1916
+                    continue;
1917
+                }
1918
+            }
1919
+            // Check if resharing is allowed, if not remove share permission
1920
+            if (isset($row['permissions']) && (!self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser())) {
1921
+                $row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE;
1922
+            }
1923
+            // Add display names to result
1924
+            $row['share_with_displayname'] = $row['share_with'];
1925
+            if ( isset($row['share_with']) && $row['share_with'] != '' &&
1926
+                $row['share_type'] === self::SHARE_TYPE_USER) {
1927
+                $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']);
1928
+            } else if(isset($row['share_with']) && $row['share_with'] != '' &&
1929
+                $row['share_type'] === self::SHARE_TYPE_REMOTE) {
1930
+                $addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']);
1931
+                foreach ($addressBookEntries as $entry) {
1932
+                    foreach ($entry['CLOUD'] as $cloudID) {
1933
+                        if ($cloudID === $row['share_with']) {
1934
+                            $row['share_with_displayname'] = $entry['FN'];
1935
+                        }
1936
+                    }
1937
+                }
1938
+            }
1939
+            if ( isset($row['uid_owner']) && $row['uid_owner'] != '') {
1940
+                $row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
1941
+            }
1942
+
1943
+            if ($row['permissions'] > 0) {
1944
+                $items[$row['id']] = $row;
1945
+            }
1946
+
1947
+        }
1948
+
1949
+        // group items if we are looking for items shared with the current user
1950
+        if (isset($shareWith) && $shareWith === \OCP\User::getUser()) {
1951
+            $items = self::groupItems($items, $itemType);
1952
+        }
1953
+
1954
+        if (!empty($items)) {
1955
+            $collectionItems = array();
1956
+            foreach ($items as &$row) {
1957
+                // Return only the item instead of a 2-dimensional array
1958
+                if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) {
1959
+                    if ($format == self::FORMAT_NONE) {
1960
+                        return $row;
1961
+                    } else {
1962
+                        break;
1963
+                    }
1964
+                }
1965
+                // Check if this is a collection of the requested item type
1966
+                if ($includeCollections && $collectionTypes && $row['item_type'] !== 'folder' && in_array($row['item_type'], $collectionTypes)) {
1967
+                    if (($collectionBackend = self::getBackend($row['item_type']))
1968
+                        && $collectionBackend instanceof \OCP\Share_Backend_Collection) {
1969
+                        // Collections can be inside collections, check if the item is a collection
1970
+                        if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) {
1971
+                            $collectionItems[] = $row;
1972
+                        } else {
1973
+                            $collection = array();
1974
+                            $collection['item_type'] = $row['item_type'];
1975
+                            if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
1976
+                                $collection['path'] = basename($row['path']);
1977
+                            }
1978
+                            $row['collection'] = $collection;
1979
+                            // Fetch all of the children sources
1980
+                            $children = $collectionBackend->getChildren($row[$column]);
1981
+                            foreach ($children as $child) {
1982
+                                $childItem = $row;
1983
+                                $childItem['item_type'] = $itemType;
1984
+                                if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') {
1985
+                                    $childItem['item_source'] = $child['source'];
1986
+                                    $childItem['item_target'] = $child['target'];
1987
+                                }
1988
+                                if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
1989
+                                    if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
1990
+                                        $childItem['file_source'] = $child['source'];
1991
+                                    } else { // TODO is this really needed if we already know that we use the file backend?
1992
+                                        $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']);
1993
+                                        $childItem['file_source'] = $meta['fileid'];
1994
+                                    }
1995
+                                    $childItem['file_target'] =
1996
+                                        \OC\Files\Filesystem::normalizePath($child['file_path']);
1997
+                                }
1998
+                                if (isset($item)) {
1999
+                                    if ($childItem[$column] == $item) {
2000
+                                        // Return only the item instead of a 2-dimensional array
2001
+                                        if ($limit == 1) {
2002
+                                            if ($format == self::FORMAT_NONE) {
2003
+                                                return $childItem;
2004
+                                            } else {
2005
+                                                // Unset the items array and break out of both loops
2006
+                                                $items = array();
2007
+                                                $items[] = $childItem;
2008
+                                                break 2;
2009
+                                            }
2010
+                                        } else {
2011
+                                            $collectionItems[] = $childItem;
2012
+                                        }
2013
+                                    }
2014
+                                } else {
2015
+                                    $collectionItems[] = $childItem;
2016
+                                }
2017
+                            }
2018
+                        }
2019
+                    }
2020
+                    // Remove collection item
2021
+                    $toRemove = $row['id'];
2022
+                    if (array_key_exists($toRemove, $switchedItems)) {
2023
+                        $toRemove = $switchedItems[$toRemove];
2024
+                    }
2025
+                    unset($items[$toRemove]);
2026
+                } elseif ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) {
2027
+                    // FIXME: Thats a dirty hack to improve file sharing performance,
2028
+                    // see github issue #10588 for more details
2029
+                    // Need to find a solution which works for all back-ends
2030
+                    $collectionBackend = self::getBackend($row['item_type']);
2031
+                    $sharedParents = $collectionBackend->getParents($row['item_source']);
2032
+                    foreach ($sharedParents as $parent) {
2033
+                        $collectionItems[] = $parent;
2034
+                    }
2035
+                }
2036
+            }
2037
+            if (!empty($collectionItems)) {
2038
+                $collectionItems = array_unique($collectionItems, SORT_REGULAR);
2039
+                $items = array_merge($items, $collectionItems);
2040
+            }
2041
+
2042
+            // filter out invalid items, these can appear when subshare entries exist
2043
+            // for a group in which the requested user isn't a member any more
2044
+            $items = array_filter($items, function($item) {
2045
+                return $item['share_type'] !== self::$shareTypeGroupUserUnique;
2046
+            });
2047
+
2048
+            return self::formatResult($items, $column, $backend, $format, $parameters);
2049
+        } elseif ($includeCollections && $collectionTypes && in_array('folder', $collectionTypes)) {
2050
+            // FIXME: Thats a dirty hack to improve file sharing performance,
2051
+            // see github issue #10588 for more details
2052
+            // Need to find a solution which works for all back-ends
2053
+            $collectionItems = array();
2054
+            $collectionBackend = self::getBackend('folder');
2055
+            $sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner);
2056
+            foreach ($sharedParents as $parent) {
2057
+                $collectionItems[] = $parent;
2058
+            }
2059
+            if ($limit === 1) {
2060
+                return reset($collectionItems);
2061
+            }
2062
+            return self::formatResult($collectionItems, $column, $backend, $format, $parameters);
2063
+        }
2064
+
2065
+        return array();
2066
+    }
2067
+
2068
+    /**
2069
+     * group items with link to the same source
2070
+     *
2071
+     * @param array $items
2072
+     * @param string $itemType
2073
+     * @return array of grouped items
2074
+     */
2075
+    protected static function groupItems($items, $itemType) {
2076
+
2077
+        $fileSharing = ($itemType === 'file' || $itemType === 'folder') ? true : false;
2078
+
2079
+        $result = array();
2080
+
2081
+        foreach ($items as $item) {
2082
+            $grouped = false;
2083
+            foreach ($result as $key => $r) {
2084
+                // for file/folder shares we need to compare file_source, otherwise we compare item_source
2085
+                // only group shares if they already point to the same target, otherwise the file where shared
2086
+                // before grouping of shares was added. In this case we don't group them toi avoid confusions
2087
+                if (( $fileSharing && $item['file_source'] === $r['file_source'] && $item['file_target'] === $r['file_target']) ||
2088
+                    (!$fileSharing && $item['item_source'] === $r['item_source'] && $item['item_target'] === $r['item_target'])) {
2089
+                    // add the first item to the list of grouped shares
2090
+                    if (!isset($result[$key]['grouped'])) {
2091
+                        $result[$key]['grouped'][] = $result[$key];
2092
+                    }
2093
+                    $result[$key]['permissions'] = (int) $item['permissions'] | (int) $r['permissions'];
2094
+                    $result[$key]['grouped'][] = $item;
2095
+                    $grouped = true;
2096
+                    break;
2097
+                }
2098
+            }
2099
+
2100
+            if (!$grouped) {
2101
+                $result[] = $item;
2102
+            }
2103
+
2104
+        }
2105
+
2106
+        return $result;
2107
+    }
2108
+
2109
+    /**
2110
+     * Put shared item into the database
2111
+     * @param string $itemType Item type
2112
+     * @param string $itemSource Item source
2113
+     * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
2114
+     * @param string $shareWith User or group the item is being shared with
2115
+     * @param string $uidOwner User that is the owner of shared item
2116
+     * @param int $permissions CRUDS permissions
2117
+     * @param boolean|array $parentFolder Parent folder target (optional)
2118
+     * @param string $token (optional)
2119
+     * @param string $itemSourceName name of the source item (optional)
2120
+     * @param \DateTime $expirationDate (optional)
2121
+     * @throws \Exception
2122
+     * @return mixed id of the new share or false
2123
+     */
2124
+    private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
2125
+                                $permissions, $parentFolder = null, $token = null, $itemSourceName = null, \DateTime $expirationDate = null) {
2126
+
2127
+        $queriesToExecute = array();
2128
+        $suggestedItemTarget = null;
2129
+        $groupFileTarget = $fileTarget = $suggestedFileTarget = $filePath = '';
2130
+        $groupItemTarget = $itemTarget = $fileSource = $parent = 0;
2131
+
2132
+        $result = self::checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate);
2133
+        if(!empty($result)) {
2134
+            $parent = $result['parent'];
2135
+            $itemSource = $result['itemSource'];
2136
+            $fileSource = $result['fileSource'];
2137
+            $suggestedItemTarget = $result['suggestedItemTarget'];
2138
+            $suggestedFileTarget = $result['suggestedFileTarget'];
2139
+            $filePath = $result['filePath'];
2140
+        }
2141
+
2142
+        $isGroupShare = false;
2143
+        if ($shareType == self::SHARE_TYPE_GROUP) {
2144
+            $isGroupShare = true;
2145
+            if (isset($shareWith['users'])) {
2146
+                $users = $shareWith['users'];
2147
+            } else {
2148
+                $users = \OC_Group::usersInGroup($shareWith['group']);
2149
+            }
2150
+            // remove current user from list
2151
+            if (in_array(\OCP\User::getUser(), $users)) {
2152
+                unset($users[array_search(\OCP\User::getUser(), $users)]);
2153
+            }
2154
+            $groupItemTarget = Helper::generateTarget($itemType, $itemSource,
2155
+                $shareType, $shareWith['group'], $uidOwner, $suggestedItemTarget);
2156
+            $groupFileTarget = Helper::generateTarget($itemType, $itemSource,
2157
+                $shareType, $shareWith['group'], $uidOwner, $filePath);
2158
+
2159
+            // add group share to table and remember the id as parent
2160
+            $queriesToExecute['groupShare'] = array(
2161
+                'itemType'			=> $itemType,
2162
+                'itemSource'		=> $itemSource,
2163
+                'itemTarget'		=> $groupItemTarget,
2164
+                'shareType'			=> $shareType,
2165
+                'shareWith'			=> $shareWith['group'],
2166
+                'uidOwner'			=> $uidOwner,
2167
+                'permissions'		=> $permissions,
2168
+                'shareTime'			=> time(),
2169
+                'fileSource'		=> $fileSource,
2170
+                'fileTarget'		=> $groupFileTarget,
2171
+                'token'				=> $token,
2172
+                'parent'			=> $parent,
2173
+                'expiration'		=> $expirationDate,
2174
+            );
2175
+
2176
+        } else {
2177
+            $users = array($shareWith);
2178
+            $itemTarget = Helper::generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner,
2179
+                $suggestedItemTarget);
2180
+        }
2181
+
2182
+        $run = true;
2183
+        $error = '';
2184
+        $preHookData = array(
2185
+            'itemType' => $itemType,
2186
+            'itemSource' => $itemSource,
2187
+            'shareType' => $shareType,
2188
+            'uidOwner' => $uidOwner,
2189
+            'permissions' => $permissions,
2190
+            'fileSource' => $fileSource,
2191
+            'expiration' => $expirationDate,
2192
+            'token' => $token,
2193
+            'run' => &$run,
2194
+            'error' => &$error
2195
+        );
2196
+
2197
+        $preHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget;
2198
+        $preHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith;
2199
+
2200
+        \OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData);
2201
+
2202
+        if ($run === false) {
2203
+            throw new \Exception($error);
2204
+        }
2205
+
2206
+        foreach ($users as $user) {
2207
+            $sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource;
2208
+            $sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user);
2209
+
2210
+            $userShareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType;
2211
+
2212
+            if ($sourceExists && $sourceExists['item_source'] === $itemSource) {
2213
+                $fileTarget = $sourceExists['file_target'];
2214
+                $itemTarget = $sourceExists['item_target'];
2215
+
2216
+                // for group shares we don't need a additional entry if the target is the same
2217
+                if($isGroupShare && $groupItemTarget === $itemTarget) {
2218
+                    continue;
2219
+                }
2220
+
2221
+            } elseif(!$sourceExists && !$isGroupShare)  {
2222
+
2223
+                $itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user,
2224
+                    $uidOwner, $suggestedItemTarget, $parent);
2225
+                if (isset($fileSource)) {
2226
+                    if ($parentFolder) {
2227
+                        if ($parentFolder === true) {
2228
+                            $fileTarget = Helper::generateTarget('file', $filePath, $userShareType, $user,
2229
+                                $uidOwner, $suggestedFileTarget, $parent);
2230
+                            if ($fileTarget != $groupFileTarget) {
2231
+                                $parentFolders[$user]['folder'] = $fileTarget;
2232
+                            }
2233
+                        } else if (isset($parentFolder[$user])) {
2234
+                            $fileTarget = $parentFolder[$user]['folder'].$itemSource;
2235
+                            $parent = $parentFolder[$user]['id'];
2236
+                        }
2237
+                    } else {
2238
+                        $fileTarget = Helper::generateTarget('file', $filePath, $userShareType,
2239
+                            $user, $uidOwner, $suggestedFileTarget, $parent);
2240
+                    }
2241
+                } else {
2242
+                    $fileTarget = null;
2243
+                }
2244
+
2245
+            } else {
2246
+
2247
+                // group share which doesn't exists until now, check if we need a unique target for this user
2248
+
2249
+                $itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $user,
2250
+                    $uidOwner, $suggestedItemTarget, $parent);
2251
+
2252
+                // do we also need a file target
2253
+                if (isset($fileSource)) {
2254
+                    $fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $user,
2255
+                        $uidOwner, $suggestedFileTarget, $parent);
2256
+                } else {
2257
+                    $fileTarget = null;
2258
+                }
2259
+
2260
+                if (($itemTarget === $groupItemTarget) &&
2261
+                    (!isset($fileSource) || $fileTarget === $groupFileTarget)) {
2262
+                    continue;
2263
+                }
2264
+            }
2265
+
2266
+            $queriesToExecute[] = array(
2267
+                'itemType'			=> $itemType,
2268
+                'itemSource'		=> $itemSource,
2269
+                'itemTarget'		=> $itemTarget,
2270
+                'shareType'			=> $userShareType,
2271
+                'shareWith'			=> $user,
2272
+                'uidOwner'			=> $uidOwner,
2273
+                'permissions'		=> $permissions,
2274
+                'shareTime'			=> time(),
2275
+                'fileSource'		=> $fileSource,
2276
+                'fileTarget'		=> $fileTarget,
2277
+                'token'				=> $token,
2278
+                'parent'			=> $parent,
2279
+                'expiration'		=> $expirationDate,
2280
+            );
2281
+
2282
+        }
2283
+
2284
+        $id = false;
2285
+        if ($isGroupShare) {
2286
+            $id = self::insertShare($queriesToExecute['groupShare']);
2287
+            // Save this id, any extra rows for this group share will need to reference it
2288
+            $parent = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
2289
+            unset($queriesToExecute['groupShare']);
2290
+        }
2291
+
2292
+        foreach ($queriesToExecute as $shareQuery) {
2293
+            $shareQuery['parent'] = $parent;
2294
+            $id = self::insertShare($shareQuery);
2295
+        }
2296
+
2297
+        $postHookData = array(
2298
+            'itemType' => $itemType,
2299
+            'itemSource' => $itemSource,
2300
+            'parent' => $parent,
2301
+            'shareType' => $shareType,
2302
+            'uidOwner' => $uidOwner,
2303
+            'permissions' => $permissions,
2304
+            'fileSource' => $fileSource,
2305
+            'id' => $parent,
2306
+            'token' => $token,
2307
+            'expirationDate' => $expirationDate,
2308
+        );
2309
+
2310
+        $postHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith;
2311
+        $postHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget;
2312
+        $postHookData['fileTarget'] = ($isGroupShare) ? $groupFileTarget : $fileTarget;
2313
+
2314
+        \OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
2315
+
2316
+
2317
+        return $id ? $id : false;
2318
+    }
2319
+
2320
+    /**
2321
+     * @param string $itemType
2322
+     * @param string $itemSource
2323
+     * @param int $shareType
2324
+     * @param string $shareWith
2325
+     * @param string $uidOwner
2326
+     * @param int $permissions
2327
+     * @param string|null $itemSourceName
2328
+     * @param null|\DateTime $expirationDate
2329
+     */
2330
+    private static function checkReshare($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $itemSourceName, $expirationDate) {
2331
+        $backend = self::getBackend($itemType);
2332
+
2333
+        $l = \OC::$server->getL10N('lib');
2334
+        $result = array();
2335
+
2336
+        $column = ($itemType === 'file' || $itemType === 'folder') ? 'file_source' : 'item_source';
2337
+
2338
+        $checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true);
2339
+        if ($checkReshare) {
2340
+            // Check if attempting to share back to owner
2341
+            if ($checkReshare['uid_owner'] == $shareWith && $shareType == self::SHARE_TYPE_USER) {
2342
+                $message = 'Sharing %s failed, because the user %s is the original sharer';
2343
+                $message_t = $l->t('Sharing failed, because the user %s is the original sharer', [$shareWith]);
2344
+
2345
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG);
2346
+                throw new \Exception($message_t);
2347
+            }
2348
+        }
2349
+
2350
+        if ($checkReshare && $checkReshare['uid_owner'] !== \OC_User::getUser()) {
2351
+            // Check if share permissions is granted
2352
+            if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & \OCP\Constants::PERMISSION_SHARE) {
2353
+                if (~(int)$checkReshare['permissions'] & $permissions) {
2354
+                    $message = 'Sharing %s failed, because the permissions exceed permissions granted to %s';
2355
+                    $message_t = $l->t('Sharing %s failed, because the permissions exceed permissions granted to %s', array($itemSourceName, $uidOwner));
2356
+
2357
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName, $uidOwner), \OCP\Util::DEBUG);
2358
+                    throw new \Exception($message_t);
2359
+                } else {
2360
+                    // TODO Don't check if inside folder
2361
+                    $result['parent'] = $checkReshare['id'];
2362
+
2363
+                    $result['expirationDate'] = $expirationDate;
2364
+                    // $checkReshare['expiration'] could be null and then is always less than any value
2365
+                    if(isset($checkReshare['expiration']) && $checkReshare['expiration'] < $expirationDate) {
2366
+                        $result['expirationDate'] = $checkReshare['expiration'];
2367
+                    }
2368
+
2369
+                    // only suggest the same name as new target if it is a reshare of the
2370
+                    // same file/folder and not the reshare of a child
2371
+                    if ($checkReshare[$column] === $itemSource) {
2372
+                        $result['filePath'] = $checkReshare['file_target'];
2373
+                        $result['itemSource'] = $checkReshare['item_source'];
2374
+                        $result['fileSource'] = $checkReshare['file_source'];
2375
+                        $result['suggestedItemTarget'] = $checkReshare['item_target'];
2376
+                        $result['suggestedFileTarget'] = $checkReshare['file_target'];
2377
+                    } else {
2378
+                        $result['filePath'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $backend->getFilePath($itemSource, $uidOwner) : null;
2379
+                        $result['suggestedItemTarget'] = null;
2380
+                        $result['suggestedFileTarget'] = null;
2381
+                        $result['itemSource'] = $itemSource;
2382
+                        $result['fileSource'] = ($backend instanceof \OCP\Share_Backend_File_Dependent) ? $itemSource : null;
2383
+                    }
2384
+                }
2385
+            } else {
2386
+                $message = 'Sharing %s failed, because resharing is not allowed';
2387
+                $message_t = $l->t('Sharing %s failed, because resharing is not allowed', array($itemSourceName));
2388
+
2389
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG);
2390
+                throw new \Exception($message_t);
2391
+            }
2392
+        } else {
2393
+            $result['parent'] = null;
2394
+            $result['suggestedItemTarget'] = null;
2395
+            $result['suggestedFileTarget'] = null;
2396
+            $result['itemSource'] = $itemSource;
2397
+            $result['expirationDate'] = $expirationDate;
2398
+            if (!$backend->isValidSource($itemSource, $uidOwner)) {
2399
+                $message = 'Sharing %s failed, because the sharing backend for '
2400
+                    .'%s could not find its source';
2401
+                $message_t = $l->t('Sharing %s failed, because the sharing backend for %s could not find its source', array($itemSource, $itemType));
2402
+                \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSource, $itemType), \OCP\Util::DEBUG);
2403
+                throw new \Exception($message_t);
2404
+            }
2405
+            if ($backend instanceof \OCP\Share_Backend_File_Dependent) {
2406
+                $result['filePath'] = $backend->getFilePath($itemSource, $uidOwner);
2407
+                if ($itemType == 'file' || $itemType == 'folder') {
2408
+                    $result['fileSource'] = $itemSource;
2409
+                } else {
2410
+                    $meta = \OC\Files\Filesystem::getFileInfo($result['filePath']);
2411
+                    $result['fileSource'] = $meta['fileid'];
2412
+                }
2413
+                if ($result['fileSource'] == -1) {
2414
+                    $message = 'Sharing %s failed, because the file could not be found in the file cache';
2415
+                    $message_t = $l->t('Sharing %s failed, because the file could not be found in the file cache', array($itemSource));
2416
+
2417
+                    \OCP\Util::writeLog('OCP\Share', sprintf($message, $itemSource), \OCP\Util::DEBUG);
2418
+                    throw new \Exception($message_t);
2419
+                }
2420
+            } else {
2421
+                $result['filePath'] = null;
2422
+                $result['fileSource'] = null;
2423
+            }
2424
+        }
2425
+
2426
+        return $result;
2427
+    }
2428
+
2429
+    /**
2430
+     *
2431
+     * @param array $shareData
2432
+     * @return mixed false in case of a failure or the id of the new share
2433
+     */
2434
+    private static function insertShare(array $shareData) {
2435
+
2436
+        $query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
2437
+            .' `item_type`, `item_source`, `item_target`, `share_type`,'
2438
+            .' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
2439
+            .' `file_target`, `token`, `parent`, `expiration`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)');
2440
+        $query->bindValue(1, $shareData['itemType']);
2441
+        $query->bindValue(2, $shareData['itemSource']);
2442
+        $query->bindValue(3, $shareData['itemTarget']);
2443
+        $query->bindValue(4, $shareData['shareType']);
2444
+        $query->bindValue(5, $shareData['shareWith']);
2445
+        $query->bindValue(6, $shareData['uidOwner']);
2446
+        $query->bindValue(7, $shareData['permissions']);
2447
+        $query->bindValue(8, $shareData['shareTime']);
2448
+        $query->bindValue(9, $shareData['fileSource']);
2449
+        $query->bindValue(10, $shareData['fileTarget']);
2450
+        $query->bindValue(11, $shareData['token']);
2451
+        $query->bindValue(12, $shareData['parent']);
2452
+        $query->bindValue(13, $shareData['expiration'], 'datetime');
2453
+        $result = $query->execute();
2454
+
2455
+        $id = false;
2456
+        if ($result) {
2457
+            $id =  \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share');
2458
+        }
2459
+
2460
+        return $id;
2461
+
2462
+    }
2463
+
2464
+    /**
2465
+     * Delete all shares with type SHARE_TYPE_LINK
2466
+     */
2467
+    public static function removeAllLinkShares() {
2468
+        // Delete any link shares
2469
+        $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*share` WHERE `share_type` = ?');
2470
+        $result = $query->execute(array(self::SHARE_TYPE_LINK));
2471
+        while ($item = $result->fetchRow()) {
2472
+            Helper::delete($item['id']);
2473
+        }
2474
+    }
2475
+
2476
+    /**
2477
+     * In case a password protected link is not yet authenticated this function will return false
2478
+     *
2479
+     * @param array $linkItem
2480
+     * @return boolean
2481
+     */
2482
+    public static function checkPasswordProtectedShare(array $linkItem) {
2483
+        if (!isset($linkItem['share_with'])) {
2484
+            return true;
2485
+        }
2486
+        if (!isset($linkItem['share_type'])) {
2487
+            return true;
2488
+        }
2489
+        if (!isset($linkItem['id'])) {
2490
+            return true;
2491
+        }
2492
+
2493
+        if ($linkItem['share_type'] != \OCP\Share::SHARE_TYPE_LINK) {
2494
+            return true;
2495
+        }
2496
+
2497
+        if ( \OC::$server->getSession()->exists('public_link_authenticated')
2498
+            && \OC::$server->getSession()->get('public_link_authenticated') === (string)$linkItem['id'] ) {
2499
+            return true;
2500
+        }
2501
+
2502
+        return false;
2503
+    }
2504
+
2505
+    /**
2506
+     * construct select statement
2507
+     * @param int $format
2508
+     * @param boolean $fileDependent ist it a file/folder share or a generla share
2509
+     * @param string $uidOwner
2510
+     * @return string select statement
2511
+     */
2512
+    private static function createSelectStatement($format, $fileDependent, $uidOwner = null) {
2513
+        $select = '*';
2514
+        if ($format == self::FORMAT_STATUSES) {
2515
+            if ($fileDependent) {
2516
+                $select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `storage`, '
2517
+                    . '`share_with`, `uid_owner` , `file_source`, `stime`, `*PREFIX*share`.`permissions`, '
2518
+                    . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`, '
2519
+                    . '`uid_initiator`';
2520
+            } else {
2521
+                $select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`';
2522
+            }
2523
+        } else {
2524
+            if (isset($uidOwner)) {
2525
+                if ($fileDependent) {
2526
+                    $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,'
2527
+                        . ' `share_type`, `share_with`, `file_source`, `file_target`, `path`, `*PREFIX*share`.`permissions`, `stime`,'
2528
+                        . ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`, '
2529
+                        . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`';
2530
+                } else {
2531
+                    $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,'
2532
+                        . ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`';
2533
+                }
2534
+            } else {
2535
+                if ($fileDependent) {
2536
+                    if ($format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) {
2537
+                        $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, '
2538
+                            . '`share_type`, `share_with`, `file_source`, `path`, `file_target`, `stime`, '
2539
+                            . '`*PREFIX*share`.`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, '
2540
+                            . '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`';
2541
+                    } else {
2542
+                        $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,'
2543
+                            . '`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,'
2544
+                            . '`file_source`, `path`, `file_target`, `*PREFIX*share`.`permissions`,'
2545
+                            . '`stime`, `expiration`, `token`, `storage`, `mail_send`,'
2546
+                            . '`*PREFIX*storages`.`id` AS `storage_id`, `*PREFIX*filecache`.`parent` as `file_parent`';
2547
+                    }
2548
+                }
2549
+            }
2550
+        }
2551
+        return $select;
2552
+    }
2553
+
2554
+
2555
+    /**
2556
+     * transform db results
2557
+     * @param array $row result
2558
+     */
2559
+    private static function transformDBResults(&$row) {
2560
+        if (isset($row['id'])) {
2561
+            $row['id'] = (int) $row['id'];
2562
+        }
2563
+        if (isset($row['share_type'])) {
2564
+            $row['share_type'] = (int) $row['share_type'];
2565
+        }
2566
+        if (isset($row['parent'])) {
2567
+            $row['parent'] = (int) $row['parent'];
2568
+        }
2569
+        if (isset($row['file_parent'])) {
2570
+            $row['file_parent'] = (int) $row['file_parent'];
2571
+        }
2572
+        if (isset($row['file_source'])) {
2573
+            $row['file_source'] = (int) $row['file_source'];
2574
+        }
2575
+        if (isset($row['permissions'])) {
2576
+            $row['permissions'] = (int) $row['permissions'];
2577
+        }
2578
+        if (isset($row['storage'])) {
2579
+            $row['storage'] = (int) $row['storage'];
2580
+        }
2581
+        if (isset($row['stime'])) {
2582
+            $row['stime'] = (int) $row['stime'];
2583
+        }
2584
+        if (isset($row['expiration']) && $row['share_type'] !== self::SHARE_TYPE_LINK) {
2585
+            // discard expiration date for non-link shares, which might have been
2586
+            // set by ancient bugs
2587
+            $row['expiration'] = null;
2588
+        }
2589
+    }
2590
+
2591
+    /**
2592
+     * format result
2593
+     * @param array $items result
2594
+     * @param string $column is it a file share or a general share ('file_target' or 'item_target')
2595
+     * @param \OCP\Share_Backend $backend sharing backend
2596
+     * @param int $format
2597
+     * @param array $parameters additional format parameters
2598
+     * @return array format result
2599
+     */
2600
+    private static function formatResult($items, $column, $backend, $format = self::FORMAT_NONE , $parameters = null) {
2601
+        if ($format === self::FORMAT_NONE) {
2602
+            return $items;
2603
+        } else if ($format === self::FORMAT_STATUSES) {
2604
+            $statuses = array();
2605
+            foreach ($items as $item) {
2606
+                if ($item['share_type'] === self::SHARE_TYPE_LINK) {
2607
+                    if ($item['uid_initiator'] !== \OC::$server->getUserSession()->getUser()->getUID()) {
2608
+                        continue;
2609
+                    }
2610
+                    $statuses[$item[$column]]['link'] = true;
2611
+                } else if (!isset($statuses[$item[$column]])) {
2612
+                    $statuses[$item[$column]]['link'] = false;
2613
+                }
2614
+                if (!empty($item['file_target'])) {
2615
+                    $statuses[$item[$column]]['path'] = $item['path'];
2616
+                }
2617
+            }
2618
+            return $statuses;
2619
+        } else {
2620
+            return $backend->formatItems($items, $format, $parameters);
2621
+        }
2622
+    }
2623
+
2624
+    /**
2625
+     * remove protocol from URL
2626
+     *
2627
+     * @param string $url
2628
+     * @return string
2629
+     */
2630
+    public static function removeProtocolFromUrl($url) {
2631
+        if (strpos($url, 'https://') === 0) {
2632
+            return substr($url, strlen('https://'));
2633
+        } else if (strpos($url, 'http://') === 0) {
2634
+            return substr($url, strlen('http://'));
2635
+        }
2636
+
2637
+        return $url;
2638
+    }
2639
+
2640
+    /**
2641
+     * try http post first with https and then with http as a fallback
2642
+     *
2643
+     * @param string $remoteDomain
2644
+     * @param string $urlSuffix
2645
+     * @param array $fields post parameters
2646
+     * @return array
2647
+     */
2648
+    private static function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) {
2649
+        $protocol = 'https://';
2650
+        $result = [
2651
+            'success' => false,
2652
+            'result' => '',
2653
+        ];
2654
+        $try = 0;
2655
+        $discoveryManager = new DiscoveryManager(
2656
+            \OC::$server->getMemCacheFactory(),
2657
+            \OC::$server->getHTTPClientService()
2658
+        );
2659
+        while ($result['success'] === false && $try < 2) {
2660
+            $endpoint = $discoveryManager->getShareEndpoint($protocol . $remoteDomain);
2661
+            $result = \OC::$server->getHTTPHelper()->post($protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, $fields);
2662
+            $try++;
2663
+            $protocol = 'http://';
2664
+        }
2665
+
2666
+        return $result;
2667
+    }
2668
+
2669
+    /**
2670
+     * send server-to-server share to remote server
2671
+     *
2672
+     * @param string $token
2673
+     * @param string $shareWith
2674
+     * @param string $name
2675
+     * @param int $remote_id
2676
+     * @param string $owner
2677
+     * @return bool
2678
+     */
2679
+    private static function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner) {
2680
+
2681
+        list($user, $remote) = Helper::splitUserRemote($shareWith);
2682
+
2683
+        if ($user && $remote) {
2684
+            $url = $remote;
2685
+
2686
+            $local = \OC::$server->getURLGenerator()->getAbsoluteURL('/');
2687
+
2688
+            $fields = array(
2689
+                'shareWith' => $user,
2690
+                'token' => $token,
2691
+                'name' => $name,
2692
+                'remoteId' => $remote_id,
2693
+                'owner' => $owner,
2694
+                'remote' => $local,
2695
+            );
2696
+
2697
+            $url = self::removeProtocolFromUrl($url);
2698
+            $result = self::tryHttpPostToShareEndpoint($url, '', $fields);
2699
+            $status = json_decode($result['result'], true);
2700
+
2701
+            if ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)) {
2702
+                \OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
2703
+                return true;
2704
+            }
2705
+
2706
+        }
2707
+
2708
+        return false;
2709
+    }
2710
+
2711
+    /**
2712
+     * send server-to-server unshare to remote server
2713
+     *
2714
+     * @param string $remote url
2715
+     * @param int $id share id
2716
+     * @param string $token
2717
+     * @return bool
2718
+     */
2719
+    private static function sendRemoteUnshare($remote, $id, $token) {
2720
+        $url = rtrim($remote, '/');
2721
+        $fields = array('token' => $token, 'format' => 'json');
2722
+        $url = self::removeProtocolFromUrl($url);
2723
+        $result = self::tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields);
2724
+        $status = json_decode($result['result'], true);
2725
+
2726
+        return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200));
2727
+    }
2728
+
2729
+    /**
2730
+     * check if user can only share with group members
2731
+     * @return bool
2732
+     */
2733
+    public static function shareWithGroupMembersOnly() {
2734
+        $value = \OC::$server->getAppConfig()->getValue('core', 'shareapi_only_share_with_group_members', 'no');
2735
+        return ($value === 'yes') ? true : false;
2736
+    }
2737
+
2738
+    /**
2739
+     * @return bool
2740
+     */
2741
+    public static function isDefaultExpireDateEnabled() {
2742
+        $defaultExpireDateEnabled = \OCP\Config::getAppValue('core', 'shareapi_default_expire_date', 'no');
2743
+        return ($defaultExpireDateEnabled === "yes") ? true : false;
2744
+    }
2745
+
2746
+    /**
2747
+     * @return bool
2748
+     */
2749
+    public static function enforceDefaultExpireDate() {
2750
+        $enforceDefaultExpireDate = \OCP\Config::getAppValue('core', 'shareapi_enforce_expire_date', 'no');
2751
+        return ($enforceDefaultExpireDate === "yes") ? true : false;
2752
+    }
2753
+
2754
+    /**
2755
+     * @return int
2756
+     */
2757
+    public static function getExpireInterval() {
2758
+        return (int)\OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
2759
+    }
2760
+
2761
+    /**
2762
+     * Checks whether the given path is reachable for the given owner
2763
+     *
2764
+     * @param string $path path relative to files
2765
+     * @param string $ownerStorageId storage id of the owner
2766
+     *
2767
+     * @return boolean true if file is reachable, false otherwise
2768
+     */
2769
+    private static function isFileReachable($path, $ownerStorageId) {
2770
+        // if outside the home storage, file is always considered reachable
2771
+        if (!(substr($ownerStorageId, 0, 6) === 'home::' ||
2772
+            substr($ownerStorageId, 0, 13) === 'object::user:'
2773
+        )) {
2774
+            return true;
2775
+        }
2776
+
2777
+        // if inside the home storage, the file has to be under "/files/"
2778
+        $path = ltrim($path, '/');
2779
+        if (substr($path, 0, 6) === 'files/') {
2780
+            return true;
2781
+        }
2782
+
2783
+        return false;
2784
+    }
2785
+
2786
+    /**
2787
+     * @param IConfig $config
2788
+     * @return bool 
2789
+     */
2790
+    public static function enforcePassword(IConfig $config) {
2791
+        $enforcePassword = $config->getAppValue('core', 'shareapi_enforce_links_password', 'no');
2792
+        return ($enforcePassword === "yes") ? true : false;
2793
+    }
2794
+
2795
+    /**
2796
+     * Get all share entries, including non-unique group items
2797
+     *
2798
+     * @param string $owner
2799
+     * @return array
2800
+     */
2801
+    public static function getAllSharesForOwner($owner) {
2802
+        $query = 'SELECT * FROM `*PREFIX*share` WHERE `uid_owner` = ?';
2803
+        $result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$owner]);
2804
+        return $result->fetchAll();
2805
+    }
2806
+
2807
+    /**
2808
+     * Get all share entries, including non-unique group items for a file
2809
+     *
2810
+     * @param int $id
2811
+     * @return array
2812
+     */
2813
+    public static function getAllSharesForFileId($id) {
2814
+        $query = 'SELECT * FROM `*PREFIX*share` WHERE `file_source` = ?';
2815
+        $result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$id]);
2816
+        return $result->fetchAll();
2817
+    }
2818
+
2819
+    /**
2820
+     * @param string $password
2821
+     * @throws \Exception
2822
+     */
2823
+    private static function verifyPassword($password) {
2824
+
2825
+        $accepted = true;
2826
+        $message = '';
2827
+        \OCP\Util::emitHook('\OC\Share', 'verifyPassword', [
2828
+            'password' => $password,
2829
+            'accepted' => &$accepted,
2830
+            'message' => &$message
2831
+        ]);
2832
+
2833
+        if (!$accepted) {
2834
+            throw new \Exception($message);
2835
+        }
2836
+    }
2837 2837
 }
Please login to merge, or discard this patch.
lib/private/Repair/AssetCache.php 2 patches
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -30,14 +30,14 @@
 block discarded – undo
30 30
 
31 31
 class AssetCache implements IRepairStep {
32 32
 
33
-	public function getName() {
34
-		return 'Remove asset cache';
35
-	}
33
+    public function getName() {
34
+        return 'Remove asset cache';
35
+    }
36 36
 
37
-	public function run(IOutput $output) {
38
-		$assetDir = \OC::$server->getConfig()->getSystemValue('assetdirectory', \OC::$SERVERROOT) . '/assets';
39
-		\OC_Helper::rmdirr($assetDir, false);
40
-		$output->info('Asset cache cleared.');
41
-	}
37
+    public function run(IOutput $output) {
38
+        $assetDir = \OC::$server->getConfig()->getSystemValue('assetdirectory', \OC::$SERVERROOT) . '/assets';
39
+        \OC_Helper::rmdirr($assetDir, false);
40
+        $output->info('Asset cache cleared.');
41
+    }
42 42
 }
43 43
 
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -35,7 +35,7 @@
 block discarded – undo
35 35
 	}
36 36
 
37 37
 	public function run(IOutput $output) {
38
-		$assetDir = \OC::$server->getConfig()->getSystemValue('assetdirectory', \OC::$SERVERROOT) . '/assets';
38
+		$assetDir = \OC::$server->getConfig()->getSystemValue('assetdirectory', \OC::$SERVERROOT).'/assets';
39 39
 		\OC_Helper::rmdirr($assetDir, false);
40 40
 		$output->info('Asset cache cleared.');
41 41
 	}
Please login to merge, or discard this patch.
lib/private/Repair/DropOldTables.php 2 patches
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -32,80 +32,80 @@
 block discarded – undo
32 32
 
33 33
 class DropOldTables implements IRepairStep {
34 34
 
35
-	/** @var IDBConnection */
36
-	protected $connection;
35
+    /** @var IDBConnection */
36
+    protected $connection;
37 37
 
38
-	/**
39
-	 * @param IDBConnection $connection
40
-	 */
41
-	public function __construct(IDBConnection $connection) {
42
-		$this->connection = $connection;
43
-	}
38
+    /**
39
+     * @param IDBConnection $connection
40
+     */
41
+    public function __construct(IDBConnection $connection) {
42
+        $this->connection = $connection;
43
+    }
44 44
 
45
-	/**
46
-	 * Returns the step's name
47
-	 *
48
-	 * @return string
49
-	 */
50
-	public function getName() {
51
-		return 'Drop old database tables';
52
-	}
45
+    /**
46
+     * Returns the step's name
47
+     *
48
+     * @return string
49
+     */
50
+    public function getName() {
51
+        return 'Drop old database tables';
52
+    }
53 53
 
54
-	/**
55
-	 * Run repair step.
56
-	 * Must throw exception on error.
57
-	 *
58
-	 * @throws \Exception in case of failure
59
-	 */
60
-	public function run(IOutput $output) {
61
-		$tables = $this->oldDatabaseTables();
62
-		$output->startProgress(count($tables));
63
-		foreach ($this->oldDatabaseTables() as $tableName) {
64
-			if ($this->connection->tableExists($tableName)){
65
-				$this->connection->dropTable($tableName);
66
-			}
67
-			$output->advance(1, "Drop old database table: $tableName");
68
-		}
69
-		$output->finishProgress();
70
-	}
54
+    /**
55
+     * Run repair step.
56
+     * Must throw exception on error.
57
+     *
58
+     * @throws \Exception in case of failure
59
+     */
60
+    public function run(IOutput $output) {
61
+        $tables = $this->oldDatabaseTables();
62
+        $output->startProgress(count($tables));
63
+        foreach ($this->oldDatabaseTables() as $tableName) {
64
+            if ($this->connection->tableExists($tableName)){
65
+                $this->connection->dropTable($tableName);
66
+            }
67
+            $output->advance(1, "Drop old database table: $tableName");
68
+        }
69
+        $output->finishProgress();
70
+    }
71 71
 
72
-	/**
73
-	 * Returns a list of outdated tables which are not used anymore
74
-	 * @return array
75
-	 */
76
-	protected function oldDatabaseTables() {
77
-		return [
78
-			'calendar_calendars',
79
-			'calendar_objects',
80
-			'calendar_share_calendar',
81
-			'calendar_share_event',
82
-			'file_map',
83
-			'foldersize',
84
-			'fscache',
85
-			'gallery_sharing',
86
-			'locks',
87
-			'log',
88
-			'media_albums',
89
-			'media_artists',
90
-			'media_sessions',
91
-			'media_songs',
92
-			'media_users',
93
-			'permissions',
94
-			'pictures_images_cache',
95
-			'principalgroups',
96
-			'principals',
97
-			'queuedtasks',
98
-			'sharing',
99
-			'clndr_calendars',
100
-			'clndr_objects',
101
-			'clndr_share_event',
102
-			'clndr_share_calendar',
103
-			'clndr_repeat',
104
-			'contacts_addressbooks',
105
-			'contacts_cards',
106
-			'contacts_cards_properties',
107
-			'gallery_albums',
108
-			'gallery_photos'
109
-		];
110
-	}
72
+    /**
73
+     * Returns a list of outdated tables which are not used anymore
74
+     * @return array
75
+     */
76
+    protected function oldDatabaseTables() {
77
+        return [
78
+            'calendar_calendars',
79
+            'calendar_objects',
80
+            'calendar_share_calendar',
81
+            'calendar_share_event',
82
+            'file_map',
83
+            'foldersize',
84
+            'fscache',
85
+            'gallery_sharing',
86
+            'locks',
87
+            'log',
88
+            'media_albums',
89
+            'media_artists',
90
+            'media_sessions',
91
+            'media_songs',
92
+            'media_users',
93
+            'permissions',
94
+            'pictures_images_cache',
95
+            'principalgroups',
96
+            'principals',
97
+            'queuedtasks',
98
+            'sharing',
99
+            'clndr_calendars',
100
+            'clndr_objects',
101
+            'clndr_share_event',
102
+            'clndr_share_calendar',
103
+            'clndr_repeat',
104
+            'contacts_addressbooks',
105
+            'contacts_cards',
106
+            'contacts_cards_properties',
107
+            'gallery_albums',
108
+            'gallery_photos'
109
+        ];
110
+    }
111 111
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -61,7 +61,7 @@
 block discarded – undo
61 61
 		$tables = $this->oldDatabaseTables();
62 62
 		$output->startProgress(count($tables));
63 63
 		foreach ($this->oldDatabaseTables() as $tableName) {
64
-			if ($this->connection->tableExists($tableName)){
64
+			if ($this->connection->tableExists($tableName)) {
65 65
 				$this->connection->dropTable($tableName);
66 66
 			}
67 67
 			$output->advance(1, "Drop old database table: $tableName");
Please login to merge, or discard this patch.
lib/private/Repair/UpdateCertificateStore.php 2 patches
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -37,54 +37,54 @@
 block discarded – undo
37 37
  * @package OC\Repair
38 38
  */
39 39
 class UpdateCertificateStore implements IRepairStep {
40
-	/**
41
-	 * FIXME: The certificate manager does only allow specifying the user
42
-	 *        within the constructor. This makes DI impossible.
43
-	 * @var Server
44
-	 */
45
-	protected $server;
46
-	/** @var IConfig */
47
-	protected $config;
40
+    /**
41
+     * FIXME: The certificate manager does only allow specifying the user
42
+     *        within the constructor. This makes DI impossible.
43
+     * @var Server
44
+     */
45
+    protected $server;
46
+    /** @var IConfig */
47
+    protected $config;
48 48
 
49
-	/**
50
-	 * @param Server $server
51
-	 * @param IConfig $config
52
-	 */
53
-	public function __construct(Server $server,
54
-								IConfig $config) {
55
-		$this->server = $server;
56
-		$this->config = $config;
57
-	}
49
+    /**
50
+     * @param Server $server
51
+     * @param IConfig $config
52
+     */
53
+    public function __construct(Server $server,
54
+                                IConfig $config) {
55
+        $this->server = $server;
56
+        $this->config = $config;
57
+    }
58 58
 
59
-	/** {@inheritDoc} */
60
-	public function getName() {
61
-		return 'Update user certificate stores with new root certificates';
62
-	}
59
+    /** {@inheritDoc} */
60
+    public function getName() {
61
+        return 'Update user certificate stores with new root certificates';
62
+    }
63 63
 
64
-	/** {@inheritDoc} */
65
-	public function run(IOutput $out) {
66
-		$rootView = new View();
67
-		$dataDirectory = $this->config->getSystemValue('datadirectory', null);
68
-		if(is_null($dataDirectory)) {
69
-			throw new \Exception('No data directory specified');
70
-		}
64
+    /** {@inheritDoc} */
65
+    public function run(IOutput $out) {
66
+        $rootView = new View();
67
+        $dataDirectory = $this->config->getSystemValue('datadirectory', null);
68
+        if(is_null($dataDirectory)) {
69
+            throw new \Exception('No data directory specified');
70
+        }
71 71
 
72
-		$pathToRootCerts = '/files_external/rootcerts.crt';
72
+        $pathToRootCerts = '/files_external/rootcerts.crt';
73 73
 
74
-		foreach($rootView->getDirectoryContent('', 'httpd/unix-directory') as $fileInfo) {
75
-			$uid = trim($fileInfo->getPath(), '/');
76
-			if($rootView->file_exists($uid . $pathToRootCerts)) {
77
-				// Delete the existing root certificate
78
-				$rootView->unlink($uid . $pathToRootCerts);
74
+        foreach($rootView->getDirectoryContent('', 'httpd/unix-directory') as $fileInfo) {
75
+            $uid = trim($fileInfo->getPath(), '/');
76
+            if($rootView->file_exists($uid . $pathToRootCerts)) {
77
+                // Delete the existing root certificate
78
+                $rootView->unlink($uid . $pathToRootCerts);
79 79
 
80
-				/**
81
-				 * FIXME: The certificate manager does only allow specifying the user
82
-				 *        within the constructor. This makes DI impossible.
83
-				 */
84
-				// Regenerate the certificates
85
-				$certificateManager = $this->server->getCertificateManager($uid);
86
-				$certificateManager->createCertificateBundle();
87
-			}
88
-		}
89
-	}
80
+                /**
81
+                 * FIXME: The certificate manager does only allow specifying the user
82
+                 *        within the constructor. This makes DI impossible.
83
+                 */
84
+                // Regenerate the certificates
85
+                $certificateManager = $this->server->getCertificateManager($uid);
86
+                $certificateManager->createCertificateBundle();
87
+            }
88
+        }
89
+    }
90 90
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -65,17 +65,17 @@
 block discarded – undo
65 65
 	public function run(IOutput $out) {
66 66
 		$rootView = new View();
67 67
 		$dataDirectory = $this->config->getSystemValue('datadirectory', null);
68
-		if(is_null($dataDirectory)) {
68
+		if (is_null($dataDirectory)) {
69 69
 			throw new \Exception('No data directory specified');
70 70
 		}
71 71
 
72 72
 		$pathToRootCerts = '/files_external/rootcerts.crt';
73 73
 
74
-		foreach($rootView->getDirectoryContent('', 'httpd/unix-directory') as $fileInfo) {
74
+		foreach ($rootView->getDirectoryContent('', 'httpd/unix-directory') as $fileInfo) {
75 75
 			$uid = trim($fileInfo->getPath(), '/');
76
-			if($rootView->file_exists($uid . $pathToRootCerts)) {
76
+			if ($rootView->file_exists($uid.$pathToRootCerts)) {
77 77
 				// Delete the existing root certificate
78
-				$rootView->unlink($uid . $pathToRootCerts);
78
+				$rootView->unlink($uid.$pathToRootCerts);
79 79
 
80 80
 				/**
81 81
 				 * FIXME: The certificate manager does only allow specifying the user
Please login to merge, or discard this patch.
lib/private/Repair/SharePropagation.php 2 patches
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -28,29 +28,29 @@
 block discarded – undo
28 28
 
29 29
 class SharePropagation implements IRepairStep {
30 30
 
31
-	/** @var  IConfig */
32
-	private $config;
31
+    /** @var  IConfig */
32
+    private $config;
33 33
 
34
-	/**
35
-	 * SharePropagation constructor.
36
-	 *
37
-	 * @param IConfig $config
38
-	 */
39
-	public function __construct(IConfig $config) {
40
-		$this->config = $config;
41
-	}
34
+    /**
35
+     * SharePropagation constructor.
36
+     *
37
+     * @param IConfig $config
38
+     */
39
+    public function __construct(IConfig $config) {
40
+        $this->config = $config;
41
+    }
42 42
 
43
-	public function getName() {
44
-		return 'Remove old share propagation app entries';
45
-	}
43
+    public function getName() {
44
+        return 'Remove old share propagation app entries';
45
+    }
46 46
 
47
-	public function run(IOutput $out ) {
48
-		$keys = $this->config->getAppKeys('files_sharing');
47
+    public function run(IOutput $out ) {
48
+        $keys = $this->config->getAppKeys('files_sharing');
49 49
 
50
-		foreach ($keys as $key) {
51
-			if (is_numeric($key)) {
52
-				$this->config->deleteAppValue('files_sharing', $key);
53
-			}
54
-		}
55
-	}
50
+        foreach ($keys as $key) {
51
+            if (is_numeric($key)) {
52
+                $this->config->deleteAppValue('files_sharing', $key);
53
+            }
54
+        }
55
+    }
56 56
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -44,7 +44,7 @@
 block discarded – undo
44 44
 		return 'Remove old share propagation app entries';
45 45
 	}
46 46
 
47
-	public function run(IOutput $out ) {
47
+	public function run(IOutput $out) {
48 48
 		$keys = $this->config->getAppKeys('files_sharing');
49 49
 
50 50
 		foreach ($keys as $key) {
Please login to merge, or discard this patch.