Completed
Pull Request — master (#9129)
by Joas
22:53
created
lib/private/HintException.php 2 patches
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -35,46 +35,46 @@
 block discarded – undo
35 35
  */
36 36
 class HintException extends \Exception {
37 37
 
38
-	private $hint;
38
+    private $hint;
39 39
 
40
-	/**
41
-	 * HintException constructor.
42
-	 *
43
-	 * @param string $message  The error message. It will be not revealed to the
44
-	 *                         the user (unless the hint is empty) and thus
45
-	 *                         should be not translated.
46
-	 * @param string $hint     A useful message that is presented to the end
47
-	 *                         user. It should be translated, but must not
48
-	 *                         contain sensitive data.
49
-	 * @param int $code
50
-	 * @param \Exception|null $previous
51
-	 */
52
-	public function __construct($message, $hint = '', $code = 0, \Exception $previous = null) {
53
-		$this->hint = $hint;
54
-		parent::__construct($message, $code, $previous);
55
-	}
40
+    /**
41
+     * HintException constructor.
42
+     *
43
+     * @param string $message  The error message. It will be not revealed to the
44
+     *                         the user (unless the hint is empty) and thus
45
+     *                         should be not translated.
46
+     * @param string $hint     A useful message that is presented to the end
47
+     *                         user. It should be translated, but must not
48
+     *                         contain sensitive data.
49
+     * @param int $code
50
+     * @param \Exception|null $previous
51
+     */
52
+    public function __construct($message, $hint = '', $code = 0, \Exception $previous = null) {
53
+        $this->hint = $hint;
54
+        parent::__construct($message, $code, $previous);
55
+    }
56 56
 
57
-	/**
58
-	 * Returns a string representation of this Exception that includes the error
59
-	 * code, the message and the hint.
60
-	 *
61
-	 * @return string
62
-	 */
63
-	public function __toString() {
64
-		return __CLASS__ . ": [{$this->code}]: {$this->message} ({$this->hint})\n";
65
-	}
57
+    /**
58
+     * Returns a string representation of this Exception that includes the error
59
+     * code, the message and the hint.
60
+     *
61
+     * @return string
62
+     */
63
+    public function __toString() {
64
+        return __CLASS__ . ": [{$this->code}]: {$this->message} ({$this->hint})\n";
65
+    }
66 66
 
67
-	/**
68
-	 * Returns the hint with the intention to be presented to the end user. If
69
-	 * an empty hint was specified upon instatiation, the message is returned
70
-	 * instead.
71
-	 *
72
-	 * @return string
73
-	 */
74
-	public function getHint() {
75
-		if (empty($this->hint)) {
76
-			return $this->message;
77
-		}
78
-		return $this->hint;
79
-	}
67
+    /**
68
+     * Returns the hint with the intention to be presented to the end user. If
69
+     * an empty hint was specified upon instatiation, the message is returned
70
+     * instead.
71
+     *
72
+     * @return string
73
+     */
74
+    public function getHint() {
75
+        if (empty($this->hint)) {
76
+            return $this->message;
77
+        }
78
+        return $this->hint;
79
+    }
80 80
 }
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
 	 * @return string
62 62
 	 */
63 63
 	public function __toString() {
64
-		return __CLASS__ . ": [{$this->code}]: {$this->message} ({$this->hint})\n";
64
+		return __CLASS__.": [{$this->code}]: {$this->message} ({$this->hint})\n";
65 65
 	}
66 66
 
67 67
 	/**
Please login to merge, or discard this patch.
lib/private/User/Backend.php 2 patches
Indentation   +120 added lines, -120 removed lines patch added patch discarded remove patch
@@ -29,136 +29,136 @@
 block discarded – undo
29 29
  * capabilities.
30 30
  */
31 31
 abstract class Backend implements UserInterface {
32
-	/**
33
-	 * error code for functions not provided by the user backend
34
-	 */
35
-	const NOT_IMPLEMENTED = -501;
32
+    /**
33
+     * error code for functions not provided by the user backend
34
+     */
35
+    const NOT_IMPLEMENTED = -501;
36 36
 
37
-	/**
38
-	 * actions that user backends can define
39
-	 */
40
-	const CREATE_USER		= 1;			// 1 << 0
41
-	const SET_PASSWORD		= 16;			// 1 << 4
42
-	const CHECK_PASSWORD	= 256;			// 1 << 8
43
-	const GET_HOME			= 4096;			// 1 << 12
44
-	const GET_DISPLAYNAME	= 65536;		// 1 << 16
45
-	const SET_DISPLAYNAME	= 1048576;		// 1 << 20
46
-	const PROVIDE_AVATAR	= 16777216;		// 1 << 24
47
-	const COUNT_USERS		= 268435456;	// 1 << 28
37
+    /**
38
+     * actions that user backends can define
39
+     */
40
+    const CREATE_USER		= 1;			// 1 << 0
41
+    const SET_PASSWORD		= 16;			// 1 << 4
42
+    const CHECK_PASSWORD	= 256;			// 1 << 8
43
+    const GET_HOME			= 4096;			// 1 << 12
44
+    const GET_DISPLAYNAME	= 65536;		// 1 << 16
45
+    const SET_DISPLAYNAME	= 1048576;		// 1 << 20
46
+    const PROVIDE_AVATAR	= 16777216;		// 1 << 24
47
+    const COUNT_USERS		= 268435456;	// 1 << 28
48 48
 
49
-	protected $possibleActions = array(
50
-		self::CREATE_USER => 'createUser',
51
-		self::SET_PASSWORD => 'setPassword',
52
-		self::CHECK_PASSWORD => 'checkPassword',
53
-		self::GET_HOME => 'getHome',
54
-		self::GET_DISPLAYNAME => 'getDisplayName',
55
-		self::SET_DISPLAYNAME => 'setDisplayName',
56
-		self::PROVIDE_AVATAR => 'canChangeAvatar',
57
-		self::COUNT_USERS => 'countUsers',
58
-	);
49
+    protected $possibleActions = array(
50
+        self::CREATE_USER => 'createUser',
51
+        self::SET_PASSWORD => 'setPassword',
52
+        self::CHECK_PASSWORD => 'checkPassword',
53
+        self::GET_HOME => 'getHome',
54
+        self::GET_DISPLAYNAME => 'getDisplayName',
55
+        self::SET_DISPLAYNAME => 'setDisplayName',
56
+        self::PROVIDE_AVATAR => 'canChangeAvatar',
57
+        self::COUNT_USERS => 'countUsers',
58
+    );
59 59
 
60
-	/**
61
-	* Get all supported actions
62
-	* @return int bitwise-or'ed actions
63
-	*
64
-	* Returns the supported actions as int to be
65
-	* compared with self::CREATE_USER etc.
66
-	*/
67
-	public function getSupportedActions() {
68
-		$actions = 0;
69
-		foreach($this->possibleActions AS $action => $methodName) {
70
-			if(method_exists($this, $methodName)) {
71
-				$actions |= $action;
72
-			}
73
-		}
60
+    /**
61
+     * Get all supported actions
62
+     * @return int bitwise-or'ed actions
63
+     *
64
+     * Returns the supported actions as int to be
65
+     * compared with self::CREATE_USER etc.
66
+     */
67
+    public function getSupportedActions() {
68
+        $actions = 0;
69
+        foreach($this->possibleActions AS $action => $methodName) {
70
+            if(method_exists($this, $methodName)) {
71
+                $actions |= $action;
72
+            }
73
+        }
74 74
 
75
-		return $actions;
76
-	}
75
+        return $actions;
76
+    }
77 77
 
78
-	/**
79
-	* Check if backend implements actions
80
-	* @param int $actions bitwise-or'ed actions
81
-	* @return boolean
82
-	*
83
-	* Returns the supported actions as int to be
84
-	* compared with self::CREATE_USER etc.
85
-	*/
86
-	public function implementsActions($actions) {
87
-		return (bool)($this->getSupportedActions() & $actions);
88
-	}
78
+    /**
79
+     * Check if backend implements actions
80
+     * @param int $actions bitwise-or'ed actions
81
+     * @return boolean
82
+     *
83
+     * Returns the supported actions as int to be
84
+     * compared with self::CREATE_USER etc.
85
+     */
86
+    public function implementsActions($actions) {
87
+        return (bool)($this->getSupportedActions() & $actions);
88
+    }
89 89
 
90
-	/**
91
-	 * delete a user
92
-	 * @param string $uid The username of the user to delete
93
-	 * @return bool
94
-	 *
95
-	 * Deletes a user
96
-	 */
97
-	public function deleteUser( $uid ) {
98
-		return false;
99
-	}
90
+    /**
91
+     * delete a user
92
+     * @param string $uid The username of the user to delete
93
+     * @return bool
94
+     *
95
+     * Deletes a user
96
+     */
97
+    public function deleteUser( $uid ) {
98
+        return false;
99
+    }
100 100
 
101
-	/**
102
-	 * Get a list of all users
103
-	 *
104
-	 * @param string $search
105
-	 * @param null|int $limit
106
-	 * @param null|int $offset
107
-	 * @return string[] an array of all uids
108
-	 */
109
-	public function getUsers($search = '', $limit = null, $offset = null) {
110
-		return array();
111
-	}
101
+    /**
102
+     * Get a list of all users
103
+     *
104
+     * @param string $search
105
+     * @param null|int $limit
106
+     * @param null|int $offset
107
+     * @return string[] an array of all uids
108
+     */
109
+    public function getUsers($search = '', $limit = null, $offset = null) {
110
+        return array();
111
+    }
112 112
 
113
-	/**
114
-	* check if a user exists
115
-	* @param string $uid the username
116
-	* @return boolean
117
-	*/
118
-	public function userExists($uid) {
119
-		return false;
120
-	}
113
+    /**
114
+     * check if a user exists
115
+     * @param string $uid the username
116
+     * @return boolean
117
+     */
118
+    public function userExists($uid) {
119
+        return false;
120
+    }
121 121
 
122
-	/**
123
-	* get the user's home directory
124
-	* @param string $uid the username
125
-	* @return boolean
126
-	*/
127
-	public function getHome($uid) {
128
-		return false;
129
-	}
122
+    /**
123
+     * get the user's home directory
124
+     * @param string $uid the username
125
+     * @return boolean
126
+     */
127
+    public function getHome($uid) {
128
+        return false;
129
+    }
130 130
 
131
-	/**
132
-	 * get display name of the user
133
-	 * @param string $uid user ID of the user
134
-	 * @return string display name
135
-	 */
136
-	public function getDisplayName($uid) {
137
-		return $uid;
138
-	}
131
+    /**
132
+     * get display name of the user
133
+     * @param string $uid user ID of the user
134
+     * @return string display name
135
+     */
136
+    public function getDisplayName($uid) {
137
+        return $uid;
138
+    }
139 139
 
140
-	/**
141
-	 * Get a list of all display names and user ids.
142
-	 *
143
-	 * @param string $search
144
-	 * @param string|null $limit
145
-	 * @param string|null $offset
146
-	 * @return array an array of all displayNames (value) and the corresponding uids (key)
147
-	 */
148
-	public function getDisplayNames($search = '', $limit = null, $offset = null) {
149
-		$displayNames = array();
150
-		$users = $this->getUsers($search, $limit, $offset);
151
-		foreach ( $users as $user) {
152
-			$displayNames[$user] = $user;
153
-		}
154
-		return $displayNames;
155
-	}
140
+    /**
141
+     * Get a list of all display names and user ids.
142
+     *
143
+     * @param string $search
144
+     * @param string|null $limit
145
+     * @param string|null $offset
146
+     * @return array an array of all displayNames (value) and the corresponding uids (key)
147
+     */
148
+    public function getDisplayNames($search = '', $limit = null, $offset = null) {
149
+        $displayNames = array();
150
+        $users = $this->getUsers($search, $limit, $offset);
151
+        foreach ( $users as $user) {
152
+            $displayNames[$user] = $user;
153
+        }
154
+        return $displayNames;
155
+    }
156 156
 
157
-	/**
158
-	 * Check if a user list is available or not
159
-	 * @return boolean if users can be listed or not
160
-	 */
161
-	public function hasUserListings() {
162
-		return false;
163
-	}
157
+    /**
158
+     * Check if a user list is available or not
159
+     * @return boolean if users can be listed or not
160
+     */
161
+    public function hasUserListings() {
162
+        return false;
163
+    }
164 164
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -37,14 +37,14 @@  discard block
 block discarded – undo
37 37
 	/**
38 38
 	 * actions that user backends can define
39 39
 	 */
40
-	const CREATE_USER		= 1;			// 1 << 0
41
-	const SET_PASSWORD		= 16;			// 1 << 4
42
-	const CHECK_PASSWORD	= 256;			// 1 << 8
43
-	const GET_HOME			= 4096;			// 1 << 12
44
-	const GET_DISPLAYNAME	= 65536;		// 1 << 16
45
-	const SET_DISPLAYNAME	= 1048576;		// 1 << 20
46
-	const PROVIDE_AVATAR	= 16777216;		// 1 << 24
47
-	const COUNT_USERS		= 268435456;	// 1 << 28
40
+	const CREATE_USER = 1; // 1 << 0
41
+	const SET_PASSWORD = 16; // 1 << 4
42
+	const CHECK_PASSWORD = 256; // 1 << 8
43
+	const GET_HOME = 4096; // 1 << 12
44
+	const GET_DISPLAYNAME	= 65536; // 1 << 16
45
+	const SET_DISPLAYNAME	= 1048576; // 1 << 20
46
+	const PROVIDE_AVATAR = 16777216; // 1 << 24
47
+	const COUNT_USERS = 268435456; // 1 << 28
48 48
 
49 49
 	protected $possibleActions = array(
50 50
 		self::CREATE_USER => 'createUser',
@@ -66,8 +66,8 @@  discard block
 block discarded – undo
66 66
 	*/
67 67
 	public function getSupportedActions() {
68 68
 		$actions = 0;
69
-		foreach($this->possibleActions AS $action => $methodName) {
70
-			if(method_exists($this, $methodName)) {
69
+		foreach ($this->possibleActions AS $action => $methodName) {
70
+			if (method_exists($this, $methodName)) {
71 71
 				$actions |= $action;
72 72
 			}
73 73
 		}
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
 	* compared with self::CREATE_USER etc.
85 85
 	*/
86 86
 	public function implementsActions($actions) {
87
-		return (bool)($this->getSupportedActions() & $actions);
87
+		return (bool) ($this->getSupportedActions() & $actions);
88 88
 	}
89 89
 
90 90
 	/**
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
 	 *
95 95
 	 * Deletes a user
96 96
 	 */
97
-	public function deleteUser( $uid ) {
97
+	public function deleteUser($uid) {
98 98
 		return false;
99 99
 	}
100 100
 
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
 	public function getDisplayNames($search = '', $limit = null, $offset = null) {
149 149
 		$displayNames = array();
150 150
 		$users = $this->getUsers($search, $limit, $offset);
151
-		foreach ( $users as $user) {
151
+		foreach ($users as $user) {
152 152
 			$displayNames[$user] = $user;
153 153
 		}
154 154
 		return $displayNames;
Please login to merge, or discard this patch.
lib/private/Diagnostics/Event.php 1 patch
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -26,79 +26,79 @@
 block discarded – undo
26 26
 use OCP\Diagnostics\IEvent;
27 27
 
28 28
 class Event implements IEvent {
29
-	/**
30
-	 * @var string
31
-	 */
32
-	protected $id;
29
+    /**
30
+     * @var string
31
+     */
32
+    protected $id;
33 33
 
34
-	/**
35
-	 * @var float
36
-	 */
37
-	protected $start;
34
+    /**
35
+     * @var float
36
+     */
37
+    protected $start;
38 38
 
39
-	/**
40
-	 * @var float
41
-	 */
42
-	protected $end;
39
+    /**
40
+     * @var float
41
+     */
42
+    protected $end;
43 43
 
44
-	/**
45
-	 * @var string
46
-	 */
47
-	protected $description;
44
+    /**
45
+     * @var string
46
+     */
47
+    protected $description;
48 48
 
49
-	/**
50
-	 * @param string $id
51
-	 * @param string $description
52
-	 * @param float $start
53
-	 */
54
-	public function __construct($id, $description, $start) {
55
-		$this->id = $id;
56
-		$this->description = $description;
57
-		$this->start = $start;
58
-	}
49
+    /**
50
+     * @param string $id
51
+     * @param string $description
52
+     * @param float $start
53
+     */
54
+    public function __construct($id, $description, $start) {
55
+        $this->id = $id;
56
+        $this->description = $description;
57
+        $this->start = $start;
58
+    }
59 59
 
60
-	/**
61
-	 * @param float $time
62
-	 */
63
-	public function end($time) {
64
-		$this->end = $time;
65
-	}
60
+    /**
61
+     * @param float $time
62
+     */
63
+    public function end($time) {
64
+        $this->end = $time;
65
+    }
66 66
 
67
-	/**
68
-	 * @return float
69
-	 */
70
-	public function getStart() {
71
-		return $this->start;
72
-	}
67
+    /**
68
+     * @return float
69
+     */
70
+    public function getStart() {
71
+        return $this->start;
72
+    }
73 73
 
74
-	/**
75
-	 * @return string
76
-	 */
77
-	public function getId() {
78
-		return $this->id;
79
-	}
74
+    /**
75
+     * @return string
76
+     */
77
+    public function getId() {
78
+        return $this->id;
79
+    }
80 80
 
81
-	/**
82
-	 * @return string
83
-	 */
84
-	public function getDescription() {
85
-		return $this->description;
86
-	}
81
+    /**
82
+     * @return string
83
+     */
84
+    public function getDescription() {
85
+        return $this->description;
86
+    }
87 87
 
88
-	/**
89
-	 * @return float
90
-	 */
91
-	public function getEnd() {
92
-		return $this->end;
93
-	}
88
+    /**
89
+     * @return float
90
+     */
91
+    public function getEnd() {
92
+        return $this->end;
93
+    }
94 94
 
95
-	/**
96
-	 * @return float
97
-	 */
98
-	public function getDuration() {
99
-		if (!$this->end) {
100
-			$this->end = microtime(true);
101
-		}
102
-		return $this->end - $this->start;
103
-	}
95
+    /**
96
+     * @return float
97
+     */
98
+    public function getDuration() {
99
+        if (!$this->end) {
100
+            $this->end = microtime(true);
101
+        }
102
+        return $this->end - $this->start;
103
+    }
104 104
 }
Please login to merge, or discard this patch.
lib/private/DateTimeZone.php 2 patches
Indentation   +86 added lines, -86 removed lines patch added patch discarded remove patch
@@ -29,100 +29,100 @@
 block discarded – undo
29 29
 use OCP\ISession;
30 30
 
31 31
 class DateTimeZone implements IDateTimeZone {
32
-	/** @var IConfig */
33
-	protected $config;
32
+    /** @var IConfig */
33
+    protected $config;
34 34
 
35
-	/** @var ISession */
36
-	protected $session;
35
+    /** @var ISession */
36
+    protected $session;
37 37
 
38
-	/**
39
-	 * Constructor
40
-	 *
41
-	 * @param IConfig $config
42
-	 * @param ISession $session
43
-	 */
44
-	public function __construct(IConfig $config, ISession $session) {
45
-		$this->config = $config;
46
-		$this->session = $session;
47
-	}
38
+    /**
39
+     * Constructor
40
+     *
41
+     * @param IConfig $config
42
+     * @param ISession $session
43
+     */
44
+    public function __construct(IConfig $config, ISession $session) {
45
+        $this->config = $config;
46
+        $this->session = $session;
47
+    }
48 48
 
49
-	/**
50
-	 * Get the timezone of the current user, based on his session information and config data
51
-	 *
52
-	 * @param bool|int $timestamp
53
-	 * @return \DateTimeZone
54
-	 */
55
-	public function getTimeZone($timestamp = false) {
56
-		$timeZone = $this->config->getUserValue($this->session->get('user_id'), 'core', 'timezone', null);
57
-		if ($timeZone === null) {
58
-			if ($this->session->exists('timezone')) {
59
-				return $this->guessTimeZoneFromOffset($this->session->get('timezone'), $timestamp);
60
-			}
61
-			$timeZone = $this->getDefaultTimeZone();
62
-		}
49
+    /**
50
+     * Get the timezone of the current user, based on his session information and config data
51
+     *
52
+     * @param bool|int $timestamp
53
+     * @return \DateTimeZone
54
+     */
55
+    public function getTimeZone($timestamp = false) {
56
+        $timeZone = $this->config->getUserValue($this->session->get('user_id'), 'core', 'timezone', null);
57
+        if ($timeZone === null) {
58
+            if ($this->session->exists('timezone')) {
59
+                return $this->guessTimeZoneFromOffset($this->session->get('timezone'), $timestamp);
60
+            }
61
+            $timeZone = $this->getDefaultTimeZone();
62
+        }
63 63
 
64
-		try {
65
-			return new \DateTimeZone($timeZone);
66
-		} catch (\Exception $e) {
67
-			\OCP\Util::writeLog('datetimezone', 'Failed to created DateTimeZone "' . $timeZone . "'", \OCP\Util::DEBUG);
68
-			return new \DateTimeZone($this->getDefaultTimeZone());
69
-		}
70
-	}
64
+        try {
65
+            return new \DateTimeZone($timeZone);
66
+        } catch (\Exception $e) {
67
+            \OCP\Util::writeLog('datetimezone', 'Failed to created DateTimeZone "' . $timeZone . "'", \OCP\Util::DEBUG);
68
+            return new \DateTimeZone($this->getDefaultTimeZone());
69
+        }
70
+    }
71 71
 
72
-	/**
73
-	 * Guess the DateTimeZone for a given offset
74
-	 *
75
-	 * We first try to find a Etc/GMT* timezone, if that does not exist,
76
-	 * we try to find it manually, before falling back to UTC.
77
-	 *
78
-	 * @param mixed $offset
79
-	 * @param bool|int $timestamp
80
-	 * @return \DateTimeZone
81
-	 */
82
-	protected function guessTimeZoneFromOffset($offset, $timestamp) {
83
-		try {
84
-			// Note: the timeZone name is the inverse to the offset,
85
-			// so a positive offset means negative timeZone
86
-			// and the other way around.
87
-			if ($offset > 0) {
88
-				$timeZone = 'Etc/GMT-' . $offset;
89
-			} else {
90
-				$timeZone = 'Etc/GMT+' . abs($offset);
91
-			}
72
+    /**
73
+     * Guess the DateTimeZone for a given offset
74
+     *
75
+     * We first try to find a Etc/GMT* timezone, if that does not exist,
76
+     * we try to find it manually, before falling back to UTC.
77
+     *
78
+     * @param mixed $offset
79
+     * @param bool|int $timestamp
80
+     * @return \DateTimeZone
81
+     */
82
+    protected function guessTimeZoneFromOffset($offset, $timestamp) {
83
+        try {
84
+            // Note: the timeZone name is the inverse to the offset,
85
+            // so a positive offset means negative timeZone
86
+            // and the other way around.
87
+            if ($offset > 0) {
88
+                $timeZone = 'Etc/GMT-' . $offset;
89
+            } else {
90
+                $timeZone = 'Etc/GMT+' . abs($offset);
91
+            }
92 92
 
93
-			return new \DateTimeZone($timeZone);
94
-		} catch (\Exception $e) {
95
-			// If the offset has no Etc/GMT* timezone,
96
-			// we try to guess one timezone that has the same offset
97
-			foreach (\DateTimeZone::listIdentifiers() as $timeZone) {
98
-				$dtz = new \DateTimeZone($timeZone);
99
-				$dateTime = new \DateTime();
93
+            return new \DateTimeZone($timeZone);
94
+        } catch (\Exception $e) {
95
+            // If the offset has no Etc/GMT* timezone,
96
+            // we try to guess one timezone that has the same offset
97
+            foreach (\DateTimeZone::listIdentifiers() as $timeZone) {
98
+                $dtz = new \DateTimeZone($timeZone);
99
+                $dateTime = new \DateTime();
100 100
 
101
-				if ($timestamp !== false) {
102
-					$dateTime->setTimestamp($timestamp);
103
-				}
101
+                if ($timestamp !== false) {
102
+                    $dateTime->setTimestamp($timestamp);
103
+                }
104 104
 
105
-				$dtOffset = $dtz->getOffset($dateTime);
106
-				if ($dtOffset == 3600 * $offset) {
107
-					return $dtz;
108
-				}
109
-			}
105
+                $dtOffset = $dtz->getOffset($dateTime);
106
+                if ($dtOffset == 3600 * $offset) {
107
+                    return $dtz;
108
+                }
109
+            }
110 110
 
111
-			// No timezone found, fallback to UTC
112
-			\OCP\Util::writeLog('datetimezone', 'Failed to find DateTimeZone for offset "' . $offset . "'", \OCP\Util::DEBUG);
113
-			return new \DateTimeZone($this->getDefaultTimeZone());
114
-		}
115
-	}
111
+            // No timezone found, fallback to UTC
112
+            \OCP\Util::writeLog('datetimezone', 'Failed to find DateTimeZone for offset "' . $offset . "'", \OCP\Util::DEBUG);
113
+            return new \DateTimeZone($this->getDefaultTimeZone());
114
+        }
115
+    }
116 116
 
117
-	/**
118
-	 * Get the default timezone of the server
119
-	 *
120
-	 * Falls back to UTC if it is not yet set.
121
-	 * 
122
-	 * @return string
123
-	 */
124
-	protected function getDefaultTimeZone() {
125
-		$serverTimeZone = date_default_timezone_get();
126
-		return $serverTimeZone ?: 'UTC';
127
-	}
117
+    /**
118
+     * Get the default timezone of the server
119
+     *
120
+     * Falls back to UTC if it is not yet set.
121
+     * 
122
+     * @return string
123
+     */
124
+    protected function getDefaultTimeZone() {
125
+        $serverTimeZone = date_default_timezone_get();
126
+        return $serverTimeZone ?: 'UTC';
127
+    }
128 128
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
 		try {
65 65
 			return new \DateTimeZone($timeZone);
66 66
 		} catch (\Exception $e) {
67
-			\OCP\Util::writeLog('datetimezone', 'Failed to created DateTimeZone "' . $timeZone . "'", \OCP\Util::DEBUG);
67
+			\OCP\Util::writeLog('datetimezone', 'Failed to created DateTimeZone "'.$timeZone."'", \OCP\Util::DEBUG);
68 68
 			return new \DateTimeZone($this->getDefaultTimeZone());
69 69
 		}
70 70
 	}
@@ -85,9 +85,9 @@  discard block
 block discarded – undo
85 85
 			// so a positive offset means negative timeZone
86 86
 			// and the other way around.
87 87
 			if ($offset > 0) {
88
-				$timeZone = 'Etc/GMT-' . $offset;
88
+				$timeZone = 'Etc/GMT-'.$offset;
89 89
 			} else {
90
-				$timeZone = 'Etc/GMT+' . abs($offset);
90
+				$timeZone = 'Etc/GMT+'.abs($offset);
91 91
 			}
92 92
 
93 93
 			return new \DateTimeZone($timeZone);
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
 			}
110 110
 
111 111
 			// No timezone found, fallback to UTC
112
-			\OCP\Util::writeLog('datetimezone', 'Failed to find DateTimeZone for offset "' . $offset . "'", \OCP\Util::DEBUG);
112
+			\OCP\Util::writeLog('datetimezone', 'Failed to find DateTimeZone for offset "'.$offset."'", \OCP\Util::DEBUG);
113 113
 			return new \DateTimeZone($this->getDefaultTimeZone());
114 114
 		}
115 115
 	}
Please login to merge, or discard this patch.
lib/private/Tagging/TagMapper.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -50,12 +50,12 @@  discard block
 block discarded – undo
50 50
 	* @return array An array of Tag objects.
51 51
 	*/
52 52
 	public function loadTags($owners, $type) {
53
-		if(!is_array($owners)) {
53
+		if (!is_array($owners)) {
54 54
 			$owners = array($owners);
55 55
 		}
56 56
 
57
-		$sql = 'SELECT `id`, `uid`, `type`, `category` FROM `' . $this->getTableName() . '` '
58
-			. 'WHERE `uid` IN (' . str_repeat('?,', count($owners)-1) . '?) AND `type` = ? ORDER BY `category`';
57
+		$sql = 'SELECT `id`, `uid`, `type`, `category` FROM `'.$this->getTableName().'` '
58
+			. 'WHERE `uid` IN ('.str_repeat('?,', count($owners) - 1).'?) AND `type` = ? ORDER BY `category`';
59 59
 		return $this->findEntities($sql, array_merge($owners, array($type)));
60 60
 	}
61 61
 
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
 	* @return bool
67 67
 	*/
68 68
 	public function tagExists($tag) {
69
-		$sql = 'SELECT `id`, `uid`, `type`, `category` FROM `' . $this->getTableName() . '` '
69
+		$sql = 'SELECT `id`, `uid`, `type`, `category` FROM `'.$this->getTableName().'` '
70 70
 			. 'WHERE `uid` = ? AND `type` = ? AND `category` = ?';
71 71
 		try {
72 72
 			$this->findEntity($sql, array($tag->getOwner(), $tag->getType(), $tag->getName()));
Please login to merge, or discard this patch.
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -33,47 +33,47 @@
 block discarded – undo
33 33
  */
34 34
 class TagMapper extends Mapper {
35 35
 
36
-	/**
37
-	* Constructor.
38
-	*
39
-	* @param IDBConnection $db Instance of the Db abstraction layer.
40
-	*/
41
-	public function __construct(IDBConnection $db) {
42
-		parent::__construct($db, 'vcategory', Tag::class);
43
-	}
36
+    /**
37
+     * Constructor.
38
+     *
39
+     * @param IDBConnection $db Instance of the Db abstraction layer.
40
+     */
41
+    public function __construct(IDBConnection $db) {
42
+        parent::__construct($db, 'vcategory', Tag::class);
43
+    }
44 44
 
45
-	/**
46
-	* Load tags from the database.
47
-	*
48
-	* @param array|string $owners The user(s) whose tags we are going to load.
49
-	* @param string $type The type of item for which we are loading tags.
50
-	* @return array An array of Tag objects.
51
-	*/
52
-	public function loadTags($owners, $type) {
53
-		if(!is_array($owners)) {
54
-			$owners = array($owners);
55
-		}
45
+    /**
46
+     * Load tags from the database.
47
+     *
48
+     * @param array|string $owners The user(s) whose tags we are going to load.
49
+     * @param string $type The type of item for which we are loading tags.
50
+     * @return array An array of Tag objects.
51
+     */
52
+    public function loadTags($owners, $type) {
53
+        if(!is_array($owners)) {
54
+            $owners = array($owners);
55
+        }
56 56
 
57
-		$sql = 'SELECT `id`, `uid`, `type`, `category` FROM `' . $this->getTableName() . '` '
58
-			. 'WHERE `uid` IN (' . str_repeat('?,', count($owners)-1) . '?) AND `type` = ? ORDER BY `category`';
59
-		return $this->findEntities($sql, array_merge($owners, array($type)));
60
-	}
57
+        $sql = 'SELECT `id`, `uid`, `type`, `category` FROM `' . $this->getTableName() . '` '
58
+            . 'WHERE `uid` IN (' . str_repeat('?,', count($owners)-1) . '?) AND `type` = ? ORDER BY `category`';
59
+        return $this->findEntities($sql, array_merge($owners, array($type)));
60
+    }
61 61
 
62
-	/**
63
-	* Check if a given Tag object already exists in the database.
64
-	*
65
-	* @param Tag $tag The tag to look for in the database.
66
-	* @return bool
67
-	*/
68
-	public function tagExists($tag) {
69
-		$sql = 'SELECT `id`, `uid`, `type`, `category` FROM `' . $this->getTableName() . '` '
70
-			. 'WHERE `uid` = ? AND `type` = ? AND `category` = ?';
71
-		try {
72
-			$this->findEntity($sql, array($tag->getOwner(), $tag->getType(), $tag->getName()));
73
-		} catch (DoesNotExistException $e) {
74
-			return false;
75
-		}
76
-		return true;
77
-	}
62
+    /**
63
+     * Check if a given Tag object already exists in the database.
64
+     *
65
+     * @param Tag $tag The tag to look for in the database.
66
+     * @return bool
67
+     */
68
+    public function tagExists($tag) {
69
+        $sql = 'SELECT `id`, `uid`, `type`, `category` FROM `' . $this->getTableName() . '` '
70
+            . 'WHERE `uid` = ? AND `type` = ? AND `category` = ?';
71
+        try {
72
+            $this->findEntity($sql, array($tag->getOwner(), $tag->getType(), $tag->getName()));
73
+        } catch (DoesNotExistException $e) {
74
+            return false;
75
+        }
76
+        return true;
77
+    }
78 78
 }
79 79
 
Please login to merge, or discard this patch.
lib/private/Tagging/Tag.php 2 patches
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -37,54 +37,54 @@
 block discarded – undo
37 37
  */
38 38
 class Tag extends Entity {
39 39
 
40
-	protected $owner;
41
-	protected $type;
42
-	protected $name;
40
+    protected $owner;
41
+    protected $type;
42
+    protected $name;
43 43
 
44
-	/**
45
-	* Constructor.
46
-	*
47
-	* @param string $owner The tag's owner
48
-	* @param string $type The type of item this tag is used for
49
-	* @param string $name The tag's name
50
-	*/
51
-	public function __construct($owner = null, $type = null, $name = null) {
52
-		$this->setOwner($owner);
53
-		$this->setType($type);
54
-		$this->setName($name);
55
-	}
44
+    /**
45
+     * Constructor.
46
+     *
47
+     * @param string $owner The tag's owner
48
+     * @param string $type The type of item this tag is used for
49
+     * @param string $name The tag's name
50
+     */
51
+    public function __construct($owner = null, $type = null, $name = null) {
52
+        $this->setOwner($owner);
53
+        $this->setType($type);
54
+        $this->setName($name);
55
+    }
56 56
 
57
-	/**
58
-	 * Transform a database columnname to a property
59
-	 *
60
-	 * @param string $columnName the name of the column
61
-	 * @return string the property name
62
-	 * @todo migrate existing database columns to the correct names
63
-	 * to be able to drop this direct mapping
64
-	 */
65
-	public function columnToProperty($columnName){
66
-		if ($columnName === 'category') {
67
-		    return 'name';
68
-		} elseif ($columnName === 'uid') {
69
-		    return 'owner';
70
-		} else {
71
-		    return parent::columnToProperty($columnName);
72
-		}
73
-	}
57
+    /**
58
+     * Transform a database columnname to a property
59
+     *
60
+     * @param string $columnName the name of the column
61
+     * @return string the property name
62
+     * @todo migrate existing database columns to the correct names
63
+     * to be able to drop this direct mapping
64
+     */
65
+    public function columnToProperty($columnName){
66
+        if ($columnName === 'category') {
67
+            return 'name';
68
+        } elseif ($columnName === 'uid') {
69
+            return 'owner';
70
+        } else {
71
+            return parent::columnToProperty($columnName);
72
+        }
73
+    }
74 74
 
75
-	/**
76
-	 * Transform a property to a database column name
77
-	 *
78
-	 * @param string $property the name of the property
79
-	 * @return string the column name
80
-	 */
81
-	public function propertyToColumn($property){
82
-		if ($property === 'name') {
83
-		    return 'category';
84
-		} elseif ($property === 'owner') {
85
-		    return 'uid';
86
-		} else {
87
-		    return parent::propertyToColumn($property);
88
-		}
89
-	}
75
+    /**
76
+     * Transform a property to a database column name
77
+     *
78
+     * @param string $property the name of the property
79
+     * @return string the column name
80
+     */
81
+    public function propertyToColumn($property){
82
+        if ($property === 'name') {
83
+            return 'category';
84
+        } elseif ($property === 'owner') {
85
+            return 'uid';
86
+        } else {
87
+            return parent::propertyToColumn($property);
88
+        }
89
+    }
90 90
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -62,7 +62,7 @@  discard block
 block discarded – undo
62 62
 	 * @todo migrate existing database columns to the correct names
63 63
 	 * to be able to drop this direct mapping
64 64
 	 */
65
-	public function columnToProperty($columnName){
65
+	public function columnToProperty($columnName) {
66 66
 		if ($columnName === 'category') {
67 67
 		    return 'name';
68 68
 		} elseif ($columnName === 'uid') {
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
 	 * @param string $property the name of the property
79 79
 	 * @return string the column name
80 80
 	 */
81
-	public function propertyToColumn($property){
81
+	public function propertyToColumn($property) {
82 82
 		if ($property === 'name') {
83 83
 		    return 'category';
84 84
 		} elseif ($property === 'owner') {
Please login to merge, or discard this patch.
lib/private/TagManager.php 1 patch
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -40,53 +40,53 @@
 block discarded – undo
40 40
 
41 41
 class TagManager implements \OCP\ITagManager {
42 42
 
43
-	/**
44
-	 * User session
45
-	 *
46
-	 * @var \OCP\IUserSession
47
-	 */
48
-	private $userSession;
43
+    /**
44
+     * User session
45
+     *
46
+     * @var \OCP\IUserSession
47
+     */
48
+    private $userSession;
49 49
 
50
-	/**
51
-	 * TagMapper
52
-	 *
53
-	 * @var TagMapper
54
-	 */
55
-	private $mapper;
50
+    /**
51
+     * TagMapper
52
+     *
53
+     * @var TagMapper
54
+     */
55
+    private $mapper;
56 56
 
57
-	/**
58
-	* Constructor.
59
-	*
60
-	* @param TagMapper $mapper Instance of the TagMapper abstraction layer.
61
-	* @param \OCP\IUserSession $userSession the user session
62
-	*/
63
-	public function __construct(TagMapper $mapper, \OCP\IUserSession $userSession) {
64
-		$this->mapper = $mapper;
65
-		$this->userSession = $userSession;
57
+    /**
58
+     * Constructor.
59
+     *
60
+     * @param TagMapper $mapper Instance of the TagMapper abstraction layer.
61
+     * @param \OCP\IUserSession $userSession the user session
62
+     */
63
+    public function __construct(TagMapper $mapper, \OCP\IUserSession $userSession) {
64
+        $this->mapper = $mapper;
65
+        $this->userSession = $userSession;
66 66
 
67
-	}
67
+    }
68 68
 
69
-	/**
70
-	* Create a new \OCP\ITags instance and load tags from db.
71
-	*
72
-	* @see \OCP\ITags
73
-	* @param string $type The type identifier e.g. 'contact' or 'event'.
74
-	* @param array $defaultTags An array of default tags to be used if none are stored.
75
-	* @param boolean $includeShared Whether to include tags for items shared with this user by others.
76
-	* @param string $userId user for which to retrieve the tags, defaults to the currently
77
-	* logged in user
78
-	* @return \OCP\ITags
79
-	*/
80
-	public function load($type, $defaultTags = array(), $includeShared = false, $userId = null) {
81
-		if (is_null($userId)) {
82
-			$user = $this->userSession->getUser();
83
-			if ($user === null) {
84
-				// nothing we can do without a user
85
-				return null;
86
-			}
87
-			$userId = $this->userSession->getUser()->getUId();
88
-		}
89
-		return new Tags($this->mapper, $userId, $type, $defaultTags, $includeShared);
90
-	}
69
+    /**
70
+     * Create a new \OCP\ITags instance and load tags from db.
71
+     *
72
+     * @see \OCP\ITags
73
+     * @param string $type The type identifier e.g. 'contact' or 'event'.
74
+     * @param array $defaultTags An array of default tags to be used if none are stored.
75
+     * @param boolean $includeShared Whether to include tags for items shared with this user by others.
76
+     * @param string $userId user for which to retrieve the tags, defaults to the currently
77
+     * logged in user
78
+     * @return \OCP\ITags
79
+     */
80
+    public function load($type, $defaultTags = array(), $includeShared = false, $userId = null) {
81
+        if (is_null($userId)) {
82
+            $user = $this->userSession->getUser();
83
+            if ($user === null) {
84
+                // nothing we can do without a user
85
+                return null;
86
+            }
87
+            $userId = $this->userSession->getUser()->getUId();
88
+        }
89
+        return new Tags($this->mapper, $userId, $type, $defaultTags, $includeShared);
90
+    }
91 91
 
92 92
 }
Please login to merge, or discard this patch.
lib/private/ContactsManager.php 2 patches
Indentation   +160 added lines, -160 removed lines patch added patch discarded remove patch
@@ -27,164 +27,164 @@
 block discarded – undo
27 27
 
28 28
 namespace OC {
29 29
 
30
-	class ContactsManager implements \OCP\Contacts\IManager {
31
-
32
-		/**
33
-		 * This function is used to search and find contacts within the users address books.
34
-		 * In case $pattern is empty all contacts will be returned.
35
-		 *
36
-		 * @param string $pattern which should match within the $searchProperties
37
-		 * @param array $searchProperties defines the properties within the query pattern should match
38
-		 * @param array $options - for future use. One should always have options!
39
-		 * @return array an array of contacts which are arrays of key-value-pairs
40
-		 */
41
-		public function search($pattern, $searchProperties = array(), $options = array()) {
42
-			$this->loadAddressBooks();
43
-			$result = array();
44
-			foreach($this->addressBooks as $addressBook) {
45
-				$r = $addressBook->search($pattern, $searchProperties, $options);
46
-				$contacts = array();
47
-				foreach($r as $c){
48
-					$c['addressbook-key'] = $addressBook->getKey();
49
-					$contacts[] = $c;
50
-				}
51
-				$result = array_merge($result, $contacts);
52
-			}
53
-
54
-			return $result;
55
-		}
56
-
57
-		/**
58
-		 * This function can be used to delete the contact identified by the given id
59
-		 *
60
-		 * @param object $id the unique identifier to a contact
61
-		 * @param string $addressBookKey identifier of the address book in which the contact shall be deleted
62
-		 * @return bool successful or not
63
-		 */
64
-		public function delete($id, $addressBookKey) {
65
-			$addressBook = $this->getAddressBook($addressBookKey);
66
-			if (!$addressBook) {
67
-				return null;
68
-			}
69
-
70
-			if ($addressBook->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
71
-				return $addressBook->delete($id);
72
-			}
73
-
74
-			return null;
75
-		}
76
-
77
-		/**
78
-		 * This function is used to create a new contact if 'id' is not given or not present.
79
-		 * Otherwise the contact will be updated by replacing the entire data set.
80
-		 *
81
-		 * @param array $properties this array if key-value-pairs defines a contact
82
-		 * @param string $addressBookKey identifier of the address book in which the contact shall be created or updated
83
-		 * @return array representing the contact just created or updated
84
-		 */
85
-		public function createOrUpdate($properties, $addressBookKey) {
86
-			$addressBook = $this->getAddressBook($addressBookKey);
87
-			if (!$addressBook) {
88
-				return null;
89
-			}
90
-
91
-			if ($addressBook->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
92
-				return $addressBook->createOrUpdate($properties);
93
-			}
94
-
95
-			return null;
96
-		}
97
-
98
-		/**
99
-		 * Check if contacts are available (e.g. contacts app enabled)
100
-		 *
101
-		 * @return bool true if enabled, false if not
102
-		 */
103
-		public function isEnabled() {
104
-			return !empty($this->addressBooks) || !empty($this->addressBookLoaders);
105
-		}
106
-
107
-		/**
108
-		 * @param \OCP\IAddressBook $addressBook
109
-		 */
110
-		public function registerAddressBook(\OCP\IAddressBook $addressBook) {
111
-			$this->addressBooks[$addressBook->getKey()] = $addressBook;
112
-		}
113
-
114
-		/**
115
-		 * @param \OCP\IAddressBook $addressBook
116
-		 */
117
-		public function unregisterAddressBook(\OCP\IAddressBook $addressBook) {
118
-			unset($this->addressBooks[$addressBook->getKey()]);
119
-		}
120
-
121
-		/**
122
-		 * @return array
123
-		 */
124
-		public function getAddressBooks() {
125
-			$this->loadAddressBooks();
126
-			$result = array();
127
-			foreach($this->addressBooks as $addressBook) {
128
-				$result[$addressBook->getKey()] = $addressBook->getDisplayName();
129
-			}
130
-
131
-			return $result;
132
-		}
133
-
134
-		/**
135
-		 * removes all registered address book instances
136
-		 */
137
-		public function clear() {
138
-			$this->addressBooks = array();
139
-			$this->addressBookLoaders = array();
140
-		}
141
-
142
-		/**
143
-		 * @var \OCP\IAddressBook[] which holds all registered address books
144
-		 */
145
-		private $addressBooks = array();
146
-
147
-		/**
148
-		 * @var \Closure[] to call to load/register address books
149
-		 */
150
-		private $addressBookLoaders = array();
151
-
152
-		/**
153
-		 * In order to improve lazy loading a closure can be registered which will be called in case
154
-		 * address books are actually requested
155
-		 *
156
-		 * @param \Closure $callable
157
-		 */
158
-		public function register(\Closure $callable)
159
-		{
160
-			$this->addressBookLoaders[] = $callable;
161
-		}
162
-
163
-		/**
164
-		 * Get (and load when needed) the address book for $key
165
-		 *
166
-		 * @param string $addressBookKey
167
-		 * @return \OCP\IAddressBook
168
-		 */
169
-		protected function getAddressBook($addressBookKey)
170
-		{
171
-			$this->loadAddressBooks();
172
-			if (!array_key_exists($addressBookKey, $this->addressBooks)) {
173
-				return null;
174
-			}
175
-
176
-			return $this->addressBooks[$addressBookKey];
177
-		}
178
-
179
-		/**
180
-		 * Load all address books registered with 'register'
181
-		 */
182
-		protected function loadAddressBooks()
183
-		{
184
-			foreach($this->addressBookLoaders as $callable) {
185
-				$callable($this);
186
-			}
187
-			$this->addressBookLoaders = array();
188
-		}
189
-	}
30
+    class ContactsManager implements \OCP\Contacts\IManager {
31
+
32
+        /**
33
+         * This function is used to search and find contacts within the users address books.
34
+         * In case $pattern is empty all contacts will be returned.
35
+         *
36
+         * @param string $pattern which should match within the $searchProperties
37
+         * @param array $searchProperties defines the properties within the query pattern should match
38
+         * @param array $options - for future use. One should always have options!
39
+         * @return array an array of contacts which are arrays of key-value-pairs
40
+         */
41
+        public function search($pattern, $searchProperties = array(), $options = array()) {
42
+            $this->loadAddressBooks();
43
+            $result = array();
44
+            foreach($this->addressBooks as $addressBook) {
45
+                $r = $addressBook->search($pattern, $searchProperties, $options);
46
+                $contacts = array();
47
+                foreach($r as $c){
48
+                    $c['addressbook-key'] = $addressBook->getKey();
49
+                    $contacts[] = $c;
50
+                }
51
+                $result = array_merge($result, $contacts);
52
+            }
53
+
54
+            return $result;
55
+        }
56
+
57
+        /**
58
+         * This function can be used to delete the contact identified by the given id
59
+         *
60
+         * @param object $id the unique identifier to a contact
61
+         * @param string $addressBookKey identifier of the address book in which the contact shall be deleted
62
+         * @return bool successful or not
63
+         */
64
+        public function delete($id, $addressBookKey) {
65
+            $addressBook = $this->getAddressBook($addressBookKey);
66
+            if (!$addressBook) {
67
+                return null;
68
+            }
69
+
70
+            if ($addressBook->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
71
+                return $addressBook->delete($id);
72
+            }
73
+
74
+            return null;
75
+        }
76
+
77
+        /**
78
+         * This function is used to create a new contact if 'id' is not given or not present.
79
+         * Otherwise the contact will be updated by replacing the entire data set.
80
+         *
81
+         * @param array $properties this array if key-value-pairs defines a contact
82
+         * @param string $addressBookKey identifier of the address book in which the contact shall be created or updated
83
+         * @return array representing the contact just created or updated
84
+         */
85
+        public function createOrUpdate($properties, $addressBookKey) {
86
+            $addressBook = $this->getAddressBook($addressBookKey);
87
+            if (!$addressBook) {
88
+                return null;
89
+            }
90
+
91
+            if ($addressBook->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
92
+                return $addressBook->createOrUpdate($properties);
93
+            }
94
+
95
+            return null;
96
+        }
97
+
98
+        /**
99
+         * Check if contacts are available (e.g. contacts app enabled)
100
+         *
101
+         * @return bool true if enabled, false if not
102
+         */
103
+        public function isEnabled() {
104
+            return !empty($this->addressBooks) || !empty($this->addressBookLoaders);
105
+        }
106
+
107
+        /**
108
+         * @param \OCP\IAddressBook $addressBook
109
+         */
110
+        public function registerAddressBook(\OCP\IAddressBook $addressBook) {
111
+            $this->addressBooks[$addressBook->getKey()] = $addressBook;
112
+        }
113
+
114
+        /**
115
+         * @param \OCP\IAddressBook $addressBook
116
+         */
117
+        public function unregisterAddressBook(\OCP\IAddressBook $addressBook) {
118
+            unset($this->addressBooks[$addressBook->getKey()]);
119
+        }
120
+
121
+        /**
122
+         * @return array
123
+         */
124
+        public function getAddressBooks() {
125
+            $this->loadAddressBooks();
126
+            $result = array();
127
+            foreach($this->addressBooks as $addressBook) {
128
+                $result[$addressBook->getKey()] = $addressBook->getDisplayName();
129
+            }
130
+
131
+            return $result;
132
+        }
133
+
134
+        /**
135
+         * removes all registered address book instances
136
+         */
137
+        public function clear() {
138
+            $this->addressBooks = array();
139
+            $this->addressBookLoaders = array();
140
+        }
141
+
142
+        /**
143
+         * @var \OCP\IAddressBook[] which holds all registered address books
144
+         */
145
+        private $addressBooks = array();
146
+
147
+        /**
148
+         * @var \Closure[] to call to load/register address books
149
+         */
150
+        private $addressBookLoaders = array();
151
+
152
+        /**
153
+         * In order to improve lazy loading a closure can be registered which will be called in case
154
+         * address books are actually requested
155
+         *
156
+         * @param \Closure $callable
157
+         */
158
+        public function register(\Closure $callable)
159
+        {
160
+            $this->addressBookLoaders[] = $callable;
161
+        }
162
+
163
+        /**
164
+         * Get (and load when needed) the address book for $key
165
+         *
166
+         * @param string $addressBookKey
167
+         * @return \OCP\IAddressBook
168
+         */
169
+        protected function getAddressBook($addressBookKey)
170
+        {
171
+            $this->loadAddressBooks();
172
+            if (!array_key_exists($addressBookKey, $this->addressBooks)) {
173
+                return null;
174
+            }
175
+
176
+            return $this->addressBooks[$addressBookKey];
177
+        }
178
+
179
+        /**
180
+         * Load all address books registered with 'register'
181
+         */
182
+        protected function loadAddressBooks()
183
+        {
184
+            foreach($this->addressBookLoaders as $callable) {
185
+                $callable($this);
186
+            }
187
+            $this->addressBookLoaders = array();
188
+        }
189
+    }
190 190
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -41,10 +41,10 @@  discard block
 block discarded – undo
41 41
 		public function search($pattern, $searchProperties = array(), $options = array()) {
42 42
 			$this->loadAddressBooks();
43 43
 			$result = array();
44
-			foreach($this->addressBooks as $addressBook) {
44
+			foreach ($this->addressBooks as $addressBook) {
45 45
 				$r = $addressBook->search($pattern, $searchProperties, $options);
46 46
 				$contacts = array();
47
-				foreach($r as $c){
47
+				foreach ($r as $c) {
48 48
 					$c['addressbook-key'] = $addressBook->getKey();
49 49
 					$contacts[] = $c;
50 50
 				}
@@ -124,7 +124,7 @@  discard block
 block discarded – undo
124 124
 		public function getAddressBooks() {
125 125
 			$this->loadAddressBooks();
126 126
 			$result = array();
127
-			foreach($this->addressBooks as $addressBook) {
127
+			foreach ($this->addressBooks as $addressBook) {
128 128
 				$result[$addressBook->getKey()] = $addressBook->getDisplayName();
129 129
 			}
130 130
 
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
 		 */
182 182
 		protected function loadAddressBooks()
183 183
 		{
184
-			foreach($this->addressBookLoaders as $callable) {
184
+			foreach ($this->addressBookLoaders as $callable) {
185 185
 				$callable($this);
186 186
 			}
187 187
 			$this->addressBookLoaders = array();
Please login to merge, or discard this patch.
lib/private/Installer.php 4 patches
Braces   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -412,7 +412,7 @@
 block discarded – undo
412 412
 			$appDir = OC_App::getInstallPath() . '/' . $appId;
413 413
 			OC_Helper::rmdirr($appDir);
414 414
 			return true;
415
-		}else{
415
+		} else{
416 416
 			\OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
417 417
 
418 418
 			return false;
Please login to merge, or discard this patch.
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -420,7 +420,7 @@
 block discarded – undo
420 420
 
421 421
 	/**
422 422
 	 * Check if app has been installed from git
423
-	 * @param string $name name of the application to remove
423
+	 * @param string $appId
424 424
 	 * @return boolean
425 425
 	 *
426 426
 	 * The function will check if the path contains a .git folder
Please login to merge, or discard this patch.
Indentation   +550 added lines, -550 removed lines patch added patch discarded remove patch
@@ -52,554 +52,554 @@
 block discarded – undo
52 52
  * This class provides the functionality needed to install, update and remove apps
53 53
  */
54 54
 class Installer {
55
-	/** @var AppFetcher */
56
-	private $appFetcher;
57
-	/** @var IClientService */
58
-	private $clientService;
59
-	/** @var ITempManager */
60
-	private $tempManager;
61
-	/** @var ILogger */
62
-	private $logger;
63
-	/** @var IConfig */
64
-	private $config;
65
-	/** @var array - for caching the result of app fetcher */
66
-	private $apps = null;
67
-	/** @var bool|null - for caching the result of the ready status */
68
-	private $isInstanceReadyForUpdates = null;
69
-
70
-	/**
71
-	 * @param AppFetcher $appFetcher
72
-	 * @param IClientService $clientService
73
-	 * @param ITempManager $tempManager
74
-	 * @param ILogger $logger
75
-	 * @param IConfig $config
76
-	 */
77
-	public function __construct(AppFetcher $appFetcher,
78
-								IClientService $clientService,
79
-								ITempManager $tempManager,
80
-								ILogger $logger,
81
-								IConfig $config) {
82
-		$this->appFetcher = $appFetcher;
83
-		$this->clientService = $clientService;
84
-		$this->tempManager = $tempManager;
85
-		$this->logger = $logger;
86
-		$this->config = $config;
87
-	}
88
-
89
-	/**
90
-	 * Installs an app that is located in one of the app folders already
91
-	 *
92
-	 * @param string $appId App to install
93
-	 * @throws \Exception
94
-	 * @return string app ID
95
-	 */
96
-	public function installApp($appId) {
97
-		$app = \OC_App::findAppInDirectories($appId);
98
-		if($app === false) {
99
-			throw new \Exception('App not found in any app directory');
100
-		}
101
-
102
-		$basedir = $app['path'].'/'.$appId;
103
-		$info = OC_App::getAppInfo($basedir.'/appinfo/info.xml', true);
104
-
105
-		$l = \OC::$server->getL10N('core');
106
-
107
-		if(!is_array($info)) {
108
-			throw new \Exception(
109
-				$l->t('App "%s" cannot be installed because appinfo file cannot be read.',
110
-					[$appId]
111
-				)
112
-			);
113
-		}
114
-
115
-		$version = implode('.', \OCP\Util::getVersion());
116
-		if (!\OC_App::isAppCompatible($version, $info)) {
117
-			throw new \Exception(
118
-				// TODO $l
119
-				$l->t('App "%s" cannot be installed because it is not compatible with this version of the server.',
120
-					[$info['name']]
121
-				)
122
-			);
123
-		}
124
-
125
-		// check for required dependencies
126
-		\OC_App::checkAppDependencies($this->config, $l, $info);
127
-		\OC_App::registerAutoloading($appId, $basedir);
128
-
129
-		//install the database
130
-		if(is_file($basedir.'/appinfo/database.xml')) {
131
-			if (\OC::$server->getConfig()->getAppValue($info['id'], 'installed_version') === null) {
132
-				OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml');
133
-			} else {
134
-				OC_DB::updateDbFromStructure($basedir.'/appinfo/database.xml');
135
-			}
136
-		} else {
137
-			$ms = new \OC\DB\MigrationService($info['id'], \OC::$server->getDatabaseConnection());
138
-			$ms->migrate();
139
-		}
140
-
141
-		\OC_App::setupBackgroundJobs($info['background-jobs']);
142
-
143
-		//run appinfo/install.php
144
-		if(!isset($data['noinstall']) or $data['noinstall']==false) {
145
-			self::includeAppScript($basedir . '/appinfo/install.php');
146
-		}
147
-
148
-		$appData = OC_App::getAppInfo($appId);
149
-		OC_App::executeRepairSteps($appId, $appData['repair-steps']['install']);
150
-
151
-		//set the installed version
152
-		\OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id'], false));
153
-		\OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no');
154
-
155
-		//set remote/public handlers
156
-		foreach($info['remote'] as $name=>$path) {
157
-			\OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $info['id'].'/'.$path);
158
-		}
159
-		foreach($info['public'] as $name=>$path) {
160
-			\OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $info['id'].'/'.$path);
161
-		}
162
-
163
-		OC_App::setAppTypes($info['id']);
164
-
165
-		return $info['id'];
166
-	}
167
-
168
-	/**
169
-	 * Updates the specified app from the appstore
170
-	 *
171
-	 * @param string $appId
172
-	 * @return bool
173
-	 */
174
-	public function updateAppstoreApp($appId) {
175
-		if($this->isUpdateAvailable($appId)) {
176
-			try {
177
-				$this->downloadApp($appId);
178
-			} catch (\Exception $e) {
179
-				$this->logger->logException($e, [
180
-					'level' => \OCP\Util::ERROR,
181
-					'app' => 'core',
182
-				]);
183
-				return false;
184
-			}
185
-			return OC_App::updateApp($appId);
186
-		}
187
-
188
-		return false;
189
-	}
190
-
191
-	/**
192
-	 * Downloads an app and puts it into the app directory
193
-	 *
194
-	 * @param string $appId
195
-	 *
196
-	 * @throws \Exception If the installation was not successful
197
-	 */
198
-	public function downloadApp($appId) {
199
-		$appId = strtolower($appId);
200
-
201
-		$apps = $this->appFetcher->get();
202
-		foreach($apps as $app) {
203
-			if($app['id'] === $appId) {
204
-				// Load the certificate
205
-				$certificate = new X509();
206
-				$certificate->loadCA(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crt'));
207
-				$loadedCertificate = $certificate->loadX509($app['certificate']);
208
-
209
-				// Verify if the certificate has been revoked
210
-				$crl = new X509();
211
-				$crl->loadCA(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crt'));
212
-				$crl->loadCRL(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crl'));
213
-				if($crl->validateSignature() !== true) {
214
-					throw new \Exception('Could not validate CRL signature');
215
-				}
216
-				$csn = $loadedCertificate['tbsCertificate']['serialNumber']->toString();
217
-				$revoked = $crl->getRevoked($csn);
218
-				if ($revoked !== false) {
219
-					throw new \Exception(
220
-						sprintf(
221
-							'Certificate "%s" has been revoked',
222
-							$csn
223
-						)
224
-					);
225
-				}
226
-
227
-				// Verify if the certificate has been issued by the Nextcloud Code Authority CA
228
-				if($certificate->validateSignature() !== true) {
229
-					throw new \Exception(
230
-						sprintf(
231
-							'App with id %s has a certificate not issued by a trusted Code Signing Authority',
232
-							$appId
233
-						)
234
-					);
235
-				}
236
-
237
-				// Verify if the certificate is issued for the requested app id
238
-				$certInfo = openssl_x509_parse($app['certificate']);
239
-				if(!isset($certInfo['subject']['CN'])) {
240
-					throw new \Exception(
241
-						sprintf(
242
-							'App with id %s has a cert with no CN',
243
-							$appId
244
-						)
245
-					);
246
-				}
247
-				if($certInfo['subject']['CN'] !== $appId) {
248
-					throw new \Exception(
249
-						sprintf(
250
-							'App with id %s has a cert issued to %s',
251
-							$appId,
252
-							$certInfo['subject']['CN']
253
-						)
254
-					);
255
-				}
256
-
257
-				// Download the release
258
-				$tempFile = $this->tempManager->getTemporaryFile('.tar.gz');
259
-				$client = $this->clientService->newClient();
260
-				$client->get($app['releases'][0]['download'], ['save_to' => $tempFile]);
261
-
262
-				// Check if the signature actually matches the downloaded content
263
-				$certificate = openssl_get_publickey($app['certificate']);
264
-				$verified = (bool)openssl_verify(file_get_contents($tempFile), base64_decode($app['releases'][0]['signature']), $certificate, OPENSSL_ALGO_SHA512);
265
-				openssl_free_key($certificate);
266
-
267
-				if($verified === true) {
268
-					// Seems to match, let's proceed
269
-					$extractDir = $this->tempManager->getTemporaryFolder();
270
-					$archive = new TAR($tempFile);
271
-
272
-					if($archive) {
273
-						if (!$archive->extract($extractDir)) {
274
-							throw new \Exception(
275
-								sprintf(
276
-									'Could not extract app %s',
277
-									$appId
278
-								)
279
-							);
280
-						}
281
-						$allFiles = scandir($extractDir);
282
-						$folders = array_diff($allFiles, ['.', '..']);
283
-						$folders = array_values($folders);
284
-
285
-						if(count($folders) > 1) {
286
-							throw new \Exception(
287
-								sprintf(
288
-									'Extracted app %s has more than 1 folder',
289
-									$appId
290
-								)
291
-							);
292
-						}
293
-
294
-						// Check if appinfo/info.xml has the same app ID as well
295
-						$loadEntities = libxml_disable_entity_loader(false);
296
-						$xml = simplexml_load_file($extractDir . '/' . $folders[0] . '/appinfo/info.xml');
297
-						libxml_disable_entity_loader($loadEntities);
298
-						if((string)$xml->id !== $appId) {
299
-							throw new \Exception(
300
-								sprintf(
301
-									'App for id %s has a wrong app ID in info.xml: %s',
302
-									$appId,
303
-									(string)$xml->id
304
-								)
305
-							);
306
-						}
307
-
308
-						// Check if the version is lower than before
309
-						$currentVersion = OC_App::getAppVersion($appId);
310
-						$newVersion = (string)$xml->version;
311
-						if(version_compare($currentVersion, $newVersion) === 1) {
312
-							throw new \Exception(
313
-								sprintf(
314
-									'App for id %s has version %s and tried to update to lower version %s',
315
-									$appId,
316
-									$currentVersion,
317
-									$newVersion
318
-								)
319
-							);
320
-						}
321
-
322
-						$baseDir = OC_App::getInstallPath() . '/' . $appId;
323
-						// Remove old app with the ID if existent
324
-						OC_Helper::rmdirr($baseDir);
325
-						// Move to app folder
326
-						if(@mkdir($baseDir)) {
327
-							$extractDir .= '/' . $folders[0];
328
-							OC_Helper::copyr($extractDir, $baseDir);
329
-						}
330
-						OC_Helper::copyr($extractDir, $baseDir);
331
-						OC_Helper::rmdirr($extractDir);
332
-						return;
333
-					} else {
334
-						throw new \Exception(
335
-							sprintf(
336
-								'Could not extract app with ID %s to %s',
337
-								$appId,
338
-								$extractDir
339
-							)
340
-						);
341
-					}
342
-				} else {
343
-					// Signature does not match
344
-					throw new \Exception(
345
-						sprintf(
346
-							'App with id %s has invalid signature',
347
-							$appId
348
-						)
349
-					);
350
-				}
351
-			}
352
-		}
353
-
354
-		throw new \Exception(
355
-			sprintf(
356
-				'Could not download app %s',
357
-				$appId
358
-			)
359
-		);
360
-	}
361
-
362
-	/**
363
-	 * Check if an update for the app is available
364
-	 *
365
-	 * @param string $appId
366
-	 * @return string|false false or the version number of the update
367
-	 */
368
-	public function isUpdateAvailable($appId) {
369
-		if ($this->isInstanceReadyForUpdates === null) {
370
-			$installPath = OC_App::getInstallPath();
371
-			if ($installPath === false || $installPath === null) {
372
-				$this->isInstanceReadyForUpdates = false;
373
-			} else {
374
-				$this->isInstanceReadyForUpdates = true;
375
-			}
376
-		}
377
-
378
-		if ($this->isInstanceReadyForUpdates === false) {
379
-			return false;
380
-		}
381
-
382
-		if ($this->isInstalledFromGit($appId) === true) {
383
-			return false;
384
-		}
385
-
386
-		if ($this->apps === null) {
387
-			$this->apps = $this->appFetcher->get();
388
-		}
389
-
390
-		foreach($this->apps as $app) {
391
-			if($app['id'] === $appId) {
392
-				$currentVersion = OC_App::getAppVersion($appId);
393
-				$newestVersion = $app['releases'][0]['version'];
394
-				if (version_compare($newestVersion, $currentVersion, '>')) {
395
-					return $newestVersion;
396
-				} else {
397
-					return false;
398
-				}
399
-			}
400
-		}
401
-
402
-		return false;
403
-	}
404
-
405
-	/**
406
-	 * Check if app has been installed from git
407
-	 * @param string $name name of the application to remove
408
-	 * @return boolean
409
-	 *
410
-	 * The function will check if the path contains a .git folder
411
-	 */
412
-	private function isInstalledFromGit($appId) {
413
-		$app = \OC_App::findAppInDirectories($appId);
414
-		if($app === false) {
415
-			return false;
416
-		}
417
-		$basedir = $app['path'].'/'.$appId;
418
-		return file_exists($basedir.'/.git/');
419
-	}
420
-
421
-	/**
422
-	 * Check if app is already downloaded
423
-	 * @param string $name name of the application to remove
424
-	 * @return boolean
425
-	 *
426
-	 * The function will check if the app is already downloaded in the apps repository
427
-	 */
428
-	public function isDownloaded($name) {
429
-		foreach(\OC::$APPSROOTS as $dir) {
430
-			$dirToTest  = $dir['path'];
431
-			$dirToTest .= '/';
432
-			$dirToTest .= $name;
433
-			$dirToTest .= '/';
434
-
435
-			if (is_dir($dirToTest)) {
436
-				return true;
437
-			}
438
-		}
439
-
440
-		return false;
441
-	}
442
-
443
-	/**
444
-	 * Removes an app
445
-	 * @param string $appId ID of the application to remove
446
-	 * @return boolean
447
-	 *
448
-	 *
449
-	 * This function works as follows
450
-	 *   -# call uninstall repair steps
451
-	 *   -# removing the files
452
-	 *
453
-	 * The function will not delete preferences, tables and the configuration,
454
-	 * this has to be done by the function oc_app_uninstall().
455
-	 */
456
-	public function removeApp($appId) {
457
-		if($this->isDownloaded( $appId )) {
458
-			if (\OC::$server->getAppManager()->isShipped($appId)) {
459
-				return false;
460
-			}
461
-			$appDir = OC_App::getInstallPath() . '/' . $appId;
462
-			OC_Helper::rmdirr($appDir);
463
-			return true;
464
-		}else{
465
-			\OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
466
-
467
-			return false;
468
-		}
469
-
470
-	}
471
-
472
-	/**
473
-	 * Installs the app within the bundle and marks the bundle as installed
474
-	 *
475
-	 * @param Bundle $bundle
476
-	 * @throws \Exception If app could not get installed
477
-	 */
478
-	public function installAppBundle(Bundle $bundle) {
479
-		$appIds = $bundle->getAppIdentifiers();
480
-		foreach($appIds as $appId) {
481
-			if(!$this->isDownloaded($appId)) {
482
-				$this->downloadApp($appId);
483
-			}
484
-			$this->installApp($appId);
485
-			$app = new OC_App();
486
-			$app->enable($appId);
487
-		}
488
-		$bundles = json_decode($this->config->getAppValue('core', 'installed.bundles', json_encode([])), true);
489
-		$bundles[] = $bundle->getIdentifier();
490
-		$this->config->setAppValue('core', 'installed.bundles', json_encode($bundles));
491
-	}
492
-
493
-	/**
494
-	 * Installs shipped apps
495
-	 *
496
-	 * This function installs all apps found in the 'apps' directory that should be enabled by default;
497
-	 * @param bool $softErrors When updating we ignore errors and simply log them, better to have a
498
-	 *                         working ownCloud at the end instead of an aborted update.
499
-	 * @return array Array of error messages (appid => Exception)
500
-	 */
501
-	public static function installShippedApps($softErrors = false) {
502
-		$appManager = \OC::$server->getAppManager();
503
-		$config = \OC::$server->getConfig();
504
-		$errors = [];
505
-		foreach(\OC::$APPSROOTS as $app_dir) {
506
-			if($dir = opendir( $app_dir['path'] )) {
507
-				while( false !== ( $filename = readdir( $dir ))) {
508
-					if( $filename[0] !== '.' and is_dir($app_dir['path']."/$filename") ) {
509
-						if( file_exists( $app_dir['path']."/$filename/appinfo/info.xml" )) {
510
-							if($config->getAppValue($filename, "installed_version", null) === null) {
511
-								$info=OC_App::getAppInfo($filename);
512
-								$enabled = isset($info['default_enable']);
513
-								if (($enabled || in_array($filename, $appManager->getAlwaysEnabledApps()))
514
-									  && $config->getAppValue($filename, 'enabled') !== 'no') {
515
-									if ($softErrors) {
516
-										try {
517
-											Installer::installShippedApp($filename);
518
-										} catch (HintException $e) {
519
-											if ($e->getPrevious() instanceof TableExistsException) {
520
-												$errors[$filename] = $e;
521
-												continue;
522
-											}
523
-											throw $e;
524
-										}
525
-									} else {
526
-										Installer::installShippedApp($filename);
527
-									}
528
-									$config->setAppValue($filename, 'enabled', 'yes');
529
-								}
530
-							}
531
-						}
532
-					}
533
-				}
534
-				closedir( $dir );
535
-			}
536
-		}
537
-
538
-		return $errors;
539
-	}
540
-
541
-	/**
542
-	 * install an app already placed in the app folder
543
-	 * @param string $app id of the app to install
544
-	 * @return integer
545
-	 */
546
-	public static function installShippedApp($app) {
547
-		//install the database
548
-		$appPath = OC_App::getAppPath($app);
549
-		\OC_App::registerAutoloading($app, $appPath);
550
-
551
-		if(is_file("$appPath/appinfo/database.xml")) {
552
-			try {
553
-				OC_DB::createDbFromStructure("$appPath/appinfo/database.xml");
554
-			} catch (TableExistsException $e) {
555
-				throw new HintException(
556
-					'Failed to enable app ' . $app,
557
-					'Please ask for help via one of our <a href="https://nextcloud.com/support/" target="_blank" rel="noreferrer noopener">support channels</a>.',
558
-					0, $e
559
-				);
560
-			}
561
-		} else {
562
-			$ms = new \OC\DB\MigrationService($app, \OC::$server->getDatabaseConnection());
563
-			$ms->migrate();
564
-		}
565
-
566
-		//run appinfo/install.php
567
-		self::includeAppScript("$appPath/appinfo/install.php");
568
-
569
-		$info = OC_App::getAppInfo($app);
570
-		if (is_null($info)) {
571
-			return false;
572
-		}
573
-		\OC_App::setupBackgroundJobs($info['background-jobs']);
574
-
575
-		OC_App::executeRepairSteps($app, $info['repair-steps']['install']);
576
-
577
-		$config = \OC::$server->getConfig();
578
-
579
-		$config->setAppValue($app, 'installed_version', OC_App::getAppVersion($app));
580
-		if (array_key_exists('ocsid', $info)) {
581
-			$config->setAppValue($app, 'ocsid', $info['ocsid']);
582
-		}
583
-
584
-		//set remote/public handlers
585
-		foreach($info['remote'] as $name=>$path) {
586
-			$config->setAppValue('core', 'remote_'.$name, $app.'/'.$path);
587
-		}
588
-		foreach($info['public'] as $name=>$path) {
589
-			$config->setAppValue('core', 'public_'.$name, $app.'/'.$path);
590
-		}
591
-
592
-		OC_App::setAppTypes($info['id']);
593
-
594
-		return $info['id'];
595
-	}
596
-
597
-	/**
598
-	 * @param string $script
599
-	 */
600
-	private static function includeAppScript($script) {
601
-		if ( file_exists($script) ){
602
-			include $script;
603
-		}
604
-	}
55
+    /** @var AppFetcher */
56
+    private $appFetcher;
57
+    /** @var IClientService */
58
+    private $clientService;
59
+    /** @var ITempManager */
60
+    private $tempManager;
61
+    /** @var ILogger */
62
+    private $logger;
63
+    /** @var IConfig */
64
+    private $config;
65
+    /** @var array - for caching the result of app fetcher */
66
+    private $apps = null;
67
+    /** @var bool|null - for caching the result of the ready status */
68
+    private $isInstanceReadyForUpdates = null;
69
+
70
+    /**
71
+     * @param AppFetcher $appFetcher
72
+     * @param IClientService $clientService
73
+     * @param ITempManager $tempManager
74
+     * @param ILogger $logger
75
+     * @param IConfig $config
76
+     */
77
+    public function __construct(AppFetcher $appFetcher,
78
+                                IClientService $clientService,
79
+                                ITempManager $tempManager,
80
+                                ILogger $logger,
81
+                                IConfig $config) {
82
+        $this->appFetcher = $appFetcher;
83
+        $this->clientService = $clientService;
84
+        $this->tempManager = $tempManager;
85
+        $this->logger = $logger;
86
+        $this->config = $config;
87
+    }
88
+
89
+    /**
90
+     * Installs an app that is located in one of the app folders already
91
+     *
92
+     * @param string $appId App to install
93
+     * @throws \Exception
94
+     * @return string app ID
95
+     */
96
+    public function installApp($appId) {
97
+        $app = \OC_App::findAppInDirectories($appId);
98
+        if($app === false) {
99
+            throw new \Exception('App not found in any app directory');
100
+        }
101
+
102
+        $basedir = $app['path'].'/'.$appId;
103
+        $info = OC_App::getAppInfo($basedir.'/appinfo/info.xml', true);
104
+
105
+        $l = \OC::$server->getL10N('core');
106
+
107
+        if(!is_array($info)) {
108
+            throw new \Exception(
109
+                $l->t('App "%s" cannot be installed because appinfo file cannot be read.',
110
+                    [$appId]
111
+                )
112
+            );
113
+        }
114
+
115
+        $version = implode('.', \OCP\Util::getVersion());
116
+        if (!\OC_App::isAppCompatible($version, $info)) {
117
+            throw new \Exception(
118
+                // TODO $l
119
+                $l->t('App "%s" cannot be installed because it is not compatible with this version of the server.',
120
+                    [$info['name']]
121
+                )
122
+            );
123
+        }
124
+
125
+        // check for required dependencies
126
+        \OC_App::checkAppDependencies($this->config, $l, $info);
127
+        \OC_App::registerAutoloading($appId, $basedir);
128
+
129
+        //install the database
130
+        if(is_file($basedir.'/appinfo/database.xml')) {
131
+            if (\OC::$server->getConfig()->getAppValue($info['id'], 'installed_version') === null) {
132
+                OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml');
133
+            } else {
134
+                OC_DB::updateDbFromStructure($basedir.'/appinfo/database.xml');
135
+            }
136
+        } else {
137
+            $ms = new \OC\DB\MigrationService($info['id'], \OC::$server->getDatabaseConnection());
138
+            $ms->migrate();
139
+        }
140
+
141
+        \OC_App::setupBackgroundJobs($info['background-jobs']);
142
+
143
+        //run appinfo/install.php
144
+        if(!isset($data['noinstall']) or $data['noinstall']==false) {
145
+            self::includeAppScript($basedir . '/appinfo/install.php');
146
+        }
147
+
148
+        $appData = OC_App::getAppInfo($appId);
149
+        OC_App::executeRepairSteps($appId, $appData['repair-steps']['install']);
150
+
151
+        //set the installed version
152
+        \OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id'], false));
153
+        \OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no');
154
+
155
+        //set remote/public handlers
156
+        foreach($info['remote'] as $name=>$path) {
157
+            \OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $info['id'].'/'.$path);
158
+        }
159
+        foreach($info['public'] as $name=>$path) {
160
+            \OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $info['id'].'/'.$path);
161
+        }
162
+
163
+        OC_App::setAppTypes($info['id']);
164
+
165
+        return $info['id'];
166
+    }
167
+
168
+    /**
169
+     * Updates the specified app from the appstore
170
+     *
171
+     * @param string $appId
172
+     * @return bool
173
+     */
174
+    public function updateAppstoreApp($appId) {
175
+        if($this->isUpdateAvailable($appId)) {
176
+            try {
177
+                $this->downloadApp($appId);
178
+            } catch (\Exception $e) {
179
+                $this->logger->logException($e, [
180
+                    'level' => \OCP\Util::ERROR,
181
+                    'app' => 'core',
182
+                ]);
183
+                return false;
184
+            }
185
+            return OC_App::updateApp($appId);
186
+        }
187
+
188
+        return false;
189
+    }
190
+
191
+    /**
192
+     * Downloads an app and puts it into the app directory
193
+     *
194
+     * @param string $appId
195
+     *
196
+     * @throws \Exception If the installation was not successful
197
+     */
198
+    public function downloadApp($appId) {
199
+        $appId = strtolower($appId);
200
+
201
+        $apps = $this->appFetcher->get();
202
+        foreach($apps as $app) {
203
+            if($app['id'] === $appId) {
204
+                // Load the certificate
205
+                $certificate = new X509();
206
+                $certificate->loadCA(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crt'));
207
+                $loadedCertificate = $certificate->loadX509($app['certificate']);
208
+
209
+                // Verify if the certificate has been revoked
210
+                $crl = new X509();
211
+                $crl->loadCA(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crt'));
212
+                $crl->loadCRL(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crl'));
213
+                if($crl->validateSignature() !== true) {
214
+                    throw new \Exception('Could not validate CRL signature');
215
+                }
216
+                $csn = $loadedCertificate['tbsCertificate']['serialNumber']->toString();
217
+                $revoked = $crl->getRevoked($csn);
218
+                if ($revoked !== false) {
219
+                    throw new \Exception(
220
+                        sprintf(
221
+                            'Certificate "%s" has been revoked',
222
+                            $csn
223
+                        )
224
+                    );
225
+                }
226
+
227
+                // Verify if the certificate has been issued by the Nextcloud Code Authority CA
228
+                if($certificate->validateSignature() !== true) {
229
+                    throw new \Exception(
230
+                        sprintf(
231
+                            'App with id %s has a certificate not issued by a trusted Code Signing Authority',
232
+                            $appId
233
+                        )
234
+                    );
235
+                }
236
+
237
+                // Verify if the certificate is issued for the requested app id
238
+                $certInfo = openssl_x509_parse($app['certificate']);
239
+                if(!isset($certInfo['subject']['CN'])) {
240
+                    throw new \Exception(
241
+                        sprintf(
242
+                            'App with id %s has a cert with no CN',
243
+                            $appId
244
+                        )
245
+                    );
246
+                }
247
+                if($certInfo['subject']['CN'] !== $appId) {
248
+                    throw new \Exception(
249
+                        sprintf(
250
+                            'App with id %s has a cert issued to %s',
251
+                            $appId,
252
+                            $certInfo['subject']['CN']
253
+                        )
254
+                    );
255
+                }
256
+
257
+                // Download the release
258
+                $tempFile = $this->tempManager->getTemporaryFile('.tar.gz');
259
+                $client = $this->clientService->newClient();
260
+                $client->get($app['releases'][0]['download'], ['save_to' => $tempFile]);
261
+
262
+                // Check if the signature actually matches the downloaded content
263
+                $certificate = openssl_get_publickey($app['certificate']);
264
+                $verified = (bool)openssl_verify(file_get_contents($tempFile), base64_decode($app['releases'][0]['signature']), $certificate, OPENSSL_ALGO_SHA512);
265
+                openssl_free_key($certificate);
266
+
267
+                if($verified === true) {
268
+                    // Seems to match, let's proceed
269
+                    $extractDir = $this->tempManager->getTemporaryFolder();
270
+                    $archive = new TAR($tempFile);
271
+
272
+                    if($archive) {
273
+                        if (!$archive->extract($extractDir)) {
274
+                            throw new \Exception(
275
+                                sprintf(
276
+                                    'Could not extract app %s',
277
+                                    $appId
278
+                                )
279
+                            );
280
+                        }
281
+                        $allFiles = scandir($extractDir);
282
+                        $folders = array_diff($allFiles, ['.', '..']);
283
+                        $folders = array_values($folders);
284
+
285
+                        if(count($folders) > 1) {
286
+                            throw new \Exception(
287
+                                sprintf(
288
+                                    'Extracted app %s has more than 1 folder',
289
+                                    $appId
290
+                                )
291
+                            );
292
+                        }
293
+
294
+                        // Check if appinfo/info.xml has the same app ID as well
295
+                        $loadEntities = libxml_disable_entity_loader(false);
296
+                        $xml = simplexml_load_file($extractDir . '/' . $folders[0] . '/appinfo/info.xml');
297
+                        libxml_disable_entity_loader($loadEntities);
298
+                        if((string)$xml->id !== $appId) {
299
+                            throw new \Exception(
300
+                                sprintf(
301
+                                    'App for id %s has a wrong app ID in info.xml: %s',
302
+                                    $appId,
303
+                                    (string)$xml->id
304
+                                )
305
+                            );
306
+                        }
307
+
308
+                        // Check if the version is lower than before
309
+                        $currentVersion = OC_App::getAppVersion($appId);
310
+                        $newVersion = (string)$xml->version;
311
+                        if(version_compare($currentVersion, $newVersion) === 1) {
312
+                            throw new \Exception(
313
+                                sprintf(
314
+                                    'App for id %s has version %s and tried to update to lower version %s',
315
+                                    $appId,
316
+                                    $currentVersion,
317
+                                    $newVersion
318
+                                )
319
+                            );
320
+                        }
321
+
322
+                        $baseDir = OC_App::getInstallPath() . '/' . $appId;
323
+                        // Remove old app with the ID if existent
324
+                        OC_Helper::rmdirr($baseDir);
325
+                        // Move to app folder
326
+                        if(@mkdir($baseDir)) {
327
+                            $extractDir .= '/' . $folders[0];
328
+                            OC_Helper::copyr($extractDir, $baseDir);
329
+                        }
330
+                        OC_Helper::copyr($extractDir, $baseDir);
331
+                        OC_Helper::rmdirr($extractDir);
332
+                        return;
333
+                    } else {
334
+                        throw new \Exception(
335
+                            sprintf(
336
+                                'Could not extract app with ID %s to %s',
337
+                                $appId,
338
+                                $extractDir
339
+                            )
340
+                        );
341
+                    }
342
+                } else {
343
+                    // Signature does not match
344
+                    throw new \Exception(
345
+                        sprintf(
346
+                            'App with id %s has invalid signature',
347
+                            $appId
348
+                        )
349
+                    );
350
+                }
351
+            }
352
+        }
353
+
354
+        throw new \Exception(
355
+            sprintf(
356
+                'Could not download app %s',
357
+                $appId
358
+            )
359
+        );
360
+    }
361
+
362
+    /**
363
+     * Check if an update for the app is available
364
+     *
365
+     * @param string $appId
366
+     * @return string|false false or the version number of the update
367
+     */
368
+    public function isUpdateAvailable($appId) {
369
+        if ($this->isInstanceReadyForUpdates === null) {
370
+            $installPath = OC_App::getInstallPath();
371
+            if ($installPath === false || $installPath === null) {
372
+                $this->isInstanceReadyForUpdates = false;
373
+            } else {
374
+                $this->isInstanceReadyForUpdates = true;
375
+            }
376
+        }
377
+
378
+        if ($this->isInstanceReadyForUpdates === false) {
379
+            return false;
380
+        }
381
+
382
+        if ($this->isInstalledFromGit($appId) === true) {
383
+            return false;
384
+        }
385
+
386
+        if ($this->apps === null) {
387
+            $this->apps = $this->appFetcher->get();
388
+        }
389
+
390
+        foreach($this->apps as $app) {
391
+            if($app['id'] === $appId) {
392
+                $currentVersion = OC_App::getAppVersion($appId);
393
+                $newestVersion = $app['releases'][0]['version'];
394
+                if (version_compare($newestVersion, $currentVersion, '>')) {
395
+                    return $newestVersion;
396
+                } else {
397
+                    return false;
398
+                }
399
+            }
400
+        }
401
+
402
+        return false;
403
+    }
404
+
405
+    /**
406
+     * Check if app has been installed from git
407
+     * @param string $name name of the application to remove
408
+     * @return boolean
409
+     *
410
+     * The function will check if the path contains a .git folder
411
+     */
412
+    private function isInstalledFromGit($appId) {
413
+        $app = \OC_App::findAppInDirectories($appId);
414
+        if($app === false) {
415
+            return false;
416
+        }
417
+        $basedir = $app['path'].'/'.$appId;
418
+        return file_exists($basedir.'/.git/');
419
+    }
420
+
421
+    /**
422
+     * Check if app is already downloaded
423
+     * @param string $name name of the application to remove
424
+     * @return boolean
425
+     *
426
+     * The function will check if the app is already downloaded in the apps repository
427
+     */
428
+    public function isDownloaded($name) {
429
+        foreach(\OC::$APPSROOTS as $dir) {
430
+            $dirToTest  = $dir['path'];
431
+            $dirToTest .= '/';
432
+            $dirToTest .= $name;
433
+            $dirToTest .= '/';
434
+
435
+            if (is_dir($dirToTest)) {
436
+                return true;
437
+            }
438
+        }
439
+
440
+        return false;
441
+    }
442
+
443
+    /**
444
+     * Removes an app
445
+     * @param string $appId ID of the application to remove
446
+     * @return boolean
447
+     *
448
+     *
449
+     * This function works as follows
450
+     *   -# call uninstall repair steps
451
+     *   -# removing the files
452
+     *
453
+     * The function will not delete preferences, tables and the configuration,
454
+     * this has to be done by the function oc_app_uninstall().
455
+     */
456
+    public function removeApp($appId) {
457
+        if($this->isDownloaded( $appId )) {
458
+            if (\OC::$server->getAppManager()->isShipped($appId)) {
459
+                return false;
460
+            }
461
+            $appDir = OC_App::getInstallPath() . '/' . $appId;
462
+            OC_Helper::rmdirr($appDir);
463
+            return true;
464
+        }else{
465
+            \OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
466
+
467
+            return false;
468
+        }
469
+
470
+    }
471
+
472
+    /**
473
+     * Installs the app within the bundle and marks the bundle as installed
474
+     *
475
+     * @param Bundle $bundle
476
+     * @throws \Exception If app could not get installed
477
+     */
478
+    public function installAppBundle(Bundle $bundle) {
479
+        $appIds = $bundle->getAppIdentifiers();
480
+        foreach($appIds as $appId) {
481
+            if(!$this->isDownloaded($appId)) {
482
+                $this->downloadApp($appId);
483
+            }
484
+            $this->installApp($appId);
485
+            $app = new OC_App();
486
+            $app->enable($appId);
487
+        }
488
+        $bundles = json_decode($this->config->getAppValue('core', 'installed.bundles', json_encode([])), true);
489
+        $bundles[] = $bundle->getIdentifier();
490
+        $this->config->setAppValue('core', 'installed.bundles', json_encode($bundles));
491
+    }
492
+
493
+    /**
494
+     * Installs shipped apps
495
+     *
496
+     * This function installs all apps found in the 'apps' directory that should be enabled by default;
497
+     * @param bool $softErrors When updating we ignore errors and simply log them, better to have a
498
+     *                         working ownCloud at the end instead of an aborted update.
499
+     * @return array Array of error messages (appid => Exception)
500
+     */
501
+    public static function installShippedApps($softErrors = false) {
502
+        $appManager = \OC::$server->getAppManager();
503
+        $config = \OC::$server->getConfig();
504
+        $errors = [];
505
+        foreach(\OC::$APPSROOTS as $app_dir) {
506
+            if($dir = opendir( $app_dir['path'] )) {
507
+                while( false !== ( $filename = readdir( $dir ))) {
508
+                    if( $filename[0] !== '.' and is_dir($app_dir['path']."/$filename") ) {
509
+                        if( file_exists( $app_dir['path']."/$filename/appinfo/info.xml" )) {
510
+                            if($config->getAppValue($filename, "installed_version", null) === null) {
511
+                                $info=OC_App::getAppInfo($filename);
512
+                                $enabled = isset($info['default_enable']);
513
+                                if (($enabled || in_array($filename, $appManager->getAlwaysEnabledApps()))
514
+                                      && $config->getAppValue($filename, 'enabled') !== 'no') {
515
+                                    if ($softErrors) {
516
+                                        try {
517
+                                            Installer::installShippedApp($filename);
518
+                                        } catch (HintException $e) {
519
+                                            if ($e->getPrevious() instanceof TableExistsException) {
520
+                                                $errors[$filename] = $e;
521
+                                                continue;
522
+                                            }
523
+                                            throw $e;
524
+                                        }
525
+                                    } else {
526
+                                        Installer::installShippedApp($filename);
527
+                                    }
528
+                                    $config->setAppValue($filename, 'enabled', 'yes');
529
+                                }
530
+                            }
531
+                        }
532
+                    }
533
+                }
534
+                closedir( $dir );
535
+            }
536
+        }
537
+
538
+        return $errors;
539
+    }
540
+
541
+    /**
542
+     * install an app already placed in the app folder
543
+     * @param string $app id of the app to install
544
+     * @return integer
545
+     */
546
+    public static function installShippedApp($app) {
547
+        //install the database
548
+        $appPath = OC_App::getAppPath($app);
549
+        \OC_App::registerAutoloading($app, $appPath);
550
+
551
+        if(is_file("$appPath/appinfo/database.xml")) {
552
+            try {
553
+                OC_DB::createDbFromStructure("$appPath/appinfo/database.xml");
554
+            } catch (TableExistsException $e) {
555
+                throw new HintException(
556
+                    'Failed to enable app ' . $app,
557
+                    'Please ask for help via one of our <a href="https://nextcloud.com/support/" target="_blank" rel="noreferrer noopener">support channels</a>.',
558
+                    0, $e
559
+                );
560
+            }
561
+        } else {
562
+            $ms = new \OC\DB\MigrationService($app, \OC::$server->getDatabaseConnection());
563
+            $ms->migrate();
564
+        }
565
+
566
+        //run appinfo/install.php
567
+        self::includeAppScript("$appPath/appinfo/install.php");
568
+
569
+        $info = OC_App::getAppInfo($app);
570
+        if (is_null($info)) {
571
+            return false;
572
+        }
573
+        \OC_App::setupBackgroundJobs($info['background-jobs']);
574
+
575
+        OC_App::executeRepairSteps($app, $info['repair-steps']['install']);
576
+
577
+        $config = \OC::$server->getConfig();
578
+
579
+        $config->setAppValue($app, 'installed_version', OC_App::getAppVersion($app));
580
+        if (array_key_exists('ocsid', $info)) {
581
+            $config->setAppValue($app, 'ocsid', $info['ocsid']);
582
+        }
583
+
584
+        //set remote/public handlers
585
+        foreach($info['remote'] as $name=>$path) {
586
+            $config->setAppValue('core', 'remote_'.$name, $app.'/'.$path);
587
+        }
588
+        foreach($info['public'] as $name=>$path) {
589
+            $config->setAppValue('core', 'public_'.$name, $app.'/'.$path);
590
+        }
591
+
592
+        OC_App::setAppTypes($info['id']);
593
+
594
+        return $info['id'];
595
+    }
596
+
597
+    /**
598
+     * @param string $script
599
+     */
600
+    private static function includeAppScript($script) {
601
+        if ( file_exists($script) ){
602
+            include $script;
603
+        }
604
+    }
605 605
 }
Please login to merge, or discard this patch.
Spacing   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
 	 */
96 96
 	public function installApp($appId) {
97 97
 		$app = \OC_App::findAppInDirectories($appId);
98
-		if($app === false) {
98
+		if ($app === false) {
99 99
 			throw new \Exception('App not found in any app directory');
100 100
 		}
101 101
 
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
 
105 105
 		$l = \OC::$server->getL10N('core');
106 106
 
107
-		if(!is_array($info)) {
107
+		if (!is_array($info)) {
108 108
 			throw new \Exception(
109 109
 				$l->t('App "%s" cannot be installed because appinfo file cannot be read.',
110 110
 					[$appId]
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
 		\OC_App::registerAutoloading($appId, $basedir);
128 128
 
129 129
 		//install the database
130
-		if(is_file($basedir.'/appinfo/database.xml')) {
130
+		if (is_file($basedir.'/appinfo/database.xml')) {
131 131
 			if (\OC::$server->getConfig()->getAppValue($info['id'], 'installed_version') === null) {
132 132
 				OC_DB::createDbFromStructure($basedir.'/appinfo/database.xml');
133 133
 			} else {
@@ -141,8 +141,8 @@  discard block
 block discarded – undo
141 141
 		\OC_App::setupBackgroundJobs($info['background-jobs']);
142 142
 
143 143
 		//run appinfo/install.php
144
-		if(!isset($data['noinstall']) or $data['noinstall']==false) {
145
-			self::includeAppScript($basedir . '/appinfo/install.php');
144
+		if (!isset($data['noinstall']) or $data['noinstall'] == false) {
145
+			self::includeAppScript($basedir.'/appinfo/install.php');
146 146
 		}
147 147
 
148 148
 		$appData = OC_App::getAppInfo($appId);
@@ -153,10 +153,10 @@  discard block
 block discarded – undo
153 153
 		\OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no');
154 154
 
155 155
 		//set remote/public handlers
156
-		foreach($info['remote'] as $name=>$path) {
156
+		foreach ($info['remote'] as $name=>$path) {
157 157
 			\OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $info['id'].'/'.$path);
158 158
 		}
159
-		foreach($info['public'] as $name=>$path) {
159
+		foreach ($info['public'] as $name=>$path) {
160 160
 			\OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $info['id'].'/'.$path);
161 161
 		}
162 162
 
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
 	 * @return bool
173 173
 	 */
174 174
 	public function updateAppstoreApp($appId) {
175
-		if($this->isUpdateAvailable($appId)) {
175
+		if ($this->isUpdateAvailable($appId)) {
176 176
 			try {
177 177
 				$this->downloadApp($appId);
178 178
 			} catch (\Exception $e) {
@@ -199,18 +199,18 @@  discard block
 block discarded – undo
199 199
 		$appId = strtolower($appId);
200 200
 
201 201
 		$apps = $this->appFetcher->get();
202
-		foreach($apps as $app) {
203
-			if($app['id'] === $appId) {
202
+		foreach ($apps as $app) {
203
+			if ($app['id'] === $appId) {
204 204
 				// Load the certificate
205 205
 				$certificate = new X509();
206
-				$certificate->loadCA(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crt'));
206
+				$certificate->loadCA(file_get_contents(__DIR__.'/../../resources/codesigning/root.crt'));
207 207
 				$loadedCertificate = $certificate->loadX509($app['certificate']);
208 208
 
209 209
 				// Verify if the certificate has been revoked
210 210
 				$crl = new X509();
211
-				$crl->loadCA(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crt'));
212
-				$crl->loadCRL(file_get_contents(__DIR__ . '/../../resources/codesigning/root.crl'));
213
-				if($crl->validateSignature() !== true) {
211
+				$crl->loadCA(file_get_contents(__DIR__.'/../../resources/codesigning/root.crt'));
212
+				$crl->loadCRL(file_get_contents(__DIR__.'/../../resources/codesigning/root.crl'));
213
+				if ($crl->validateSignature() !== true) {
214 214
 					throw new \Exception('Could not validate CRL signature');
215 215
 				}
216 216
 				$csn = $loadedCertificate['tbsCertificate']['serialNumber']->toString();
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
 				}
226 226
 
227 227
 				// Verify if the certificate has been issued by the Nextcloud Code Authority CA
228
-				if($certificate->validateSignature() !== true) {
228
+				if ($certificate->validateSignature() !== true) {
229 229
 					throw new \Exception(
230 230
 						sprintf(
231 231
 							'App with id %s has a certificate not issued by a trusted Code Signing Authority',
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
 
237 237
 				// Verify if the certificate is issued for the requested app id
238 238
 				$certInfo = openssl_x509_parse($app['certificate']);
239
-				if(!isset($certInfo['subject']['CN'])) {
239
+				if (!isset($certInfo['subject']['CN'])) {
240 240
 					throw new \Exception(
241 241
 						sprintf(
242 242
 							'App with id %s has a cert with no CN',
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
 						)
245 245
 					);
246 246
 				}
247
-				if($certInfo['subject']['CN'] !== $appId) {
247
+				if ($certInfo['subject']['CN'] !== $appId) {
248 248
 					throw new \Exception(
249 249
 						sprintf(
250 250
 							'App with id %s has a cert issued to %s',
@@ -261,15 +261,15 @@  discard block
 block discarded – undo
261 261
 
262 262
 				// Check if the signature actually matches the downloaded content
263 263
 				$certificate = openssl_get_publickey($app['certificate']);
264
-				$verified = (bool)openssl_verify(file_get_contents($tempFile), base64_decode($app['releases'][0]['signature']), $certificate, OPENSSL_ALGO_SHA512);
264
+				$verified = (bool) openssl_verify(file_get_contents($tempFile), base64_decode($app['releases'][0]['signature']), $certificate, OPENSSL_ALGO_SHA512);
265 265
 				openssl_free_key($certificate);
266 266
 
267
-				if($verified === true) {
267
+				if ($verified === true) {
268 268
 					// Seems to match, let's proceed
269 269
 					$extractDir = $this->tempManager->getTemporaryFolder();
270 270
 					$archive = new TAR($tempFile);
271 271
 
272
-					if($archive) {
272
+					if ($archive) {
273 273
 						if (!$archive->extract($extractDir)) {
274 274
 							throw new \Exception(
275 275
 								sprintf(
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
 						$folders = array_diff($allFiles, ['.', '..']);
283 283
 						$folders = array_values($folders);
284 284
 
285
-						if(count($folders) > 1) {
285
+						if (count($folders) > 1) {
286 286
 							throw new \Exception(
287 287
 								sprintf(
288 288
 									'Extracted app %s has more than 1 folder',
@@ -293,22 +293,22 @@  discard block
 block discarded – undo
293 293
 
294 294
 						// Check if appinfo/info.xml has the same app ID as well
295 295
 						$loadEntities = libxml_disable_entity_loader(false);
296
-						$xml = simplexml_load_file($extractDir . '/' . $folders[0] . '/appinfo/info.xml');
296
+						$xml = simplexml_load_file($extractDir.'/'.$folders[0].'/appinfo/info.xml');
297 297
 						libxml_disable_entity_loader($loadEntities);
298
-						if((string)$xml->id !== $appId) {
298
+						if ((string) $xml->id !== $appId) {
299 299
 							throw new \Exception(
300 300
 								sprintf(
301 301
 									'App for id %s has a wrong app ID in info.xml: %s',
302 302
 									$appId,
303
-									(string)$xml->id
303
+									(string) $xml->id
304 304
 								)
305 305
 							);
306 306
 						}
307 307
 
308 308
 						// Check if the version is lower than before
309 309
 						$currentVersion = OC_App::getAppVersion($appId);
310
-						$newVersion = (string)$xml->version;
311
-						if(version_compare($currentVersion, $newVersion) === 1) {
310
+						$newVersion = (string) $xml->version;
311
+						if (version_compare($currentVersion, $newVersion) === 1) {
312 312
 							throw new \Exception(
313 313
 								sprintf(
314 314
 									'App for id %s has version %s and tried to update to lower version %s',
@@ -319,12 +319,12 @@  discard block
 block discarded – undo
319 319
 							);
320 320
 						}
321 321
 
322
-						$baseDir = OC_App::getInstallPath() . '/' . $appId;
322
+						$baseDir = OC_App::getInstallPath().'/'.$appId;
323 323
 						// Remove old app with the ID if existent
324 324
 						OC_Helper::rmdirr($baseDir);
325 325
 						// Move to app folder
326
-						if(@mkdir($baseDir)) {
327
-							$extractDir .= '/' . $folders[0];
326
+						if (@mkdir($baseDir)) {
327
+							$extractDir .= '/'.$folders[0];
328 328
 							OC_Helper::copyr($extractDir, $baseDir);
329 329
 						}
330 330
 						OC_Helper::copyr($extractDir, $baseDir);
@@ -387,8 +387,8 @@  discard block
 block discarded – undo
387 387
 			$this->apps = $this->appFetcher->get();
388 388
 		}
389 389
 
390
-		foreach($this->apps as $app) {
391
-			if($app['id'] === $appId) {
390
+		foreach ($this->apps as $app) {
391
+			if ($app['id'] === $appId) {
392 392
 				$currentVersion = OC_App::getAppVersion($appId);
393 393
 				$newestVersion = $app['releases'][0]['version'];
394 394
 				if (version_compare($newestVersion, $currentVersion, '>')) {
@@ -411,7 +411,7 @@  discard block
 block discarded – undo
411 411
 	 */
412 412
 	private function isInstalledFromGit($appId) {
413 413
 		$app = \OC_App::findAppInDirectories($appId);
414
-		if($app === false) {
414
+		if ($app === false) {
415 415
 			return false;
416 416
 		}
417 417
 		$basedir = $app['path'].'/'.$appId;
@@ -426,7 +426,7 @@  discard block
 block discarded – undo
426 426
 	 * The function will check if the app is already downloaded in the apps repository
427 427
 	 */
428 428
 	public function isDownloaded($name) {
429
-		foreach(\OC::$APPSROOTS as $dir) {
429
+		foreach (\OC::$APPSROOTS as $dir) {
430 430
 			$dirToTest  = $dir['path'];
431 431
 			$dirToTest .= '/';
432 432
 			$dirToTest .= $name;
@@ -454,14 +454,14 @@  discard block
 block discarded – undo
454 454
 	 * this has to be done by the function oc_app_uninstall().
455 455
 	 */
456 456
 	public function removeApp($appId) {
457
-		if($this->isDownloaded( $appId )) {
457
+		if ($this->isDownloaded($appId)) {
458 458
 			if (\OC::$server->getAppManager()->isShipped($appId)) {
459 459
 				return false;
460 460
 			}
461
-			$appDir = OC_App::getInstallPath() . '/' . $appId;
461
+			$appDir = OC_App::getInstallPath().'/'.$appId;
462 462
 			OC_Helper::rmdirr($appDir);
463 463
 			return true;
464
-		}else{
464
+		} else {
465 465
 			\OCP\Util::writeLog('core', 'can\'t remove app '.$appId.'. It is not installed.', \OCP\Util::ERROR);
466 466
 
467 467
 			return false;
@@ -477,8 +477,8 @@  discard block
 block discarded – undo
477 477
 	 */
478 478
 	public function installAppBundle(Bundle $bundle) {
479 479
 		$appIds = $bundle->getAppIdentifiers();
480
-		foreach($appIds as $appId) {
481
-			if(!$this->isDownloaded($appId)) {
480
+		foreach ($appIds as $appId) {
481
+			if (!$this->isDownloaded($appId)) {
482 482
 				$this->downloadApp($appId);
483 483
 			}
484 484
 			$this->installApp($appId);
@@ -502,13 +502,13 @@  discard block
 block discarded – undo
502 502
 		$appManager = \OC::$server->getAppManager();
503 503
 		$config = \OC::$server->getConfig();
504 504
 		$errors = [];
505
-		foreach(\OC::$APPSROOTS as $app_dir) {
506
-			if($dir = opendir( $app_dir['path'] )) {
507
-				while( false !== ( $filename = readdir( $dir ))) {
508
-					if( $filename[0] !== '.' and is_dir($app_dir['path']."/$filename") ) {
509
-						if( file_exists( $app_dir['path']."/$filename/appinfo/info.xml" )) {
510
-							if($config->getAppValue($filename, "installed_version", null) === null) {
511
-								$info=OC_App::getAppInfo($filename);
505
+		foreach (\OC::$APPSROOTS as $app_dir) {
506
+			if ($dir = opendir($app_dir['path'])) {
507
+				while (false !== ($filename = readdir($dir))) {
508
+					if ($filename[0] !== '.' and is_dir($app_dir['path']."/$filename")) {
509
+						if (file_exists($app_dir['path']."/$filename/appinfo/info.xml")) {
510
+							if ($config->getAppValue($filename, "installed_version", null) === null) {
511
+								$info = OC_App::getAppInfo($filename);
512 512
 								$enabled = isset($info['default_enable']);
513 513
 								if (($enabled || in_array($filename, $appManager->getAlwaysEnabledApps()))
514 514
 									  && $config->getAppValue($filename, 'enabled') !== 'no') {
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
 						}
532 532
 					}
533 533
 				}
534
-				closedir( $dir );
534
+				closedir($dir);
535 535
 			}
536 536
 		}
537 537
 
@@ -548,12 +548,12 @@  discard block
 block discarded – undo
548 548
 		$appPath = OC_App::getAppPath($app);
549 549
 		\OC_App::registerAutoloading($app, $appPath);
550 550
 
551
-		if(is_file("$appPath/appinfo/database.xml")) {
551
+		if (is_file("$appPath/appinfo/database.xml")) {
552 552
 			try {
553 553
 				OC_DB::createDbFromStructure("$appPath/appinfo/database.xml");
554 554
 			} catch (TableExistsException $e) {
555 555
 				throw new HintException(
556
-					'Failed to enable app ' . $app,
556
+					'Failed to enable app '.$app,
557 557
 					'Please ask for help via one of our <a href="https://nextcloud.com/support/" target="_blank" rel="noreferrer noopener">support channels</a>.',
558 558
 					0, $e
559 559
 				);
@@ -582,10 +582,10 @@  discard block
 block discarded – undo
582 582
 		}
583 583
 
584 584
 		//set remote/public handlers
585
-		foreach($info['remote'] as $name=>$path) {
585
+		foreach ($info['remote'] as $name=>$path) {
586 586
 			$config->setAppValue('core', 'remote_'.$name, $app.'/'.$path);
587 587
 		}
588
-		foreach($info['public'] as $name=>$path) {
588
+		foreach ($info['public'] as $name=>$path) {
589 589
 			$config->setAppValue('core', 'public_'.$name, $app.'/'.$path);
590 590
 		}
591 591
 
@@ -598,7 +598,7 @@  discard block
 block discarded – undo
598 598
 	 * @param string $script
599 599
 	 */
600 600
 	private static function includeAppScript($script) {
601
-		if ( file_exists($script) ){
601
+		if (file_exists($script)) {
602 602
 			include $script;
603 603
 		}
604 604
 	}
Please login to merge, or discard this patch.