@@ -30,7 +30,6 @@ |
||
30 | 30 | * StorageConnectionException constructor. |
31 | 31 | * |
32 | 32 | * @param string $message |
33 | - * @param int $code |
|
34 | 33 | * @param \Exception $previous |
35 | 34 | * @since 9.0.0 |
36 | 35 | */ |
@@ -27,16 +27,16 @@ |
||
27 | 27 | */ |
28 | 28 | class StorageConnectionException extends StorageNotAvailableException { |
29 | 29 | |
30 | - /** |
|
31 | - * StorageConnectionException constructor. |
|
32 | - * |
|
33 | - * @param string $message |
|
34 | - * @param int $code |
|
35 | - * @param \Exception $previous |
|
36 | - * @since 9.0.0 |
|
37 | - */ |
|
38 | - public function __construct($message = '', \Exception $previous = null) { |
|
39 | - $l = \OC::$server->getL10N('core'); |
|
40 | - parent::__construct($l->t('Storage connection error. %s', $message), self::STATUS_NETWORK_ERROR, $previous); |
|
41 | - } |
|
30 | + /** |
|
31 | + * StorageConnectionException constructor. |
|
32 | + * |
|
33 | + * @param string $message |
|
34 | + * @param int $code |
|
35 | + * @param \Exception $previous |
|
36 | + * @since 9.0.0 |
|
37 | + */ |
|
38 | + public function __construct($message = '', \Exception $previous = null) { |
|
39 | + $l = \OC::$server->getL10N('core'); |
|
40 | + parent::__construct($l->t('Storage connection error. %s', $message), self::STATUS_NETWORK_ERROR, $previous); |
|
41 | + } |
|
42 | 42 | } |
@@ -30,7 +30,6 @@ |
||
30 | 30 | * StorageTimeoutException constructor. |
31 | 31 | * |
32 | 32 | * @param string $message |
33 | - * @param int $code |
|
34 | 33 | * @param \Exception $previous |
35 | 34 | * @since 9.0.0 |
36 | 35 | */ |
@@ -27,16 +27,16 @@ |
||
27 | 27 | */ |
28 | 28 | class StorageTimeoutException extends StorageNotAvailableException { |
29 | 29 | |
30 | - /** |
|
31 | - * StorageTimeoutException constructor. |
|
32 | - * |
|
33 | - * @param string $message |
|
34 | - * @param int $code |
|
35 | - * @param \Exception $previous |
|
36 | - * @since 9.0.0 |
|
37 | - */ |
|
38 | - public function __construct($message = '', \Exception $previous = null) { |
|
39 | - $l = \OC::$server->getL10N('core'); |
|
40 | - parent::__construct($l->t('Storage connection timeout. %s', $message), self::STATUS_TIMEOUT, $previous); |
|
41 | - } |
|
30 | + /** |
|
31 | + * StorageTimeoutException constructor. |
|
32 | + * |
|
33 | + * @param string $message |
|
34 | + * @param int $code |
|
35 | + * @param \Exception $previous |
|
36 | + * @since 9.0.0 |
|
37 | + */ |
|
38 | + public function __construct($message = '', \Exception $previous = null) { |
|
39 | + $l = \OC::$server->getL10N('core'); |
|
40 | + parent::__construct($l->t('Storage connection timeout. %s', $message), self::STATUS_TIMEOUT, $previous); |
|
41 | + } |
|
42 | 42 | } |
@@ -32,18 +32,21 @@ discard block |
||
32 | 32 | /** |
33 | 33 | * @param string $message |
34 | 34 | * @since 9.1.0 |
35 | + * @return void |
|
35 | 36 | */ |
36 | 37 | public function info($message); |
37 | 38 | |
38 | 39 | /** |
39 | 40 | * @param string $message |
40 | 41 | * @since 9.1.0 |
42 | + * @return void |
|
41 | 43 | */ |
42 | 44 | public function warning($message); |
43 | 45 | |
44 | 46 | /** |
45 | 47 | * @param int $max |
46 | 48 | * @since 9.1.0 |
49 | + * @return void |
|
47 | 50 | */ |
48 | 51 | public function startProgress($max = 0); |
49 | 52 | |
@@ -51,12 +54,13 @@ discard block |
||
51 | 54 | * @param int $step |
52 | 55 | * @param string $description |
53 | 56 | * @since 9.1.0 |
57 | + * @return void |
|
54 | 58 | */ |
55 | 59 | public function advance($step = 1, $description = ''); |
56 | 60 | |
57 | 61 | /** |
58 | - * @param int $max |
|
59 | 62 | * @since 9.1.0 |
63 | + * @return void |
|
60 | 64 | */ |
61 | 65 | public function finishProgress(); |
62 | 66 |
@@ -30,35 +30,35 @@ |
||
30 | 30 | */ |
31 | 31 | interface IOutput { |
32 | 32 | |
33 | - /** |
|
34 | - * @param string $message |
|
35 | - * @since 9.1.0 |
|
36 | - */ |
|
37 | - public function info($message); |
|
33 | + /** |
|
34 | + * @param string $message |
|
35 | + * @since 9.1.0 |
|
36 | + */ |
|
37 | + public function info($message); |
|
38 | 38 | |
39 | - /** |
|
40 | - * @param string $message |
|
41 | - * @since 9.1.0 |
|
42 | - */ |
|
43 | - public function warning($message); |
|
39 | + /** |
|
40 | + * @param string $message |
|
41 | + * @since 9.1.0 |
|
42 | + */ |
|
43 | + public function warning($message); |
|
44 | 44 | |
45 | - /** |
|
46 | - * @param int $max |
|
47 | - * @since 9.1.0 |
|
48 | - */ |
|
49 | - public function startProgress($max = 0); |
|
45 | + /** |
|
46 | + * @param int $max |
|
47 | + * @since 9.1.0 |
|
48 | + */ |
|
49 | + public function startProgress($max = 0); |
|
50 | 50 | |
51 | - /** |
|
52 | - * @param int $step |
|
53 | - * @param string $description |
|
54 | - * @since 9.1.0 |
|
55 | - */ |
|
56 | - public function advance($step = 1, $description = ''); |
|
51 | + /** |
|
52 | + * @param int $step |
|
53 | + * @param string $description |
|
54 | + * @since 9.1.0 |
|
55 | + */ |
|
56 | + public function advance($step = 1, $description = ''); |
|
57 | 57 | |
58 | - /** |
|
59 | - * @param int $max |
|
60 | - * @since 9.1.0 |
|
61 | - */ |
|
62 | - public function finishProgress(); |
|
58 | + /** |
|
59 | + * @param int $max |
|
60 | + * @since 9.1.0 |
|
61 | + */ |
|
62 | + public function finishProgress(); |
|
63 | 63 | |
64 | 64 | } |
@@ -102,17 +102,19 @@ discard block |
||
102 | 102 | * with the same attributes |
103 | 103 | * |
104 | 104 | * @since 9.0.0 |
105 | + * @return void |
|
105 | 106 | */ |
106 | 107 | public function updateTag($tagId, $newName, $userVisible, $userAssignable); |
107 | 108 | |
108 | 109 | /** |
109 | 110 | * Delete the given tags from the database and all their relationships. |
110 | 111 | * |
111 | - * @param string|array $tagIds array of tag ids |
|
112 | + * @param string $tagIds array of tag ids |
|
112 | 113 | * |
113 | 114 | * @throws \OCP\SystemTag\TagNotFoundException if at least one tag did not exist |
114 | 115 | * |
115 | 116 | * @since 9.0.0 |
117 | + * @return void |
|
116 | 118 | */ |
117 | 119 | public function deleteTags($tagIds); |
118 | 120 | |
@@ -123,7 +125,7 @@ discard block |
||
123 | 125 | * @param ISystemTag $tag tag to check permission for |
124 | 126 | * @param IUser $user user to check permission for |
125 | 127 | * |
126 | - * @return true if the user is allowed to assign/unassign the tag, false otherwise |
|
128 | + * @return boolean if the user is allowed to assign/unassign the tag, false otherwise |
|
127 | 129 | * |
128 | 130 | * @since 9.1.0 |
129 | 131 | */ |
@@ -133,9 +135,9 @@ discard block |
||
133 | 135 | * Checks whether the given user is allowed to see the tag with the given id. |
134 | 136 | * |
135 | 137 | * @param ISystemTag $tag tag to check permission for |
136 | - * @param IUser $user user to check permission for |
|
138 | + * @param IUser $userId user to check permission for |
|
137 | 139 | * |
138 | - * @return true if the user can see the tag, false otherwise |
|
140 | + * @return boolean if the user can see the tag, false otherwise |
|
139 | 141 | * |
140 | 142 | * @since 9.1.0 |
141 | 143 | */ |
@@ -148,6 +150,7 @@ discard block |
||
148 | 150 | * @param string[] $groupIds group ids of groups that can assign/unassign the tag |
149 | 151 | * |
150 | 152 | * @since 9.1.0 |
153 | + * @return void |
|
151 | 154 | */ |
152 | 155 | public function setTagGroups(ISystemTag $tag, $groupIds); |
153 | 156 |
@@ -33,133 +33,133 @@ |
||
33 | 33 | */ |
34 | 34 | interface ISystemTagManager { |
35 | 35 | |
36 | - /** |
|
37 | - * Returns the tag objects matching the given tag ids. |
|
38 | - * |
|
39 | - * @param array|string $tagIds id or array of unique ids of the tag to retrieve |
|
40 | - * |
|
41 | - * @return \OCP\SystemTag\ISystemTag[] array of system tags with tag id as key |
|
42 | - * |
|
43 | - * @throws \InvalidArgumentException if at least one given tag ids is invalid (string instead of integer, etc.) |
|
44 | - * @throws \OCP\SystemTag\TagNotFoundException if at least one given tag ids did no exist |
|
45 | - * The message contains a json_encoded array of the ids that could not be found |
|
46 | - * |
|
47 | - * @since 9.0.0 |
|
48 | - */ |
|
49 | - public function getTagsByIds($tagIds); |
|
36 | + /** |
|
37 | + * Returns the tag objects matching the given tag ids. |
|
38 | + * |
|
39 | + * @param array|string $tagIds id or array of unique ids of the tag to retrieve |
|
40 | + * |
|
41 | + * @return \OCP\SystemTag\ISystemTag[] array of system tags with tag id as key |
|
42 | + * |
|
43 | + * @throws \InvalidArgumentException if at least one given tag ids is invalid (string instead of integer, etc.) |
|
44 | + * @throws \OCP\SystemTag\TagNotFoundException if at least one given tag ids did no exist |
|
45 | + * The message contains a json_encoded array of the ids that could not be found |
|
46 | + * |
|
47 | + * @since 9.0.0 |
|
48 | + */ |
|
49 | + public function getTagsByIds($tagIds); |
|
50 | 50 | |
51 | - /** |
|
52 | - * Returns the tag object matching the given attributes. |
|
53 | - * |
|
54 | - * @param string $tagName tag name |
|
55 | - * @param bool $userVisible whether the tag is visible by users |
|
56 | - * @param bool $userAssignable whether the tag is assignable by users |
|
57 | - * |
|
58 | - * @return \OCP\SystemTag\ISystemTag system tag |
|
59 | - * |
|
60 | - * @throws \OCP\SystemTag\TagNotFoundException if tag does not exist |
|
61 | - * |
|
62 | - * @since 9.0.0 |
|
63 | - */ |
|
64 | - public function getTag($tagName, $userVisible, $userAssignable); |
|
51 | + /** |
|
52 | + * Returns the tag object matching the given attributes. |
|
53 | + * |
|
54 | + * @param string $tagName tag name |
|
55 | + * @param bool $userVisible whether the tag is visible by users |
|
56 | + * @param bool $userAssignable whether the tag is assignable by users |
|
57 | + * |
|
58 | + * @return \OCP\SystemTag\ISystemTag system tag |
|
59 | + * |
|
60 | + * @throws \OCP\SystemTag\TagNotFoundException if tag does not exist |
|
61 | + * |
|
62 | + * @since 9.0.0 |
|
63 | + */ |
|
64 | + public function getTag($tagName, $userVisible, $userAssignable); |
|
65 | 65 | |
66 | - /** |
|
67 | - * Creates the tag object using the given attributes. |
|
68 | - * |
|
69 | - * @param string $tagName tag name |
|
70 | - * @param bool $userVisible whether the tag is visible by users |
|
71 | - * @param bool $userAssignable whether the tag is assignable by users |
|
72 | - * |
|
73 | - * @return \OCP\SystemTag\ISystemTag system tag |
|
74 | - * |
|
75 | - * @throws \OCP\SystemTag\TagAlreadyExistsException if tag already exists |
|
76 | - * |
|
77 | - * @since 9.0.0 |
|
78 | - */ |
|
79 | - public function createTag($tagName, $userVisible, $userAssignable); |
|
66 | + /** |
|
67 | + * Creates the tag object using the given attributes. |
|
68 | + * |
|
69 | + * @param string $tagName tag name |
|
70 | + * @param bool $userVisible whether the tag is visible by users |
|
71 | + * @param bool $userAssignable whether the tag is assignable by users |
|
72 | + * |
|
73 | + * @return \OCP\SystemTag\ISystemTag system tag |
|
74 | + * |
|
75 | + * @throws \OCP\SystemTag\TagAlreadyExistsException if tag already exists |
|
76 | + * |
|
77 | + * @since 9.0.0 |
|
78 | + */ |
|
79 | + public function createTag($tagName, $userVisible, $userAssignable); |
|
80 | 80 | |
81 | - /** |
|
82 | - * Returns all known tags, optionally filtered by visibility. |
|
83 | - * |
|
84 | - * @param bool|null $visibilityFilter filter by visibility if non-null |
|
85 | - * @param string $nameSearchPattern optional search pattern for the tag name |
|
86 | - * |
|
87 | - * @return \OCP\SystemTag\ISystemTag[] array of system tags or empty array if none found |
|
88 | - * |
|
89 | - * @since 9.0.0 |
|
90 | - */ |
|
91 | - public function getAllTags($visibilityFilter = null, $nameSearchPattern = null); |
|
81 | + /** |
|
82 | + * Returns all known tags, optionally filtered by visibility. |
|
83 | + * |
|
84 | + * @param bool|null $visibilityFilter filter by visibility if non-null |
|
85 | + * @param string $nameSearchPattern optional search pattern for the tag name |
|
86 | + * |
|
87 | + * @return \OCP\SystemTag\ISystemTag[] array of system tags or empty array if none found |
|
88 | + * |
|
89 | + * @since 9.0.0 |
|
90 | + */ |
|
91 | + public function getAllTags($visibilityFilter = null, $nameSearchPattern = null); |
|
92 | 92 | |
93 | - /** |
|
94 | - * Updates the given tag |
|
95 | - * |
|
96 | - * @param string $tagId tag id |
|
97 | - * @param string $newName the new tag name |
|
98 | - * @param bool $userVisible whether the tag is visible by users |
|
99 | - * @param bool $userAssignable whether the tag is assignable by users |
|
100 | - * |
|
101 | - * @throws \OCP\SystemTag\TagNotFoundException if tag with the given id does not exist |
|
102 | - * @throws \OCP\SystemTag\TagAlreadyExistsException if there is already another tag |
|
103 | - * with the same attributes |
|
104 | - * |
|
105 | - * @since 9.0.0 |
|
106 | - */ |
|
107 | - public function updateTag($tagId, $newName, $userVisible, $userAssignable); |
|
93 | + /** |
|
94 | + * Updates the given tag |
|
95 | + * |
|
96 | + * @param string $tagId tag id |
|
97 | + * @param string $newName the new tag name |
|
98 | + * @param bool $userVisible whether the tag is visible by users |
|
99 | + * @param bool $userAssignable whether the tag is assignable by users |
|
100 | + * |
|
101 | + * @throws \OCP\SystemTag\TagNotFoundException if tag with the given id does not exist |
|
102 | + * @throws \OCP\SystemTag\TagAlreadyExistsException if there is already another tag |
|
103 | + * with the same attributes |
|
104 | + * |
|
105 | + * @since 9.0.0 |
|
106 | + */ |
|
107 | + public function updateTag($tagId, $newName, $userVisible, $userAssignable); |
|
108 | 108 | |
109 | - /** |
|
110 | - * Delete the given tags from the database and all their relationships. |
|
111 | - * |
|
112 | - * @param string|array $tagIds array of tag ids |
|
113 | - * |
|
114 | - * @throws \OCP\SystemTag\TagNotFoundException if at least one tag did not exist |
|
115 | - * |
|
116 | - * @since 9.0.0 |
|
117 | - */ |
|
118 | - public function deleteTags($tagIds); |
|
109 | + /** |
|
110 | + * Delete the given tags from the database and all their relationships. |
|
111 | + * |
|
112 | + * @param string|array $tagIds array of tag ids |
|
113 | + * |
|
114 | + * @throws \OCP\SystemTag\TagNotFoundException if at least one tag did not exist |
|
115 | + * |
|
116 | + * @since 9.0.0 |
|
117 | + */ |
|
118 | + public function deleteTags($tagIds); |
|
119 | 119 | |
120 | - /** |
|
121 | - * Checks whether the given user is allowed to assign/unassign the tag with the |
|
122 | - * given id. |
|
123 | - * |
|
124 | - * @param ISystemTag $tag tag to check permission for |
|
125 | - * @param IUser $user user to check permission for |
|
126 | - * |
|
127 | - * @return true if the user is allowed to assign/unassign the tag, false otherwise |
|
128 | - * |
|
129 | - * @since 9.1.0 |
|
130 | - */ |
|
131 | - public function canUserAssignTag(ISystemTag $tag, IUser $user); |
|
120 | + /** |
|
121 | + * Checks whether the given user is allowed to assign/unassign the tag with the |
|
122 | + * given id. |
|
123 | + * |
|
124 | + * @param ISystemTag $tag tag to check permission for |
|
125 | + * @param IUser $user user to check permission for |
|
126 | + * |
|
127 | + * @return true if the user is allowed to assign/unassign the tag, false otherwise |
|
128 | + * |
|
129 | + * @since 9.1.0 |
|
130 | + */ |
|
131 | + public function canUserAssignTag(ISystemTag $tag, IUser $user); |
|
132 | 132 | |
133 | - /** |
|
134 | - * Checks whether the given user is allowed to see the tag with the given id. |
|
135 | - * |
|
136 | - * @param ISystemTag $tag tag to check permission for |
|
137 | - * @param IUser $user user to check permission for |
|
138 | - * |
|
139 | - * @return true if the user can see the tag, false otherwise |
|
140 | - * |
|
141 | - * @since 9.1.0 |
|
142 | - */ |
|
143 | - public function canUserSeeTag(ISystemTag $tag, IUser $userId); |
|
133 | + /** |
|
134 | + * Checks whether the given user is allowed to see the tag with the given id. |
|
135 | + * |
|
136 | + * @param ISystemTag $tag tag to check permission for |
|
137 | + * @param IUser $user user to check permission for |
|
138 | + * |
|
139 | + * @return true if the user can see the tag, false otherwise |
|
140 | + * |
|
141 | + * @since 9.1.0 |
|
142 | + */ |
|
143 | + public function canUserSeeTag(ISystemTag $tag, IUser $userId); |
|
144 | 144 | |
145 | - /** |
|
146 | - * Set groups that can assign a given tag. |
|
147 | - * |
|
148 | - * @param ISystemTag $tag tag for group assignment |
|
149 | - * @param string[] $groupIds group ids of groups that can assign/unassign the tag |
|
150 | - * |
|
151 | - * @since 9.1.0 |
|
152 | - */ |
|
153 | - public function setTagGroups(ISystemTag $tag, $groupIds); |
|
145 | + /** |
|
146 | + * Set groups that can assign a given tag. |
|
147 | + * |
|
148 | + * @param ISystemTag $tag tag for group assignment |
|
149 | + * @param string[] $groupIds group ids of groups that can assign/unassign the tag |
|
150 | + * |
|
151 | + * @since 9.1.0 |
|
152 | + */ |
|
153 | + public function setTagGroups(ISystemTag $tag, $groupIds); |
|
154 | 154 | |
155 | - /** |
|
156 | - * Get groups that can assign a given tag. |
|
157 | - * |
|
158 | - * @param ISystemTag $tag tag for group assignment |
|
159 | - * |
|
160 | - * @return string[] group ids of groups that can assign/unassign the tag |
|
161 | - * |
|
162 | - * @since 9.1.0 |
|
163 | - */ |
|
164 | - public function getTagGroups(ISystemTag $tag); |
|
155 | + /** |
|
156 | + * Get groups that can assign a given tag. |
|
157 | + * |
|
158 | + * @param ISystemTag $tag tag for group assignment |
|
159 | + * |
|
160 | + * @return string[] group ids of groups that can assign/unassign the tag |
|
161 | + * |
|
162 | + * @since 9.1.0 |
|
163 | + */ |
|
164 | + public function getTagGroups(ISystemTag $tag); |
|
165 | 165 | } |
@@ -100,8 +100,8 @@ |
||
100 | 100 | /** |
101 | 101 | * Return the relative date in relation to today. Returns something like "last hour" or "two month ago" |
102 | 102 | * @param int $timestamp unix timestamp |
103 | - * @param boolean $dateOnly |
|
104 | - * @return \OC_L10N_String human readable interpretation of the timestamp |
|
103 | + * @param integer $dateOnly |
|
104 | + * @return string human readable interpretation of the timestamp |
|
105 | 105 | * |
106 | 106 | * @deprecated 8.0.0 Use \OCP\Template::relative_modified_date() instead |
107 | 107 | */ |
@@ -50,7 +50,7 @@ discard block |
||
50 | 50 | * @deprecated 8.0.0 Use \OCP\Template::image_path() instead |
51 | 51 | */ |
52 | 52 | function image_path( $app, $image ) { |
53 | - return(\image_path( $app, $image )); |
|
53 | + return(\image_path( $app, $image )); |
|
54 | 54 | } |
55 | 55 | |
56 | 56 | |
@@ -61,7 +61,7 @@ discard block |
||
61 | 61 | * @deprecated 8.0.0 Use \OCP\Template::mimetype_icon() instead |
62 | 62 | */ |
63 | 63 | function mimetype_icon( $mimetype ) { |
64 | - return(\mimetype_icon( $mimetype )); |
|
64 | + return(\mimetype_icon( $mimetype )); |
|
65 | 65 | } |
66 | 66 | |
67 | 67 | /** |
@@ -71,7 +71,7 @@ discard block |
||
71 | 71 | * @deprecated 8.0.0 Use \OCP\Template::preview_icon() instead |
72 | 72 | */ |
73 | 73 | function preview_icon( $path ) { |
74 | - return(\preview_icon( $path )); |
|
74 | + return(\preview_icon( $path )); |
|
75 | 75 | } |
76 | 76 | |
77 | 77 | /** |
@@ -83,7 +83,7 @@ discard block |
||
83 | 83 | * @deprecated 8.0.0 Use \OCP\Template::publicPreview_icon() instead |
84 | 84 | */ |
85 | 85 | function publicPreview_icon ( $path, $token ) { |
86 | - return(\publicPreview_icon( $path, $token )); |
|
86 | + return(\publicPreview_icon( $path, $token )); |
|
87 | 87 | } |
88 | 88 | |
89 | 89 | /** |
@@ -94,7 +94,7 @@ discard block |
||
94 | 94 | * @deprecated 8.0.0 Use \OCP\Template::human_file_size() instead |
95 | 95 | */ |
96 | 96 | function human_file_size( $bytes ) { |
97 | - return(\human_file_size( $bytes )); |
|
97 | + return(\human_file_size( $bytes )); |
|
98 | 98 | } |
99 | 99 | |
100 | 100 | |
@@ -107,7 +107,7 @@ discard block |
||
107 | 107 | * @deprecated 8.0.0 Use \OCP\Template::relative_modified_date() instead |
108 | 108 | */ |
109 | 109 | function relative_modified_date( $timestamp, $dateOnly = false ) { |
110 | - return(\relative_modified_date($timestamp, null, $dateOnly)); |
|
110 | + return(\relative_modified_date($timestamp, null, $dateOnly)); |
|
111 | 111 | } |
112 | 112 | |
113 | 113 | |
@@ -118,7 +118,7 @@ discard block |
||
118 | 118 | * @deprecated 8.0.0 Use \OCP\Template::human_file_size() instead |
119 | 119 | */ |
120 | 120 | function simple_file_size($bytes) { |
121 | - return(\human_file_size($bytes)); |
|
121 | + return(\human_file_size($bytes)); |
|
122 | 122 | } |
123 | 123 | |
124 | 124 | |
@@ -131,7 +131,7 @@ discard block |
||
131 | 131 | * @deprecated 8.0.0 Use \OCP\Template::html_select_options() instead |
132 | 132 | */ |
133 | 133 | function html_select_options($options, $selected, $params=array()) { |
134 | - return(\html_select_options($options, $selected, $params)); |
|
134 | + return(\html_select_options($options, $selected, $params)); |
|
135 | 135 | } |
136 | 136 | |
137 | 137 | |
@@ -142,90 +142,90 @@ discard block |
||
142 | 142 | * @since 8.0.0 |
143 | 143 | */ |
144 | 144 | class Template extends \OC_Template { |
145 | - /** |
|
146 | - * Make OC_Helper::imagePath available as a simple function |
|
147 | - * |
|
148 | - * @see \OCP\IURLGenerator::imagePath |
|
149 | - * |
|
150 | - * @param string $app |
|
151 | - * @param string $image |
|
152 | - * @return string to the image |
|
153 | - * @since 8.0.0 |
|
154 | - */ |
|
155 | - public static function image_path($app, $image) { |
|
156 | - return \image_path($app, $image); |
|
157 | - } |
|
158 | - |
|
159 | - |
|
160 | - /** |
|
161 | - * Make OC_Helper::mimetypeIcon available as a simple function |
|
162 | - * |
|
163 | - * @param string $mimetype |
|
164 | - * @return string to the image of this file type. |
|
165 | - * @since 8.0.0 |
|
166 | - */ |
|
167 | - public static function mimetype_icon($mimetype) { |
|
168 | - return \mimetype_icon($mimetype); |
|
169 | - } |
|
170 | - |
|
171 | - /** |
|
172 | - * Make preview_icon available as a simple function |
|
173 | - * |
|
174 | - * @param string $path path to file |
|
175 | - * @return string to the preview of the image |
|
176 | - * @since 8.0.0 |
|
177 | - */ |
|
178 | - public static function preview_icon($path) { |
|
179 | - return \preview_icon($path); |
|
180 | - } |
|
181 | - |
|
182 | - /** |
|
183 | - * Make publicpreview_icon available as a simple function |
|
184 | - * Returns the path to the preview of the image. |
|
185 | - * |
|
186 | - * @param string $path of file |
|
187 | - * @param string $token |
|
188 | - * @return string link to the preview |
|
189 | - * @since 8.0.0 |
|
190 | - */ |
|
191 | - public static function publicPreview_icon($path, $token) { |
|
192 | - return \publicPreview_icon($path, $token); |
|
193 | - } |
|
194 | - |
|
195 | - /** |
|
196 | - * Make OC_Helper::humanFileSize available as a simple function |
|
197 | - * Example: 2048 to 2 kB. |
|
198 | - * |
|
199 | - * @param int $bytes in bytes |
|
200 | - * @return string size as string |
|
201 | - * @since 8.0.0 |
|
202 | - */ |
|
203 | - public static function human_file_size($bytes) { |
|
204 | - return \human_file_size($bytes); |
|
205 | - } |
|
206 | - |
|
207 | - /** |
|
208 | - * Return the relative date in relation to today. Returns something like "last hour" or "two month ago" |
|
209 | - * |
|
210 | - * @param int $timestamp unix timestamp |
|
211 | - * @param boolean $dateOnly |
|
212 | - * @return string human readable interpretation of the timestamp |
|
213 | - * @since 8.0.0 |
|
214 | - */ |
|
215 | - public static function relative_modified_date($timestamp, $dateOnly = false) { |
|
216 | - return \relative_modified_date($timestamp, null, $dateOnly); |
|
217 | - } |
|
218 | - |
|
219 | - /** |
|
220 | - * Generate html code for an options block. |
|
221 | - * |
|
222 | - * @param array $options the options |
|
223 | - * @param mixed $selected which one is selected? |
|
224 | - * @param array $params the parameters |
|
225 | - * @return string html options |
|
226 | - * @since 8.0.0 |
|
227 | - */ |
|
228 | - public static function html_select_options($options, $selected, $params=array()) { |
|
229 | - return \html_select_options($options, $selected, $params); |
|
230 | - } |
|
145 | + /** |
|
146 | + * Make OC_Helper::imagePath available as a simple function |
|
147 | + * |
|
148 | + * @see \OCP\IURLGenerator::imagePath |
|
149 | + * |
|
150 | + * @param string $app |
|
151 | + * @param string $image |
|
152 | + * @return string to the image |
|
153 | + * @since 8.0.0 |
|
154 | + */ |
|
155 | + public static function image_path($app, $image) { |
|
156 | + return \image_path($app, $image); |
|
157 | + } |
|
158 | + |
|
159 | + |
|
160 | + /** |
|
161 | + * Make OC_Helper::mimetypeIcon available as a simple function |
|
162 | + * |
|
163 | + * @param string $mimetype |
|
164 | + * @return string to the image of this file type. |
|
165 | + * @since 8.0.0 |
|
166 | + */ |
|
167 | + public static function mimetype_icon($mimetype) { |
|
168 | + return \mimetype_icon($mimetype); |
|
169 | + } |
|
170 | + |
|
171 | + /** |
|
172 | + * Make preview_icon available as a simple function |
|
173 | + * |
|
174 | + * @param string $path path to file |
|
175 | + * @return string to the preview of the image |
|
176 | + * @since 8.0.0 |
|
177 | + */ |
|
178 | + public static function preview_icon($path) { |
|
179 | + return \preview_icon($path); |
|
180 | + } |
|
181 | + |
|
182 | + /** |
|
183 | + * Make publicpreview_icon available as a simple function |
|
184 | + * Returns the path to the preview of the image. |
|
185 | + * |
|
186 | + * @param string $path of file |
|
187 | + * @param string $token |
|
188 | + * @return string link to the preview |
|
189 | + * @since 8.0.0 |
|
190 | + */ |
|
191 | + public static function publicPreview_icon($path, $token) { |
|
192 | + return \publicPreview_icon($path, $token); |
|
193 | + } |
|
194 | + |
|
195 | + /** |
|
196 | + * Make OC_Helper::humanFileSize available as a simple function |
|
197 | + * Example: 2048 to 2 kB. |
|
198 | + * |
|
199 | + * @param int $bytes in bytes |
|
200 | + * @return string size as string |
|
201 | + * @since 8.0.0 |
|
202 | + */ |
|
203 | + public static function human_file_size($bytes) { |
|
204 | + return \human_file_size($bytes); |
|
205 | + } |
|
206 | + |
|
207 | + /** |
|
208 | + * Return the relative date in relation to today. Returns something like "last hour" or "two month ago" |
|
209 | + * |
|
210 | + * @param int $timestamp unix timestamp |
|
211 | + * @param boolean $dateOnly |
|
212 | + * @return string human readable interpretation of the timestamp |
|
213 | + * @since 8.0.0 |
|
214 | + */ |
|
215 | + public static function relative_modified_date($timestamp, $dateOnly = false) { |
|
216 | + return \relative_modified_date($timestamp, null, $dateOnly); |
|
217 | + } |
|
218 | + |
|
219 | + /** |
|
220 | + * Generate html code for an options block. |
|
221 | + * |
|
222 | + * @param array $options the options |
|
223 | + * @param mixed $selected which one is selected? |
|
224 | + * @param array $params the parameters |
|
225 | + * @return string html options |
|
226 | + * @since 8.0.0 |
|
227 | + */ |
|
228 | + public static function html_select_options($options, $selected, $params=array()) { |
|
229 | + return \html_select_options($options, $selected, $params); |
|
230 | + } |
|
231 | 231 | } |
@@ -49,8 +49,8 @@ discard block |
||
49 | 49 | * @see \OCP\IURLGenerator::imagePath |
50 | 50 | * @deprecated 8.0.0 Use \OCP\Template::image_path() instead |
51 | 51 | */ |
52 | -function image_path( $app, $image ) { |
|
53 | - return(\image_path( $app, $image )); |
|
52 | +function image_path($app, $image) { |
|
53 | + return(\image_path($app, $image)); |
|
54 | 54 | } |
55 | 55 | |
56 | 56 | |
@@ -60,8 +60,8 @@ discard block |
||
60 | 60 | * @return string to the image of this file type. |
61 | 61 | * @deprecated 8.0.0 Use \OCP\Template::mimetype_icon() instead |
62 | 62 | */ |
63 | -function mimetype_icon( $mimetype ) { |
|
64 | - return(\mimetype_icon( $mimetype )); |
|
63 | +function mimetype_icon($mimetype) { |
|
64 | + return(\mimetype_icon($mimetype)); |
|
65 | 65 | } |
66 | 66 | |
67 | 67 | /** |
@@ -70,8 +70,8 @@ discard block |
||
70 | 70 | * @return string to the preview of the image |
71 | 71 | * @deprecated 8.0.0 Use \OCP\Template::preview_icon() instead |
72 | 72 | */ |
73 | -function preview_icon( $path ) { |
|
74 | - return(\preview_icon( $path )); |
|
73 | +function preview_icon($path) { |
|
74 | + return(\preview_icon($path)); |
|
75 | 75 | } |
76 | 76 | |
77 | 77 | /** |
@@ -82,8 +82,8 @@ discard block |
||
82 | 82 | * @return string link to the preview |
83 | 83 | * @deprecated 8.0.0 Use \OCP\Template::publicPreview_icon() instead |
84 | 84 | */ |
85 | -function publicPreview_icon ( $path, $token ) { |
|
86 | - return(\publicPreview_icon( $path, $token )); |
|
85 | +function publicPreview_icon($path, $token) { |
|
86 | + return(\publicPreview_icon($path, $token)); |
|
87 | 87 | } |
88 | 88 | |
89 | 89 | /** |
@@ -93,8 +93,8 @@ discard block |
||
93 | 93 | * @return string size as string |
94 | 94 | * @deprecated 8.0.0 Use \OCP\Template::human_file_size() instead |
95 | 95 | */ |
96 | -function human_file_size( $bytes ) { |
|
97 | - return(\human_file_size( $bytes )); |
|
96 | +function human_file_size($bytes) { |
|
97 | + return(\human_file_size($bytes)); |
|
98 | 98 | } |
99 | 99 | |
100 | 100 | |
@@ -106,7 +106,7 @@ discard block |
||
106 | 106 | * |
107 | 107 | * @deprecated 8.0.0 Use \OCP\Template::relative_modified_date() instead |
108 | 108 | */ |
109 | -function relative_modified_date( $timestamp, $dateOnly = false ) { |
|
109 | +function relative_modified_date($timestamp, $dateOnly = false) { |
|
110 | 110 | return(\relative_modified_date($timestamp, null, $dateOnly)); |
111 | 111 | } |
112 | 112 | |
@@ -130,7 +130,7 @@ discard block |
||
130 | 130 | * @return string html options |
131 | 131 | * @deprecated 8.0.0 Use \OCP\Template::html_select_options() instead |
132 | 132 | */ |
133 | -function html_select_options($options, $selected, $params=array()) { |
|
133 | +function html_select_options($options, $selected, $params = array()) { |
|
134 | 134 | return(\html_select_options($options, $selected, $params)); |
135 | 135 | } |
136 | 136 | |
@@ -225,7 +225,7 @@ discard block |
||
225 | 225 | * @return string html options |
226 | 226 | * @since 8.0.0 |
227 | 227 | */ |
228 | - public static function html_select_options($options, $selected, $params=array()) { |
|
228 | + public static function html_select_options($options, $selected, $params = array()) { |
|
229 | 229 | return \html_select_options($options, $selected, $params); |
230 | 230 | } |
231 | 231 | } |
@@ -544,7 +544,7 @@ |
||
544 | 544 | * @param array $input The array to work on |
545 | 545 | * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default) |
546 | 546 | * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
547 | - * @return array |
|
547 | + * @return string |
|
548 | 548 | * @since 4.5.0 |
549 | 549 | */ |
550 | 550 | public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') { |
@@ -57,655 +57,655 @@ |
||
57 | 57 | * @since 4.0.0 |
58 | 58 | */ |
59 | 59 | class Util { |
60 | - // consts for Logging |
|
61 | - const DEBUG=0; |
|
62 | - const INFO=1; |
|
63 | - const WARN=2; |
|
64 | - const ERROR=3; |
|
65 | - const FATAL=4; |
|
66 | - |
|
67 | - /** \OCP\Share\IManager */ |
|
68 | - private static $shareManager; |
|
69 | - |
|
70 | - /** |
|
71 | - * get the current installed version of ownCloud |
|
72 | - * @return array |
|
73 | - * @since 4.0.0 |
|
74 | - */ |
|
75 | - public static function getVersion() { |
|
76 | - return(\OC_Util::getVersion()); |
|
77 | - } |
|
60 | + // consts for Logging |
|
61 | + const DEBUG=0; |
|
62 | + const INFO=1; |
|
63 | + const WARN=2; |
|
64 | + const ERROR=3; |
|
65 | + const FATAL=4; |
|
66 | + |
|
67 | + /** \OCP\Share\IManager */ |
|
68 | + private static $shareManager; |
|
69 | + |
|
70 | + /** |
|
71 | + * get the current installed version of ownCloud |
|
72 | + * @return array |
|
73 | + * @since 4.0.0 |
|
74 | + */ |
|
75 | + public static function getVersion() { |
|
76 | + return(\OC_Util::getVersion()); |
|
77 | + } |
|
78 | 78 | |
79 | - /** |
|
80 | - * Set current update channel |
|
81 | - * @param string $channel |
|
82 | - * @since 8.1.0 |
|
83 | - */ |
|
84 | - public static function setChannel($channel) { |
|
85 | - \OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel); |
|
86 | - } |
|
79 | + /** |
|
80 | + * Set current update channel |
|
81 | + * @param string $channel |
|
82 | + * @since 8.1.0 |
|
83 | + */ |
|
84 | + public static function setChannel($channel) { |
|
85 | + \OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel); |
|
86 | + } |
|
87 | 87 | |
88 | - /** |
|
89 | - * Get current update channel |
|
90 | - * @return string |
|
91 | - * @since 8.1.0 |
|
92 | - */ |
|
93 | - public static function getChannel() { |
|
94 | - return \OC_Util::getChannel(); |
|
95 | - } |
|
96 | - |
|
97 | - /** |
|
98 | - * send an email |
|
99 | - * @param string $toaddress |
|
100 | - * @param string $toname |
|
101 | - * @param string $subject |
|
102 | - * @param string $mailtext |
|
103 | - * @param string $fromaddress |
|
104 | - * @param string $fromname |
|
105 | - * @param int $html |
|
106 | - * @param string $altbody |
|
107 | - * @param string $ccaddress |
|
108 | - * @param string $ccname |
|
109 | - * @param string $bcc |
|
110 | - * @deprecated 8.1.0 Use \OCP\Mail\IMailer instead |
|
111 | - * @since 4.0.0 |
|
112 | - */ |
|
113 | - public static function sendMail($toaddress, $toname, $subject, $mailtext, $fromaddress, $fromname, |
|
114 | - $html = 0, $altbody = '', $ccaddress = '', $ccname = '', $bcc = '') { |
|
115 | - $mailer = \OC::$server->getMailer(); |
|
116 | - $message = $mailer->createMessage(); |
|
117 | - $message->setTo([$toaddress => $toname]); |
|
118 | - $message->setSubject($subject); |
|
119 | - $message->setPlainBody($mailtext); |
|
120 | - $message->setFrom([$fromaddress => $fromname]); |
|
121 | - if($html === 1) { |
|
122 | - $message->setHTMLBody($altbody); |
|
123 | - } |
|
124 | - |
|
125 | - if($altbody === '') { |
|
126 | - $message->setHTMLBody($mailtext); |
|
127 | - $message->setPlainBody(''); |
|
128 | - } else { |
|
129 | - $message->setHtmlBody($mailtext); |
|
130 | - $message->setPlainBody($altbody); |
|
131 | - } |
|
132 | - |
|
133 | - if(!empty($ccaddress)) { |
|
134 | - if(!empty($ccname)) { |
|
135 | - $message->setCc([$ccaddress => $ccname]); |
|
136 | - } else { |
|
137 | - $message->setCc([$ccaddress]); |
|
138 | - } |
|
139 | - } |
|
140 | - if(!empty($bcc)) { |
|
141 | - $message->setBcc([$bcc]); |
|
142 | - } |
|
143 | - |
|
144 | - $mailer->send($message); |
|
145 | - } |
|
146 | - |
|
147 | - /** |
|
148 | - * write a message in the log |
|
149 | - * @param string $app |
|
150 | - * @param string $message |
|
151 | - * @param int $level |
|
152 | - * @since 4.0.0 |
|
153 | - * @deprecated 13.0.0 use log of \OCP\ILogger |
|
154 | - */ |
|
155 | - public static function writeLog( $app, $message, $level ) { |
|
156 | - $context = ['app' => $app]; |
|
157 | - \OC::$server->getLogger()->log($level, $message, $context); |
|
158 | - } |
|
159 | - |
|
160 | - /** |
|
161 | - * write exception into the log |
|
162 | - * @param string $app app name |
|
163 | - * @param \Exception $ex exception to log |
|
164 | - * @param int $level log level, defaults to \OCP\Util::FATAL |
|
165 | - * @since ....0.0 - parameter $level was added in 7.0.0 |
|
166 | - * @deprecated 8.2.0 use logException of \OCP\ILogger |
|
167 | - */ |
|
168 | - public static function logException( $app, \Exception $ex, $level = \OCP\Util::FATAL ) { |
|
169 | - \OC::$server->getLogger()->logException($ex, ['app' => $app]); |
|
170 | - } |
|
171 | - |
|
172 | - /** |
|
173 | - * check if sharing is disabled for the current user |
|
174 | - * |
|
175 | - * @return boolean |
|
176 | - * @since 7.0.0 |
|
177 | - * @deprecated 9.1.0 Use \OC::$server->getShareManager()->sharingDisabledForUser |
|
178 | - */ |
|
179 | - public static function isSharingDisabledForUser() { |
|
180 | - if (self::$shareManager === null) { |
|
181 | - self::$shareManager = \OC::$server->getShareManager(); |
|
182 | - } |
|
183 | - |
|
184 | - $user = \OC::$server->getUserSession()->getUser(); |
|
185 | - if ($user !== null) { |
|
186 | - $user = $user->getUID(); |
|
187 | - } |
|
188 | - |
|
189 | - return self::$shareManager->sharingDisabledForUser($user); |
|
190 | - } |
|
191 | - |
|
192 | - /** |
|
193 | - * get l10n object |
|
194 | - * @param string $application |
|
195 | - * @param string|null $language |
|
196 | - * @return \OCP\IL10N |
|
197 | - * @since 6.0.0 - parameter $language was added in 8.0.0 |
|
198 | - */ |
|
199 | - public static function getL10N($application, $language = null) { |
|
200 | - return \OC::$server->getL10N($application, $language); |
|
201 | - } |
|
202 | - |
|
203 | - /** |
|
204 | - * add a css file |
|
205 | - * @param string $application |
|
206 | - * @param string $file |
|
207 | - * @since 4.0.0 |
|
208 | - */ |
|
209 | - public static function addStyle( $application, $file = null ) { |
|
210 | - \OC_Util::addStyle( $application, $file ); |
|
211 | - } |
|
212 | - |
|
213 | - /** |
|
214 | - * add a javascript file |
|
215 | - * @param string $application |
|
216 | - * @param string $file |
|
217 | - * @since 4.0.0 |
|
218 | - */ |
|
219 | - public static function addScript( $application, $file = null ) { |
|
220 | - \OC_Util::addScript( $application, $file ); |
|
221 | - } |
|
222 | - |
|
223 | - /** |
|
224 | - * Add a translation JS file |
|
225 | - * @param string $application application id |
|
226 | - * @param string $languageCode language code, defaults to the current locale |
|
227 | - * @since 8.0.0 |
|
228 | - */ |
|
229 | - public static function addTranslations($application, $languageCode = null) { |
|
230 | - \OC_Util::addTranslations($application, $languageCode); |
|
231 | - } |
|
232 | - |
|
233 | - /** |
|
234 | - * Add a custom element to the header |
|
235 | - * If $text is null then the element will be written as empty element. |
|
236 | - * So use "" to get a closing tag. |
|
237 | - * @param string $tag tag name of the element |
|
238 | - * @param array $attributes array of attributes for the element |
|
239 | - * @param string $text the text content for the element |
|
240 | - * @since 4.0.0 |
|
241 | - */ |
|
242 | - public static function addHeader($tag, $attributes, $text=null) { |
|
243 | - \OC_Util::addHeader($tag, $attributes, $text); |
|
244 | - } |
|
245 | - |
|
246 | - /** |
|
247 | - * formats a timestamp in the "right" way |
|
248 | - * @param int $timestamp $timestamp |
|
249 | - * @param bool $dateOnly option to omit time from the result |
|
250 | - * @param DateTimeZone|string $timeZone where the given timestamp shall be converted to |
|
251 | - * @return string timestamp |
|
252 | - * |
|
253 | - * @deprecated 8.0.0 Use \OC::$server->query('DateTimeFormatter') instead |
|
254 | - * @since 4.0.0 |
|
255 | - */ |
|
256 | - public static function formatDate($timestamp, $dateOnly=false, $timeZone = null) { |
|
257 | - return(\OC_Util::formatDate($timestamp, $dateOnly, $timeZone)); |
|
258 | - } |
|
259 | - |
|
260 | - /** |
|
261 | - * check if some encrypted files are stored |
|
262 | - * @return bool |
|
263 | - * |
|
264 | - * @deprecated 8.1.0 No longer required |
|
265 | - * @since 6.0.0 |
|
266 | - */ |
|
267 | - public static function encryptedFiles() { |
|
268 | - return false; |
|
269 | - } |
|
270 | - |
|
271 | - /** |
|
272 | - * Creates an absolute url to the given app and file. |
|
273 | - * @param string $app app |
|
274 | - * @param string $file file |
|
275 | - * @param array $args array with param=>value, will be appended to the returned url |
|
276 | - * The value of $args will be urlencoded |
|
277 | - * @return string the url |
|
278 | - * @since 4.0.0 - parameter $args was added in 4.5.0 |
|
279 | - */ |
|
280 | - public static function linkToAbsolute( $app, $file, $args = array() ) { |
|
281 | - $urlGenerator = \OC::$server->getURLGenerator(); |
|
282 | - return $urlGenerator->getAbsoluteURL( |
|
283 | - $urlGenerator->linkTo($app, $file, $args) |
|
284 | - ); |
|
285 | - } |
|
286 | - |
|
287 | - /** |
|
288 | - * Creates an absolute url for remote use. |
|
289 | - * @param string $service id |
|
290 | - * @return string the url |
|
291 | - * @since 4.0.0 |
|
292 | - */ |
|
293 | - public static function linkToRemote( $service ) { |
|
294 | - $urlGenerator = \OC::$server->getURLGenerator(); |
|
295 | - $remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service; |
|
296 | - return $urlGenerator->getAbsoluteURL( |
|
297 | - $remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '') |
|
298 | - ); |
|
299 | - } |
|
300 | - |
|
301 | - /** |
|
302 | - * Creates an absolute url for public use |
|
303 | - * @param string $service id |
|
304 | - * @return string the url |
|
305 | - * @since 4.5.0 |
|
306 | - */ |
|
307 | - public static function linkToPublic($service) { |
|
308 | - return \OC_Helper::linkToPublic($service); |
|
309 | - } |
|
310 | - |
|
311 | - /** |
|
312 | - * Creates an url using a defined route |
|
313 | - * @param string $route |
|
314 | - * @param array $parameters |
|
315 | - * @internal param array $args with param=>value, will be appended to the returned url |
|
316 | - * @return string the url |
|
317 | - * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->linkToRoute($route, $parameters) |
|
318 | - * @since 5.0.0 |
|
319 | - */ |
|
320 | - public static function linkToRoute( $route, $parameters = array() ) { |
|
321 | - return \OC::$server->getURLGenerator()->linkToRoute($route, $parameters); |
|
322 | - } |
|
323 | - |
|
324 | - /** |
|
325 | - * Creates an url to the given app and file |
|
326 | - * @param string $app app |
|
327 | - * @param string $file file |
|
328 | - * @param array $args array with param=>value, will be appended to the returned url |
|
329 | - * The value of $args will be urlencoded |
|
330 | - * @return string the url |
|
331 | - * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->linkTo($app, $file, $args) |
|
332 | - * @since 4.0.0 - parameter $args was added in 4.5.0 |
|
333 | - */ |
|
334 | - public static function linkTo( $app, $file, $args = array() ) { |
|
335 | - return \OC::$server->getURLGenerator()->linkTo($app, $file, $args); |
|
336 | - } |
|
337 | - |
|
338 | - /** |
|
339 | - * Returns the server host, even if the website uses one or more reverse proxy |
|
340 | - * @return string the server host |
|
341 | - * @deprecated 8.1.0 Use \OCP\IRequest::getServerHost |
|
342 | - * @since 4.0.0 |
|
343 | - */ |
|
344 | - public static function getServerHost() { |
|
345 | - return \OC::$server->getRequest()->getServerHost(); |
|
346 | - } |
|
347 | - |
|
348 | - /** |
|
349 | - * Returns the server host name without an eventual port number |
|
350 | - * @return string the server hostname |
|
351 | - * @since 5.0.0 |
|
352 | - */ |
|
353 | - public static function getServerHostName() { |
|
354 | - $host_name = self::getServerHost(); |
|
355 | - // strip away port number (if existing) |
|
356 | - $colon_pos = strpos($host_name, ':'); |
|
357 | - if ($colon_pos != FALSE) { |
|
358 | - $host_name = substr($host_name, 0, $colon_pos); |
|
359 | - } |
|
360 | - return $host_name; |
|
361 | - } |
|
362 | - |
|
363 | - /** |
|
364 | - * Returns the default email address |
|
365 | - * @param string $user_part the user part of the address |
|
366 | - * @return string the default email address |
|
367 | - * |
|
368 | - * Assembles a default email address (using the server hostname |
|
369 | - * and the given user part, and returns it |
|
370 | - * Example: when given lostpassword-noreply as $user_part param, |
|
371 | - * and is currently accessed via http(s)://example.com/, |
|
372 | - * it would return '[email protected]' |
|
373 | - * |
|
374 | - * If the configuration value 'mail_from_address' is set in |
|
375 | - * config.php, this value will override the $user_part that |
|
376 | - * is passed to this function |
|
377 | - * @since 5.0.0 |
|
378 | - */ |
|
379 | - public static function getDefaultEmailAddress($user_part) { |
|
380 | - $config = \OC::$server->getConfig(); |
|
381 | - $user_part = $config->getSystemValue('mail_from_address', $user_part); |
|
382 | - $host_name = self::getServerHostName(); |
|
383 | - $host_name = $config->getSystemValue('mail_domain', $host_name); |
|
384 | - $defaultEmailAddress = $user_part.'@'.$host_name; |
|
385 | - |
|
386 | - $mailer = \OC::$server->getMailer(); |
|
387 | - if ($mailer->validateMailAddress($defaultEmailAddress)) { |
|
388 | - return $defaultEmailAddress; |
|
389 | - } |
|
390 | - |
|
391 | - // in case we cannot build a valid email address from the hostname let's fallback to 'localhost.localdomain' |
|
392 | - return $user_part.'@localhost.localdomain'; |
|
393 | - } |
|
394 | - |
|
395 | - /** |
|
396 | - * Returns the server protocol. It respects reverse proxy servers and load balancers |
|
397 | - * @return string the server protocol |
|
398 | - * @deprecated 8.1.0 Use \OCP\IRequest::getServerProtocol |
|
399 | - * @since 4.5.0 |
|
400 | - */ |
|
401 | - public static function getServerProtocol() { |
|
402 | - return \OC::$server->getRequest()->getServerProtocol(); |
|
403 | - } |
|
404 | - |
|
405 | - /** |
|
406 | - * Returns the request uri, even if the website uses one or more reverse proxies |
|
407 | - * @return string the request uri |
|
408 | - * @deprecated 8.1.0 Use \OCP\IRequest::getRequestUri |
|
409 | - * @since 5.0.0 |
|
410 | - */ |
|
411 | - public static function getRequestUri() { |
|
412 | - return \OC::$server->getRequest()->getRequestUri(); |
|
413 | - } |
|
414 | - |
|
415 | - /** |
|
416 | - * Returns the script name, even if the website uses one or more reverse proxies |
|
417 | - * @return string the script name |
|
418 | - * @deprecated 8.1.0 Use \OCP\IRequest::getScriptName |
|
419 | - * @since 5.0.0 |
|
420 | - */ |
|
421 | - public static function getScriptName() { |
|
422 | - return \OC::$server->getRequest()->getScriptName(); |
|
423 | - } |
|
424 | - |
|
425 | - /** |
|
426 | - * Creates path to an image |
|
427 | - * @param string $app app |
|
428 | - * @param string $image image name |
|
429 | - * @return string the url |
|
430 | - * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->imagePath($app, $image) |
|
431 | - * @since 4.0.0 |
|
432 | - */ |
|
433 | - public static function imagePath( $app, $image ) { |
|
434 | - return \OC::$server->getURLGenerator()->imagePath($app, $image); |
|
435 | - } |
|
436 | - |
|
437 | - /** |
|
438 | - * Make a human file size (2048 to 2 kB) |
|
439 | - * @param int $bytes file size in bytes |
|
440 | - * @return string a human readable file size |
|
441 | - * @since 4.0.0 |
|
442 | - */ |
|
443 | - public static function humanFileSize( $bytes ) { |
|
444 | - return(\OC_Helper::humanFileSize( $bytes )); |
|
445 | - } |
|
446 | - |
|
447 | - /** |
|
448 | - * Make a computer file size (2 kB to 2048) |
|
449 | - * @param string $str file size in a fancy format |
|
450 | - * @return int a file size in bytes |
|
451 | - * |
|
452 | - * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418 |
|
453 | - * @since 4.0.0 |
|
454 | - */ |
|
455 | - public static function computerFileSize( $str ) { |
|
456 | - return(\OC_Helper::computerFileSize( $str )); |
|
457 | - } |
|
458 | - |
|
459 | - /** |
|
460 | - * connects a function to a hook |
|
461 | - * |
|
462 | - * @param string $signalClass class name of emitter |
|
463 | - * @param string $signalName name of signal |
|
464 | - * @param string|object $slotClass class name of slot |
|
465 | - * @param string $slotName name of slot |
|
466 | - * @return bool |
|
467 | - * |
|
468 | - * This function makes it very easy to connect to use hooks. |
|
469 | - * |
|
470 | - * TODO: write example |
|
471 | - * @since 4.0.0 |
|
472 | - */ |
|
473 | - static public function connectHook($signalClass, $signalName, $slotClass, $slotName ) { |
|
474 | - return(\OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName )); |
|
475 | - } |
|
476 | - |
|
477 | - /** |
|
478 | - * Emits a signal. To get data from the slot use references! |
|
479 | - * @param string $signalclass class name of emitter |
|
480 | - * @param string $signalname name of signal |
|
481 | - * @param array $params default: array() array with additional data |
|
482 | - * @return bool true if slots exists or false if not |
|
483 | - * |
|
484 | - * TODO: write example |
|
485 | - * @since 4.0.0 |
|
486 | - */ |
|
487 | - static public function emitHook( $signalclass, $signalname, $params = array()) { |
|
488 | - return(\OC_Hook::emit( $signalclass, $signalname, $params )); |
|
489 | - } |
|
490 | - |
|
491 | - /** |
|
492 | - * Cached encrypted CSRF token. Some static unit-tests of ownCloud compare |
|
493 | - * multiple OC_Template elements which invoke `callRegister`. If the value |
|
494 | - * would not be cached these unit-tests would fail. |
|
495 | - * @var string |
|
496 | - */ |
|
497 | - private static $token = ''; |
|
498 | - |
|
499 | - /** |
|
500 | - * Register an get/post call. This is important to prevent CSRF attacks |
|
501 | - * @since 4.5.0 |
|
502 | - */ |
|
503 | - public static function callRegister() { |
|
504 | - if(self::$token === '') { |
|
505 | - self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue(); |
|
506 | - } |
|
507 | - return self::$token; |
|
508 | - } |
|
509 | - |
|
510 | - /** |
|
511 | - * Check an ajax get/post call if the request token is valid. exit if not. |
|
512 | - * @since 4.5.0 |
|
513 | - * @deprecated 9.0.0 Use annotations based on the app framework. |
|
514 | - */ |
|
515 | - public static function callCheck() { |
|
516 | - if(!\OC::$server->getRequest()->passesStrictCookieCheck()) { |
|
517 | - header('Location: '.\OC::$WEBROOT); |
|
518 | - exit(); |
|
519 | - } |
|
520 | - |
|
521 | - if (!(\OC::$server->getRequest()->passesCSRFCheck())) { |
|
522 | - exit(); |
|
523 | - } |
|
524 | - } |
|
525 | - |
|
526 | - /** |
|
527 | - * Used to sanitize HTML |
|
528 | - * |
|
529 | - * This function is used to sanitize HTML and should be applied on any |
|
530 | - * string or array of strings before displaying it on a web page. |
|
531 | - * |
|
532 | - * @param string|array $value |
|
533 | - * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter. |
|
534 | - * @since 4.5.0 |
|
535 | - */ |
|
536 | - public static function sanitizeHTML($value) { |
|
537 | - return \OC_Util::sanitizeHTML($value); |
|
538 | - } |
|
539 | - |
|
540 | - /** |
|
541 | - * Public function to encode url parameters |
|
542 | - * |
|
543 | - * This function is used to encode path to file before output. |
|
544 | - * Encoding is done according to RFC 3986 with one exception: |
|
545 | - * Character '/' is preserved as is. |
|
546 | - * |
|
547 | - * @param string $component part of URI to encode |
|
548 | - * @return string |
|
549 | - * @since 6.0.0 |
|
550 | - */ |
|
551 | - public static function encodePath($component) { |
|
552 | - return(\OC_Util::encodePath($component)); |
|
553 | - } |
|
554 | - |
|
555 | - /** |
|
556 | - * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. |
|
557 | - * |
|
558 | - * @param array $input The array to work on |
|
559 | - * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default) |
|
560 | - * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
561 | - * @return array |
|
562 | - * @since 4.5.0 |
|
563 | - */ |
|
564 | - public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') { |
|
565 | - return(\OC_Helper::mb_array_change_key_case($input, $case, $encoding)); |
|
566 | - } |
|
567 | - |
|
568 | - /** |
|
569 | - * replaces a copy of string delimited by the start and (optionally) length parameters with the string given in replacement. |
|
570 | - * |
|
571 | - * @param string $string The input string. Opposite to the PHP build-in function does not accept an array. |
|
572 | - * @param string $replacement The replacement string. |
|
573 | - * @param int $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string. |
|
574 | - * @param int $length Length of the part to be replaced |
|
575 | - * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
576 | - * @return string |
|
577 | - * @since 4.5.0 |
|
578 | - * @deprecated 8.2.0 Use substr_replace() instead. |
|
579 | - */ |
|
580 | - public static function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = 'UTF-8') { |
|
581 | - return substr_replace($string, $replacement, $start, $length); |
|
582 | - } |
|
583 | - |
|
584 | - /** |
|
585 | - * Replace all occurrences of the search string with the replacement string |
|
586 | - * |
|
587 | - * @param string $search The value being searched for, otherwise known as the needle. String. |
|
588 | - * @param string $replace The replacement string. |
|
589 | - * @param string $subject The string or array being searched and replaced on, otherwise known as the haystack. |
|
590 | - * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
591 | - * @param int $count If passed, this will be set to the number of replacements performed. |
|
592 | - * @return string |
|
593 | - * @since 4.5.0 |
|
594 | - * @deprecated 8.2.0 Use str_replace() instead. |
|
595 | - */ |
|
596 | - public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { |
|
597 | - return str_replace($search, $replace, $subject, $count); |
|
598 | - } |
|
599 | - |
|
600 | - /** |
|
601 | - * performs a search in a nested array |
|
602 | - * |
|
603 | - * @param array $haystack the array to be searched |
|
604 | - * @param string $needle the search string |
|
605 | - * @param int $index optional, only search this key name |
|
606 | - * @return mixed the key of the matching field, otherwise false |
|
607 | - * @since 4.5.0 |
|
608 | - */ |
|
609 | - public static function recursiveArraySearch($haystack, $needle, $index = null) { |
|
610 | - return(\OC_Helper::recursiveArraySearch($haystack, $needle, $index)); |
|
611 | - } |
|
612 | - |
|
613 | - /** |
|
614 | - * calculates the maximum upload size respecting system settings, free space and user quota |
|
615 | - * |
|
616 | - * @param string $dir the current folder where the user currently operates |
|
617 | - * @param int $free the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly |
|
618 | - * @return int number of bytes representing |
|
619 | - * @since 5.0.0 |
|
620 | - */ |
|
621 | - public static function maxUploadFilesize($dir, $free = null) { |
|
622 | - return \OC_Helper::maxUploadFilesize($dir, $free); |
|
623 | - } |
|
624 | - |
|
625 | - /** |
|
626 | - * Calculate free space left within user quota |
|
627 | - * @param string $dir the current folder where the user currently operates |
|
628 | - * @return int number of bytes representing |
|
629 | - * @since 7.0.0 |
|
630 | - */ |
|
631 | - public static function freeSpace($dir) { |
|
632 | - return \OC_Helper::freeSpace($dir); |
|
633 | - } |
|
634 | - |
|
635 | - /** |
|
636 | - * Calculate PHP upload limit |
|
637 | - * |
|
638 | - * @return int number of bytes representing |
|
639 | - * @since 7.0.0 |
|
640 | - */ |
|
641 | - public static function uploadLimit() { |
|
642 | - return \OC_Helper::uploadLimit(); |
|
643 | - } |
|
644 | - |
|
645 | - /** |
|
646 | - * Returns whether the given file name is valid |
|
647 | - * @param string $file file name to check |
|
648 | - * @return bool true if the file name is valid, false otherwise |
|
649 | - * @deprecated 8.1.0 use \OC\Files\View::verifyPath() |
|
650 | - * @since 7.0.0 |
|
651 | - */ |
|
652 | - public static function isValidFileName($file) { |
|
653 | - return \OC_Util::isValidFileName($file); |
|
654 | - } |
|
655 | - |
|
656 | - /** |
|
657 | - * Generates a cryptographic secure pseudo-random string |
|
658 | - * @param int $length of the random string |
|
659 | - * @return string |
|
660 | - * @deprecated 8.0.0 Use \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate($length); instead |
|
661 | - * @since 7.0.0 |
|
662 | - */ |
|
663 | - public static function generateRandomBytes($length = 30) { |
|
664 | - return \OC::$server->getSecureRandom()->generate($length, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS); |
|
665 | - } |
|
666 | - |
|
667 | - /** |
|
668 | - * Compare two strings to provide a natural sort |
|
669 | - * @param string $a first string to compare |
|
670 | - * @param string $b second string to compare |
|
671 | - * @return -1 if $b comes before $a, 1 if $a comes before $b |
|
672 | - * or 0 if the strings are identical |
|
673 | - * @since 7.0.0 |
|
674 | - */ |
|
675 | - public static function naturalSortCompare($a, $b) { |
|
676 | - return \OC\NaturalSort::getInstance()->compare($a, $b); |
|
677 | - } |
|
678 | - |
|
679 | - /** |
|
680 | - * check if a password is required for each public link |
|
681 | - * @return boolean |
|
682 | - * @since 7.0.0 |
|
683 | - */ |
|
684 | - public static function isPublicLinkPasswordRequired() { |
|
685 | - return \OC_Util::isPublicLinkPasswordRequired(); |
|
686 | - } |
|
687 | - |
|
688 | - /** |
|
689 | - * check if share API enforces a default expire date |
|
690 | - * @return boolean |
|
691 | - * @since 8.0.0 |
|
692 | - */ |
|
693 | - public static function isDefaultExpireDateEnforced() { |
|
694 | - return \OC_Util::isDefaultExpireDateEnforced(); |
|
695 | - } |
|
696 | - |
|
697 | - protected static $needUpgradeCache = null; |
|
698 | - |
|
699 | - /** |
|
700 | - * Checks whether the current version needs upgrade. |
|
701 | - * |
|
702 | - * @return bool true if upgrade is needed, false otherwise |
|
703 | - * @since 7.0.0 |
|
704 | - */ |
|
705 | - public static function needUpgrade() { |
|
706 | - if (!isset(self::$needUpgradeCache)) { |
|
707 | - self::$needUpgradeCache=\OC_Util::needUpgrade(\OC::$server->getSystemConfig()); |
|
708 | - } |
|
709 | - return self::$needUpgradeCache; |
|
710 | - } |
|
88 | + /** |
|
89 | + * Get current update channel |
|
90 | + * @return string |
|
91 | + * @since 8.1.0 |
|
92 | + */ |
|
93 | + public static function getChannel() { |
|
94 | + return \OC_Util::getChannel(); |
|
95 | + } |
|
96 | + |
|
97 | + /** |
|
98 | + * send an email |
|
99 | + * @param string $toaddress |
|
100 | + * @param string $toname |
|
101 | + * @param string $subject |
|
102 | + * @param string $mailtext |
|
103 | + * @param string $fromaddress |
|
104 | + * @param string $fromname |
|
105 | + * @param int $html |
|
106 | + * @param string $altbody |
|
107 | + * @param string $ccaddress |
|
108 | + * @param string $ccname |
|
109 | + * @param string $bcc |
|
110 | + * @deprecated 8.1.0 Use \OCP\Mail\IMailer instead |
|
111 | + * @since 4.0.0 |
|
112 | + */ |
|
113 | + public static function sendMail($toaddress, $toname, $subject, $mailtext, $fromaddress, $fromname, |
|
114 | + $html = 0, $altbody = '', $ccaddress = '', $ccname = '', $bcc = '') { |
|
115 | + $mailer = \OC::$server->getMailer(); |
|
116 | + $message = $mailer->createMessage(); |
|
117 | + $message->setTo([$toaddress => $toname]); |
|
118 | + $message->setSubject($subject); |
|
119 | + $message->setPlainBody($mailtext); |
|
120 | + $message->setFrom([$fromaddress => $fromname]); |
|
121 | + if($html === 1) { |
|
122 | + $message->setHTMLBody($altbody); |
|
123 | + } |
|
124 | + |
|
125 | + if($altbody === '') { |
|
126 | + $message->setHTMLBody($mailtext); |
|
127 | + $message->setPlainBody(''); |
|
128 | + } else { |
|
129 | + $message->setHtmlBody($mailtext); |
|
130 | + $message->setPlainBody($altbody); |
|
131 | + } |
|
132 | + |
|
133 | + if(!empty($ccaddress)) { |
|
134 | + if(!empty($ccname)) { |
|
135 | + $message->setCc([$ccaddress => $ccname]); |
|
136 | + } else { |
|
137 | + $message->setCc([$ccaddress]); |
|
138 | + } |
|
139 | + } |
|
140 | + if(!empty($bcc)) { |
|
141 | + $message->setBcc([$bcc]); |
|
142 | + } |
|
143 | + |
|
144 | + $mailer->send($message); |
|
145 | + } |
|
146 | + |
|
147 | + /** |
|
148 | + * write a message in the log |
|
149 | + * @param string $app |
|
150 | + * @param string $message |
|
151 | + * @param int $level |
|
152 | + * @since 4.0.0 |
|
153 | + * @deprecated 13.0.0 use log of \OCP\ILogger |
|
154 | + */ |
|
155 | + public static function writeLog( $app, $message, $level ) { |
|
156 | + $context = ['app' => $app]; |
|
157 | + \OC::$server->getLogger()->log($level, $message, $context); |
|
158 | + } |
|
159 | + |
|
160 | + /** |
|
161 | + * write exception into the log |
|
162 | + * @param string $app app name |
|
163 | + * @param \Exception $ex exception to log |
|
164 | + * @param int $level log level, defaults to \OCP\Util::FATAL |
|
165 | + * @since ....0.0 - parameter $level was added in 7.0.0 |
|
166 | + * @deprecated 8.2.0 use logException of \OCP\ILogger |
|
167 | + */ |
|
168 | + public static function logException( $app, \Exception $ex, $level = \OCP\Util::FATAL ) { |
|
169 | + \OC::$server->getLogger()->logException($ex, ['app' => $app]); |
|
170 | + } |
|
171 | + |
|
172 | + /** |
|
173 | + * check if sharing is disabled for the current user |
|
174 | + * |
|
175 | + * @return boolean |
|
176 | + * @since 7.0.0 |
|
177 | + * @deprecated 9.1.0 Use \OC::$server->getShareManager()->sharingDisabledForUser |
|
178 | + */ |
|
179 | + public static function isSharingDisabledForUser() { |
|
180 | + if (self::$shareManager === null) { |
|
181 | + self::$shareManager = \OC::$server->getShareManager(); |
|
182 | + } |
|
183 | + |
|
184 | + $user = \OC::$server->getUserSession()->getUser(); |
|
185 | + if ($user !== null) { |
|
186 | + $user = $user->getUID(); |
|
187 | + } |
|
188 | + |
|
189 | + return self::$shareManager->sharingDisabledForUser($user); |
|
190 | + } |
|
191 | + |
|
192 | + /** |
|
193 | + * get l10n object |
|
194 | + * @param string $application |
|
195 | + * @param string|null $language |
|
196 | + * @return \OCP\IL10N |
|
197 | + * @since 6.0.0 - parameter $language was added in 8.0.0 |
|
198 | + */ |
|
199 | + public static function getL10N($application, $language = null) { |
|
200 | + return \OC::$server->getL10N($application, $language); |
|
201 | + } |
|
202 | + |
|
203 | + /** |
|
204 | + * add a css file |
|
205 | + * @param string $application |
|
206 | + * @param string $file |
|
207 | + * @since 4.0.0 |
|
208 | + */ |
|
209 | + public static function addStyle( $application, $file = null ) { |
|
210 | + \OC_Util::addStyle( $application, $file ); |
|
211 | + } |
|
212 | + |
|
213 | + /** |
|
214 | + * add a javascript file |
|
215 | + * @param string $application |
|
216 | + * @param string $file |
|
217 | + * @since 4.0.0 |
|
218 | + */ |
|
219 | + public static function addScript( $application, $file = null ) { |
|
220 | + \OC_Util::addScript( $application, $file ); |
|
221 | + } |
|
222 | + |
|
223 | + /** |
|
224 | + * Add a translation JS file |
|
225 | + * @param string $application application id |
|
226 | + * @param string $languageCode language code, defaults to the current locale |
|
227 | + * @since 8.0.0 |
|
228 | + */ |
|
229 | + public static function addTranslations($application, $languageCode = null) { |
|
230 | + \OC_Util::addTranslations($application, $languageCode); |
|
231 | + } |
|
232 | + |
|
233 | + /** |
|
234 | + * Add a custom element to the header |
|
235 | + * If $text is null then the element will be written as empty element. |
|
236 | + * So use "" to get a closing tag. |
|
237 | + * @param string $tag tag name of the element |
|
238 | + * @param array $attributes array of attributes for the element |
|
239 | + * @param string $text the text content for the element |
|
240 | + * @since 4.0.0 |
|
241 | + */ |
|
242 | + public static function addHeader($tag, $attributes, $text=null) { |
|
243 | + \OC_Util::addHeader($tag, $attributes, $text); |
|
244 | + } |
|
245 | + |
|
246 | + /** |
|
247 | + * formats a timestamp in the "right" way |
|
248 | + * @param int $timestamp $timestamp |
|
249 | + * @param bool $dateOnly option to omit time from the result |
|
250 | + * @param DateTimeZone|string $timeZone where the given timestamp shall be converted to |
|
251 | + * @return string timestamp |
|
252 | + * |
|
253 | + * @deprecated 8.0.0 Use \OC::$server->query('DateTimeFormatter') instead |
|
254 | + * @since 4.0.0 |
|
255 | + */ |
|
256 | + public static function formatDate($timestamp, $dateOnly=false, $timeZone = null) { |
|
257 | + return(\OC_Util::formatDate($timestamp, $dateOnly, $timeZone)); |
|
258 | + } |
|
259 | + |
|
260 | + /** |
|
261 | + * check if some encrypted files are stored |
|
262 | + * @return bool |
|
263 | + * |
|
264 | + * @deprecated 8.1.0 No longer required |
|
265 | + * @since 6.0.0 |
|
266 | + */ |
|
267 | + public static function encryptedFiles() { |
|
268 | + return false; |
|
269 | + } |
|
270 | + |
|
271 | + /** |
|
272 | + * Creates an absolute url to the given app and file. |
|
273 | + * @param string $app app |
|
274 | + * @param string $file file |
|
275 | + * @param array $args array with param=>value, will be appended to the returned url |
|
276 | + * The value of $args will be urlencoded |
|
277 | + * @return string the url |
|
278 | + * @since 4.0.0 - parameter $args was added in 4.5.0 |
|
279 | + */ |
|
280 | + public static function linkToAbsolute( $app, $file, $args = array() ) { |
|
281 | + $urlGenerator = \OC::$server->getURLGenerator(); |
|
282 | + return $urlGenerator->getAbsoluteURL( |
|
283 | + $urlGenerator->linkTo($app, $file, $args) |
|
284 | + ); |
|
285 | + } |
|
286 | + |
|
287 | + /** |
|
288 | + * Creates an absolute url for remote use. |
|
289 | + * @param string $service id |
|
290 | + * @return string the url |
|
291 | + * @since 4.0.0 |
|
292 | + */ |
|
293 | + public static function linkToRemote( $service ) { |
|
294 | + $urlGenerator = \OC::$server->getURLGenerator(); |
|
295 | + $remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service; |
|
296 | + return $urlGenerator->getAbsoluteURL( |
|
297 | + $remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '') |
|
298 | + ); |
|
299 | + } |
|
300 | + |
|
301 | + /** |
|
302 | + * Creates an absolute url for public use |
|
303 | + * @param string $service id |
|
304 | + * @return string the url |
|
305 | + * @since 4.5.0 |
|
306 | + */ |
|
307 | + public static function linkToPublic($service) { |
|
308 | + return \OC_Helper::linkToPublic($service); |
|
309 | + } |
|
310 | + |
|
311 | + /** |
|
312 | + * Creates an url using a defined route |
|
313 | + * @param string $route |
|
314 | + * @param array $parameters |
|
315 | + * @internal param array $args with param=>value, will be appended to the returned url |
|
316 | + * @return string the url |
|
317 | + * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->linkToRoute($route, $parameters) |
|
318 | + * @since 5.0.0 |
|
319 | + */ |
|
320 | + public static function linkToRoute( $route, $parameters = array() ) { |
|
321 | + return \OC::$server->getURLGenerator()->linkToRoute($route, $parameters); |
|
322 | + } |
|
323 | + |
|
324 | + /** |
|
325 | + * Creates an url to the given app and file |
|
326 | + * @param string $app app |
|
327 | + * @param string $file file |
|
328 | + * @param array $args array with param=>value, will be appended to the returned url |
|
329 | + * The value of $args will be urlencoded |
|
330 | + * @return string the url |
|
331 | + * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->linkTo($app, $file, $args) |
|
332 | + * @since 4.0.0 - parameter $args was added in 4.5.0 |
|
333 | + */ |
|
334 | + public static function linkTo( $app, $file, $args = array() ) { |
|
335 | + return \OC::$server->getURLGenerator()->linkTo($app, $file, $args); |
|
336 | + } |
|
337 | + |
|
338 | + /** |
|
339 | + * Returns the server host, even if the website uses one or more reverse proxy |
|
340 | + * @return string the server host |
|
341 | + * @deprecated 8.1.0 Use \OCP\IRequest::getServerHost |
|
342 | + * @since 4.0.0 |
|
343 | + */ |
|
344 | + public static function getServerHost() { |
|
345 | + return \OC::$server->getRequest()->getServerHost(); |
|
346 | + } |
|
347 | + |
|
348 | + /** |
|
349 | + * Returns the server host name without an eventual port number |
|
350 | + * @return string the server hostname |
|
351 | + * @since 5.0.0 |
|
352 | + */ |
|
353 | + public static function getServerHostName() { |
|
354 | + $host_name = self::getServerHost(); |
|
355 | + // strip away port number (if existing) |
|
356 | + $colon_pos = strpos($host_name, ':'); |
|
357 | + if ($colon_pos != FALSE) { |
|
358 | + $host_name = substr($host_name, 0, $colon_pos); |
|
359 | + } |
|
360 | + return $host_name; |
|
361 | + } |
|
362 | + |
|
363 | + /** |
|
364 | + * Returns the default email address |
|
365 | + * @param string $user_part the user part of the address |
|
366 | + * @return string the default email address |
|
367 | + * |
|
368 | + * Assembles a default email address (using the server hostname |
|
369 | + * and the given user part, and returns it |
|
370 | + * Example: when given lostpassword-noreply as $user_part param, |
|
371 | + * and is currently accessed via http(s)://example.com/, |
|
372 | + * it would return '[email protected]' |
|
373 | + * |
|
374 | + * If the configuration value 'mail_from_address' is set in |
|
375 | + * config.php, this value will override the $user_part that |
|
376 | + * is passed to this function |
|
377 | + * @since 5.0.0 |
|
378 | + */ |
|
379 | + public static function getDefaultEmailAddress($user_part) { |
|
380 | + $config = \OC::$server->getConfig(); |
|
381 | + $user_part = $config->getSystemValue('mail_from_address', $user_part); |
|
382 | + $host_name = self::getServerHostName(); |
|
383 | + $host_name = $config->getSystemValue('mail_domain', $host_name); |
|
384 | + $defaultEmailAddress = $user_part.'@'.$host_name; |
|
385 | + |
|
386 | + $mailer = \OC::$server->getMailer(); |
|
387 | + if ($mailer->validateMailAddress($defaultEmailAddress)) { |
|
388 | + return $defaultEmailAddress; |
|
389 | + } |
|
390 | + |
|
391 | + // in case we cannot build a valid email address from the hostname let's fallback to 'localhost.localdomain' |
|
392 | + return $user_part.'@localhost.localdomain'; |
|
393 | + } |
|
394 | + |
|
395 | + /** |
|
396 | + * Returns the server protocol. It respects reverse proxy servers and load balancers |
|
397 | + * @return string the server protocol |
|
398 | + * @deprecated 8.1.0 Use \OCP\IRequest::getServerProtocol |
|
399 | + * @since 4.5.0 |
|
400 | + */ |
|
401 | + public static function getServerProtocol() { |
|
402 | + return \OC::$server->getRequest()->getServerProtocol(); |
|
403 | + } |
|
404 | + |
|
405 | + /** |
|
406 | + * Returns the request uri, even if the website uses one or more reverse proxies |
|
407 | + * @return string the request uri |
|
408 | + * @deprecated 8.1.0 Use \OCP\IRequest::getRequestUri |
|
409 | + * @since 5.0.0 |
|
410 | + */ |
|
411 | + public static function getRequestUri() { |
|
412 | + return \OC::$server->getRequest()->getRequestUri(); |
|
413 | + } |
|
414 | + |
|
415 | + /** |
|
416 | + * Returns the script name, even if the website uses one or more reverse proxies |
|
417 | + * @return string the script name |
|
418 | + * @deprecated 8.1.0 Use \OCP\IRequest::getScriptName |
|
419 | + * @since 5.0.0 |
|
420 | + */ |
|
421 | + public static function getScriptName() { |
|
422 | + return \OC::$server->getRequest()->getScriptName(); |
|
423 | + } |
|
424 | + |
|
425 | + /** |
|
426 | + * Creates path to an image |
|
427 | + * @param string $app app |
|
428 | + * @param string $image image name |
|
429 | + * @return string the url |
|
430 | + * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->imagePath($app, $image) |
|
431 | + * @since 4.0.0 |
|
432 | + */ |
|
433 | + public static function imagePath( $app, $image ) { |
|
434 | + return \OC::$server->getURLGenerator()->imagePath($app, $image); |
|
435 | + } |
|
436 | + |
|
437 | + /** |
|
438 | + * Make a human file size (2048 to 2 kB) |
|
439 | + * @param int $bytes file size in bytes |
|
440 | + * @return string a human readable file size |
|
441 | + * @since 4.0.0 |
|
442 | + */ |
|
443 | + public static function humanFileSize( $bytes ) { |
|
444 | + return(\OC_Helper::humanFileSize( $bytes )); |
|
445 | + } |
|
446 | + |
|
447 | + /** |
|
448 | + * Make a computer file size (2 kB to 2048) |
|
449 | + * @param string $str file size in a fancy format |
|
450 | + * @return int a file size in bytes |
|
451 | + * |
|
452 | + * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418 |
|
453 | + * @since 4.0.0 |
|
454 | + */ |
|
455 | + public static function computerFileSize( $str ) { |
|
456 | + return(\OC_Helper::computerFileSize( $str )); |
|
457 | + } |
|
458 | + |
|
459 | + /** |
|
460 | + * connects a function to a hook |
|
461 | + * |
|
462 | + * @param string $signalClass class name of emitter |
|
463 | + * @param string $signalName name of signal |
|
464 | + * @param string|object $slotClass class name of slot |
|
465 | + * @param string $slotName name of slot |
|
466 | + * @return bool |
|
467 | + * |
|
468 | + * This function makes it very easy to connect to use hooks. |
|
469 | + * |
|
470 | + * TODO: write example |
|
471 | + * @since 4.0.0 |
|
472 | + */ |
|
473 | + static public function connectHook($signalClass, $signalName, $slotClass, $slotName ) { |
|
474 | + return(\OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName )); |
|
475 | + } |
|
476 | + |
|
477 | + /** |
|
478 | + * Emits a signal. To get data from the slot use references! |
|
479 | + * @param string $signalclass class name of emitter |
|
480 | + * @param string $signalname name of signal |
|
481 | + * @param array $params default: array() array with additional data |
|
482 | + * @return bool true if slots exists or false if not |
|
483 | + * |
|
484 | + * TODO: write example |
|
485 | + * @since 4.0.0 |
|
486 | + */ |
|
487 | + static public function emitHook( $signalclass, $signalname, $params = array()) { |
|
488 | + return(\OC_Hook::emit( $signalclass, $signalname, $params )); |
|
489 | + } |
|
490 | + |
|
491 | + /** |
|
492 | + * Cached encrypted CSRF token. Some static unit-tests of ownCloud compare |
|
493 | + * multiple OC_Template elements which invoke `callRegister`. If the value |
|
494 | + * would not be cached these unit-tests would fail. |
|
495 | + * @var string |
|
496 | + */ |
|
497 | + private static $token = ''; |
|
498 | + |
|
499 | + /** |
|
500 | + * Register an get/post call. This is important to prevent CSRF attacks |
|
501 | + * @since 4.5.0 |
|
502 | + */ |
|
503 | + public static function callRegister() { |
|
504 | + if(self::$token === '') { |
|
505 | + self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue(); |
|
506 | + } |
|
507 | + return self::$token; |
|
508 | + } |
|
509 | + |
|
510 | + /** |
|
511 | + * Check an ajax get/post call if the request token is valid. exit if not. |
|
512 | + * @since 4.5.0 |
|
513 | + * @deprecated 9.0.0 Use annotations based on the app framework. |
|
514 | + */ |
|
515 | + public static function callCheck() { |
|
516 | + if(!\OC::$server->getRequest()->passesStrictCookieCheck()) { |
|
517 | + header('Location: '.\OC::$WEBROOT); |
|
518 | + exit(); |
|
519 | + } |
|
520 | + |
|
521 | + if (!(\OC::$server->getRequest()->passesCSRFCheck())) { |
|
522 | + exit(); |
|
523 | + } |
|
524 | + } |
|
525 | + |
|
526 | + /** |
|
527 | + * Used to sanitize HTML |
|
528 | + * |
|
529 | + * This function is used to sanitize HTML and should be applied on any |
|
530 | + * string or array of strings before displaying it on a web page. |
|
531 | + * |
|
532 | + * @param string|array $value |
|
533 | + * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter. |
|
534 | + * @since 4.5.0 |
|
535 | + */ |
|
536 | + public static function sanitizeHTML($value) { |
|
537 | + return \OC_Util::sanitizeHTML($value); |
|
538 | + } |
|
539 | + |
|
540 | + /** |
|
541 | + * Public function to encode url parameters |
|
542 | + * |
|
543 | + * This function is used to encode path to file before output. |
|
544 | + * Encoding is done according to RFC 3986 with one exception: |
|
545 | + * Character '/' is preserved as is. |
|
546 | + * |
|
547 | + * @param string $component part of URI to encode |
|
548 | + * @return string |
|
549 | + * @since 6.0.0 |
|
550 | + */ |
|
551 | + public static function encodePath($component) { |
|
552 | + return(\OC_Util::encodePath($component)); |
|
553 | + } |
|
554 | + |
|
555 | + /** |
|
556 | + * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. |
|
557 | + * |
|
558 | + * @param array $input The array to work on |
|
559 | + * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default) |
|
560 | + * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
561 | + * @return array |
|
562 | + * @since 4.5.0 |
|
563 | + */ |
|
564 | + public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') { |
|
565 | + return(\OC_Helper::mb_array_change_key_case($input, $case, $encoding)); |
|
566 | + } |
|
567 | + |
|
568 | + /** |
|
569 | + * replaces a copy of string delimited by the start and (optionally) length parameters with the string given in replacement. |
|
570 | + * |
|
571 | + * @param string $string The input string. Opposite to the PHP build-in function does not accept an array. |
|
572 | + * @param string $replacement The replacement string. |
|
573 | + * @param int $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string. |
|
574 | + * @param int $length Length of the part to be replaced |
|
575 | + * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
576 | + * @return string |
|
577 | + * @since 4.5.0 |
|
578 | + * @deprecated 8.2.0 Use substr_replace() instead. |
|
579 | + */ |
|
580 | + public static function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = 'UTF-8') { |
|
581 | + return substr_replace($string, $replacement, $start, $length); |
|
582 | + } |
|
583 | + |
|
584 | + /** |
|
585 | + * Replace all occurrences of the search string with the replacement string |
|
586 | + * |
|
587 | + * @param string $search The value being searched for, otherwise known as the needle. String. |
|
588 | + * @param string $replace The replacement string. |
|
589 | + * @param string $subject The string or array being searched and replaced on, otherwise known as the haystack. |
|
590 | + * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8 |
|
591 | + * @param int $count If passed, this will be set to the number of replacements performed. |
|
592 | + * @return string |
|
593 | + * @since 4.5.0 |
|
594 | + * @deprecated 8.2.0 Use str_replace() instead. |
|
595 | + */ |
|
596 | + public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { |
|
597 | + return str_replace($search, $replace, $subject, $count); |
|
598 | + } |
|
599 | + |
|
600 | + /** |
|
601 | + * performs a search in a nested array |
|
602 | + * |
|
603 | + * @param array $haystack the array to be searched |
|
604 | + * @param string $needle the search string |
|
605 | + * @param int $index optional, only search this key name |
|
606 | + * @return mixed the key of the matching field, otherwise false |
|
607 | + * @since 4.5.0 |
|
608 | + */ |
|
609 | + public static function recursiveArraySearch($haystack, $needle, $index = null) { |
|
610 | + return(\OC_Helper::recursiveArraySearch($haystack, $needle, $index)); |
|
611 | + } |
|
612 | + |
|
613 | + /** |
|
614 | + * calculates the maximum upload size respecting system settings, free space and user quota |
|
615 | + * |
|
616 | + * @param string $dir the current folder where the user currently operates |
|
617 | + * @param int $free the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly |
|
618 | + * @return int number of bytes representing |
|
619 | + * @since 5.0.0 |
|
620 | + */ |
|
621 | + public static function maxUploadFilesize($dir, $free = null) { |
|
622 | + return \OC_Helper::maxUploadFilesize($dir, $free); |
|
623 | + } |
|
624 | + |
|
625 | + /** |
|
626 | + * Calculate free space left within user quota |
|
627 | + * @param string $dir the current folder where the user currently operates |
|
628 | + * @return int number of bytes representing |
|
629 | + * @since 7.0.0 |
|
630 | + */ |
|
631 | + public static function freeSpace($dir) { |
|
632 | + return \OC_Helper::freeSpace($dir); |
|
633 | + } |
|
634 | + |
|
635 | + /** |
|
636 | + * Calculate PHP upload limit |
|
637 | + * |
|
638 | + * @return int number of bytes representing |
|
639 | + * @since 7.0.0 |
|
640 | + */ |
|
641 | + public static function uploadLimit() { |
|
642 | + return \OC_Helper::uploadLimit(); |
|
643 | + } |
|
644 | + |
|
645 | + /** |
|
646 | + * Returns whether the given file name is valid |
|
647 | + * @param string $file file name to check |
|
648 | + * @return bool true if the file name is valid, false otherwise |
|
649 | + * @deprecated 8.1.0 use \OC\Files\View::verifyPath() |
|
650 | + * @since 7.0.0 |
|
651 | + */ |
|
652 | + public static function isValidFileName($file) { |
|
653 | + return \OC_Util::isValidFileName($file); |
|
654 | + } |
|
655 | + |
|
656 | + /** |
|
657 | + * Generates a cryptographic secure pseudo-random string |
|
658 | + * @param int $length of the random string |
|
659 | + * @return string |
|
660 | + * @deprecated 8.0.0 Use \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate($length); instead |
|
661 | + * @since 7.0.0 |
|
662 | + */ |
|
663 | + public static function generateRandomBytes($length = 30) { |
|
664 | + return \OC::$server->getSecureRandom()->generate($length, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS); |
|
665 | + } |
|
666 | + |
|
667 | + /** |
|
668 | + * Compare two strings to provide a natural sort |
|
669 | + * @param string $a first string to compare |
|
670 | + * @param string $b second string to compare |
|
671 | + * @return -1 if $b comes before $a, 1 if $a comes before $b |
|
672 | + * or 0 if the strings are identical |
|
673 | + * @since 7.0.0 |
|
674 | + */ |
|
675 | + public static function naturalSortCompare($a, $b) { |
|
676 | + return \OC\NaturalSort::getInstance()->compare($a, $b); |
|
677 | + } |
|
678 | + |
|
679 | + /** |
|
680 | + * check if a password is required for each public link |
|
681 | + * @return boolean |
|
682 | + * @since 7.0.0 |
|
683 | + */ |
|
684 | + public static function isPublicLinkPasswordRequired() { |
|
685 | + return \OC_Util::isPublicLinkPasswordRequired(); |
|
686 | + } |
|
687 | + |
|
688 | + /** |
|
689 | + * check if share API enforces a default expire date |
|
690 | + * @return boolean |
|
691 | + * @since 8.0.0 |
|
692 | + */ |
|
693 | + public static function isDefaultExpireDateEnforced() { |
|
694 | + return \OC_Util::isDefaultExpireDateEnforced(); |
|
695 | + } |
|
696 | + |
|
697 | + protected static $needUpgradeCache = null; |
|
698 | + |
|
699 | + /** |
|
700 | + * Checks whether the current version needs upgrade. |
|
701 | + * |
|
702 | + * @return bool true if upgrade is needed, false otherwise |
|
703 | + * @since 7.0.0 |
|
704 | + */ |
|
705 | + public static function needUpgrade() { |
|
706 | + if (!isset(self::$needUpgradeCache)) { |
|
707 | + self::$needUpgradeCache=\OC_Util::needUpgrade(\OC::$server->getSystemConfig()); |
|
708 | + } |
|
709 | + return self::$needUpgradeCache; |
|
710 | + } |
|
711 | 711 | } |
@@ -58,11 +58,11 @@ discard block |
||
58 | 58 | */ |
59 | 59 | class Util { |
60 | 60 | // consts for Logging |
61 | - const DEBUG=0; |
|
62 | - const INFO=1; |
|
63 | - const WARN=2; |
|
64 | - const ERROR=3; |
|
65 | - const FATAL=4; |
|
61 | + const DEBUG = 0; |
|
62 | + const INFO = 1; |
|
63 | + const WARN = 2; |
|
64 | + const ERROR = 3; |
|
65 | + const FATAL = 4; |
|
66 | 66 | |
67 | 67 | /** \OCP\Share\IManager */ |
68 | 68 | private static $shareManager; |
@@ -118,11 +118,11 @@ discard block |
||
118 | 118 | $message->setSubject($subject); |
119 | 119 | $message->setPlainBody($mailtext); |
120 | 120 | $message->setFrom([$fromaddress => $fromname]); |
121 | - if($html === 1) { |
|
121 | + if ($html === 1) { |
|
122 | 122 | $message->setHTMLBody($altbody); |
123 | 123 | } |
124 | 124 | |
125 | - if($altbody === '') { |
|
125 | + if ($altbody === '') { |
|
126 | 126 | $message->setHTMLBody($mailtext); |
127 | 127 | $message->setPlainBody(''); |
128 | 128 | } else { |
@@ -130,14 +130,14 @@ discard block |
||
130 | 130 | $message->setPlainBody($altbody); |
131 | 131 | } |
132 | 132 | |
133 | - if(!empty($ccaddress)) { |
|
134 | - if(!empty($ccname)) { |
|
133 | + if (!empty($ccaddress)) { |
|
134 | + if (!empty($ccname)) { |
|
135 | 135 | $message->setCc([$ccaddress => $ccname]); |
136 | 136 | } else { |
137 | 137 | $message->setCc([$ccaddress]); |
138 | 138 | } |
139 | 139 | } |
140 | - if(!empty($bcc)) { |
|
140 | + if (!empty($bcc)) { |
|
141 | 141 | $message->setBcc([$bcc]); |
142 | 142 | } |
143 | 143 | |
@@ -152,7 +152,7 @@ discard block |
||
152 | 152 | * @since 4.0.0 |
153 | 153 | * @deprecated 13.0.0 use log of \OCP\ILogger |
154 | 154 | */ |
155 | - public static function writeLog( $app, $message, $level ) { |
|
155 | + public static function writeLog($app, $message, $level) { |
|
156 | 156 | $context = ['app' => $app]; |
157 | 157 | \OC::$server->getLogger()->log($level, $message, $context); |
158 | 158 | } |
@@ -165,7 +165,7 @@ discard block |
||
165 | 165 | * @since ....0.0 - parameter $level was added in 7.0.0 |
166 | 166 | * @deprecated 8.2.0 use logException of \OCP\ILogger |
167 | 167 | */ |
168 | - public static function logException( $app, \Exception $ex, $level = \OCP\Util::FATAL ) { |
|
168 | + public static function logException($app, \Exception $ex, $level = \OCP\Util::FATAL) { |
|
169 | 169 | \OC::$server->getLogger()->logException($ex, ['app' => $app]); |
170 | 170 | } |
171 | 171 | |
@@ -206,8 +206,8 @@ discard block |
||
206 | 206 | * @param string $file |
207 | 207 | * @since 4.0.0 |
208 | 208 | */ |
209 | - public static function addStyle( $application, $file = null ) { |
|
210 | - \OC_Util::addStyle( $application, $file ); |
|
209 | + public static function addStyle($application, $file = null) { |
|
210 | + \OC_Util::addStyle($application, $file); |
|
211 | 211 | } |
212 | 212 | |
213 | 213 | /** |
@@ -216,8 +216,8 @@ discard block |
||
216 | 216 | * @param string $file |
217 | 217 | * @since 4.0.0 |
218 | 218 | */ |
219 | - public static function addScript( $application, $file = null ) { |
|
220 | - \OC_Util::addScript( $application, $file ); |
|
219 | + public static function addScript($application, $file = null) { |
|
220 | + \OC_Util::addScript($application, $file); |
|
221 | 221 | } |
222 | 222 | |
223 | 223 | /** |
@@ -239,7 +239,7 @@ discard block |
||
239 | 239 | * @param string $text the text content for the element |
240 | 240 | * @since 4.0.0 |
241 | 241 | */ |
242 | - public static function addHeader($tag, $attributes, $text=null) { |
|
242 | + public static function addHeader($tag, $attributes, $text = null) { |
|
243 | 243 | \OC_Util::addHeader($tag, $attributes, $text); |
244 | 244 | } |
245 | 245 | |
@@ -253,7 +253,7 @@ discard block |
||
253 | 253 | * @deprecated 8.0.0 Use \OC::$server->query('DateTimeFormatter') instead |
254 | 254 | * @since 4.0.0 |
255 | 255 | */ |
256 | - public static function formatDate($timestamp, $dateOnly=false, $timeZone = null) { |
|
256 | + public static function formatDate($timestamp, $dateOnly = false, $timeZone = null) { |
|
257 | 257 | return(\OC_Util::formatDate($timestamp, $dateOnly, $timeZone)); |
258 | 258 | } |
259 | 259 | |
@@ -277,7 +277,7 @@ discard block |
||
277 | 277 | * @return string the url |
278 | 278 | * @since 4.0.0 - parameter $args was added in 4.5.0 |
279 | 279 | */ |
280 | - public static function linkToAbsolute( $app, $file, $args = array() ) { |
|
280 | + public static function linkToAbsolute($app, $file, $args = array()) { |
|
281 | 281 | $urlGenerator = \OC::$server->getURLGenerator(); |
282 | 282 | return $urlGenerator->getAbsoluteURL( |
283 | 283 | $urlGenerator->linkTo($app, $file, $args) |
@@ -290,11 +290,11 @@ discard block |
||
290 | 290 | * @return string the url |
291 | 291 | * @since 4.0.0 |
292 | 292 | */ |
293 | - public static function linkToRemote( $service ) { |
|
293 | + public static function linkToRemote($service) { |
|
294 | 294 | $urlGenerator = \OC::$server->getURLGenerator(); |
295 | - $remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service; |
|
295 | + $remoteBase = $urlGenerator->linkTo('', 'remote.php').'/'.$service; |
|
296 | 296 | return $urlGenerator->getAbsoluteURL( |
297 | - $remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '') |
|
297 | + $remoteBase.(($service[strlen($service) - 1] != '/') ? '/' : '') |
|
298 | 298 | ); |
299 | 299 | } |
300 | 300 | |
@@ -317,7 +317,7 @@ discard block |
||
317 | 317 | * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->linkToRoute($route, $parameters) |
318 | 318 | * @since 5.0.0 |
319 | 319 | */ |
320 | - public static function linkToRoute( $route, $parameters = array() ) { |
|
320 | + public static function linkToRoute($route, $parameters = array()) { |
|
321 | 321 | return \OC::$server->getURLGenerator()->linkToRoute($route, $parameters); |
322 | 322 | } |
323 | 323 | |
@@ -331,7 +331,7 @@ discard block |
||
331 | 331 | * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->linkTo($app, $file, $args) |
332 | 332 | * @since 4.0.0 - parameter $args was added in 4.5.0 |
333 | 333 | */ |
334 | - public static function linkTo( $app, $file, $args = array() ) { |
|
334 | + public static function linkTo($app, $file, $args = array()) { |
|
335 | 335 | return \OC::$server->getURLGenerator()->linkTo($app, $file, $args); |
336 | 336 | } |
337 | 337 | |
@@ -430,7 +430,7 @@ discard block |
||
430 | 430 | * @deprecated 8.1.0 Use \OC::$server->getURLGenerator()->imagePath($app, $image) |
431 | 431 | * @since 4.0.0 |
432 | 432 | */ |
433 | - public static function imagePath( $app, $image ) { |
|
433 | + public static function imagePath($app, $image) { |
|
434 | 434 | return \OC::$server->getURLGenerator()->imagePath($app, $image); |
435 | 435 | } |
436 | 436 | |
@@ -440,8 +440,8 @@ discard block |
||
440 | 440 | * @return string a human readable file size |
441 | 441 | * @since 4.0.0 |
442 | 442 | */ |
443 | - public static function humanFileSize( $bytes ) { |
|
444 | - return(\OC_Helper::humanFileSize( $bytes )); |
|
443 | + public static function humanFileSize($bytes) { |
|
444 | + return(\OC_Helper::humanFileSize($bytes)); |
|
445 | 445 | } |
446 | 446 | |
447 | 447 | /** |
@@ -452,8 +452,8 @@ discard block |
||
452 | 452 | * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418 |
453 | 453 | * @since 4.0.0 |
454 | 454 | */ |
455 | - public static function computerFileSize( $str ) { |
|
456 | - return(\OC_Helper::computerFileSize( $str )); |
|
455 | + public static function computerFileSize($str) { |
|
456 | + return(\OC_Helper::computerFileSize($str)); |
|
457 | 457 | } |
458 | 458 | |
459 | 459 | /** |
@@ -470,8 +470,8 @@ discard block |
||
470 | 470 | * TODO: write example |
471 | 471 | * @since 4.0.0 |
472 | 472 | */ |
473 | - static public function connectHook($signalClass, $signalName, $slotClass, $slotName ) { |
|
474 | - return(\OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName )); |
|
473 | + static public function connectHook($signalClass, $signalName, $slotClass, $slotName) { |
|
474 | + return(\OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName)); |
|
475 | 475 | } |
476 | 476 | |
477 | 477 | /** |
@@ -484,8 +484,8 @@ discard block |
||
484 | 484 | * TODO: write example |
485 | 485 | * @since 4.0.0 |
486 | 486 | */ |
487 | - static public function emitHook( $signalclass, $signalname, $params = array()) { |
|
488 | - return(\OC_Hook::emit( $signalclass, $signalname, $params )); |
|
487 | + static public function emitHook($signalclass, $signalname, $params = array()) { |
|
488 | + return(\OC_Hook::emit($signalclass, $signalname, $params)); |
|
489 | 489 | } |
490 | 490 | |
491 | 491 | /** |
@@ -501,7 +501,7 @@ discard block |
||
501 | 501 | * @since 4.5.0 |
502 | 502 | */ |
503 | 503 | public static function callRegister() { |
504 | - if(self::$token === '') { |
|
504 | + if (self::$token === '') { |
|
505 | 505 | self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue(); |
506 | 506 | } |
507 | 507 | return self::$token; |
@@ -513,7 +513,7 @@ discard block |
||
513 | 513 | * @deprecated 9.0.0 Use annotations based on the app framework. |
514 | 514 | */ |
515 | 515 | public static function callCheck() { |
516 | - if(!\OC::$server->getRequest()->passesStrictCookieCheck()) { |
|
516 | + if (!\OC::$server->getRequest()->passesStrictCookieCheck()) { |
|
517 | 517 | header('Location: '.\OC::$WEBROOT); |
518 | 518 | exit(); |
519 | 519 | } |
@@ -704,7 +704,7 @@ discard block |
||
704 | 704 | */ |
705 | 705 | public static function needUpgrade() { |
706 | 706 | if (!isset(self::$needUpgradeCache)) { |
707 | - self::$needUpgradeCache=\OC_Util::needUpgrade(\OC::$server->getSystemConfig()); |
|
707 | + self::$needUpgradeCache = \OC_Util::needUpgrade(\OC::$server->getSystemConfig()); |
|
708 | 708 | } |
709 | 709 | return self::$needUpgradeCache; |
710 | 710 | } |
@@ -200,7 +200,7 @@ discard block |
||
200 | 200 | * and does not take the chroot into account ) |
201 | 201 | * |
202 | 202 | * @param string $path |
203 | - * @return \OCP\Files\Mount\IMountPoint |
|
203 | + * @return Mount\MountPoint|null |
|
204 | 204 | */ |
205 | 205 | public function getMount($path) { |
206 | 206 | return Filesystem::getMountManager()->find($this->getAbsolutePath($path)); |
@@ -963,7 +963,7 @@ discard block |
||
963 | 963 | |
964 | 964 | /** |
965 | 965 | * @param string $path |
966 | - * @return bool|string |
|
966 | + * @return string|false |
|
967 | 967 | * @throws \OCP\Files\InvalidPathException |
968 | 968 | */ |
969 | 969 | public function toTmpFile($path) { |
@@ -1078,7 +1078,7 @@ discard block |
||
1078 | 1078 | * @param string $path |
1079 | 1079 | * @param array $hooks (optional) |
1080 | 1080 | * @param mixed $extraParam (optional) |
1081 | - * @return mixed |
|
1081 | + * @return string |
|
1082 | 1082 | * @throws \Exception |
1083 | 1083 | * |
1084 | 1084 | * This method takes requests for basic filesystem functions (e.g. reading & writing |
@@ -2086,7 +2086,7 @@ discard block |
||
2086 | 2086 | |
2087 | 2087 | /** |
2088 | 2088 | * @param string $filename |
2089 | - * @return array |
|
2089 | + * @return string[] |
|
2090 | 2090 | * @throws \OC\User\NoUserException |
2091 | 2091 | * @throws NotFoundException |
2092 | 2092 | */ |
@@ -125,9 +125,9 @@ discard block |
||
125 | 125 | $path = '/'; |
126 | 126 | } |
127 | 127 | if ($path[0] !== '/') { |
128 | - $path = '/' . $path; |
|
128 | + $path = '/'.$path; |
|
129 | 129 | } |
130 | - return $this->fakeRoot . $path; |
|
130 | + return $this->fakeRoot.$path; |
|
131 | 131 | } |
132 | 132 | |
133 | 133 | /** |
@@ -139,7 +139,7 @@ discard block |
||
139 | 139 | public function chroot($fakeRoot) { |
140 | 140 | if (!$fakeRoot == '') { |
141 | 141 | if ($fakeRoot[0] !== '/') { |
142 | - $fakeRoot = '/' . $fakeRoot; |
|
142 | + $fakeRoot = '/'.$fakeRoot; |
|
143 | 143 | } |
144 | 144 | } |
145 | 145 | $this->fakeRoot = $fakeRoot; |
@@ -171,7 +171,7 @@ discard block |
||
171 | 171 | } |
172 | 172 | |
173 | 173 | // missing slashes can cause wrong matches! |
174 | - $root = rtrim($this->fakeRoot, '/') . '/'; |
|
174 | + $root = rtrim($this->fakeRoot, '/').'/'; |
|
175 | 175 | |
176 | 176 | if (strpos($path, $root) !== 0) { |
177 | 177 | return null; |
@@ -277,7 +277,7 @@ discard block |
||
277 | 277 | if ($mount instanceof MoveableMount) { |
278 | 278 | // cut of /user/files to get the relative path to data/user/files |
279 | 279 | $pathParts = explode('/', $path, 4); |
280 | - $relPath = '/' . $pathParts[3]; |
|
280 | + $relPath = '/'.$pathParts[3]; |
|
281 | 281 | $this->lockFile($relPath, ILockingProvider::LOCK_SHARED, true); |
282 | 282 | \OC_Hook::emit( |
283 | 283 | Filesystem::CLASSNAME, "umount", |
@@ -688,7 +688,7 @@ discard block |
||
688 | 688 | } |
689 | 689 | $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; |
690 | 690 | $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
691 | - $mount = Filesystem::getMountManager()->find($absolutePath . $postFix); |
|
691 | + $mount = Filesystem::getMountManager()->find($absolutePath.$postFix); |
|
692 | 692 | if ($mount and $mount->getInternalPath($absolutePath) === '') { |
693 | 693 | return $this->removeMount($mount, $absolutePath); |
694 | 694 | } |
@@ -954,7 +954,7 @@ discard block |
||
954 | 954 | $hooks[] = 'write'; |
955 | 955 | break; |
956 | 956 | default: |
957 | - \OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR); |
|
957 | + \OCP\Util::writeLog('core', 'invalid mode ('.$mode.') for '.$path, \OCP\Util::ERROR); |
|
958 | 958 | } |
959 | 959 | |
960 | 960 | if ($mode !== 'r' && $mode !== 'w') { |
@@ -1058,7 +1058,7 @@ discard block |
||
1058 | 1058 | array(Filesystem::signal_param_path => $this->getHookPath($path)) |
1059 | 1059 | ); |
1060 | 1060 | } |
1061 | - list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); |
|
1061 | + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath.$postFix); |
|
1062 | 1062 | if ($storage) { |
1063 | 1063 | $result = $storage->hash($type, $internalPath, $raw); |
1064 | 1064 | return $result; |
@@ -1109,7 +1109,7 @@ discard block |
||
1109 | 1109 | |
1110 | 1110 | $run = $this->runHooks($hooks, $path); |
1111 | 1111 | /** @var \OC\Files\Storage\Storage $storage */ |
1112 | - list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); |
|
1112 | + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath.$postFix); |
|
1113 | 1113 | if ($run and $storage) { |
1114 | 1114 | if (in_array('write', $hooks) || in_array('delete', $hooks)) { |
1115 | 1115 | $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE); |
@@ -1148,7 +1148,7 @@ discard block |
||
1148 | 1148 | $unlockLater = true; |
1149 | 1149 | // make sure our unlocking callback will still be called if connection is aborted |
1150 | 1150 | ignore_user_abort(true); |
1151 | - $result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) { |
|
1151 | + $result = CallbackWrapper::wrap($result, null, null, function() use ($hooks, $path) { |
|
1152 | 1152 | if (in_array('write', $hooks)) { |
1153 | 1153 | $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); |
1154 | 1154 | } else if (in_array('read', $hooks)) { |
@@ -1209,7 +1209,7 @@ discard block |
||
1209 | 1209 | return true; |
1210 | 1210 | } |
1211 | 1211 | |
1212 | - return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/'); |
|
1212 | + return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot.'/'); |
|
1213 | 1213 | } |
1214 | 1214 | |
1215 | 1215 | /** |
@@ -1228,7 +1228,7 @@ discard block |
||
1228 | 1228 | if ($hook != 'read') { |
1229 | 1229 | \OC_Hook::emit( |
1230 | 1230 | Filesystem::CLASSNAME, |
1231 | - $prefix . $hook, |
|
1231 | + $prefix.$hook, |
|
1232 | 1232 | array( |
1233 | 1233 | Filesystem::signal_param_run => &$run, |
1234 | 1234 | Filesystem::signal_param_path => $path |
@@ -1237,7 +1237,7 @@ discard block |
||
1237 | 1237 | } elseif (!$post) { |
1238 | 1238 | \OC_Hook::emit( |
1239 | 1239 | Filesystem::CLASSNAME, |
1240 | - $prefix . $hook, |
|
1240 | + $prefix.$hook, |
|
1241 | 1241 | array( |
1242 | 1242 | Filesystem::signal_param_path => $path |
1243 | 1243 | ) |
@@ -1332,7 +1332,7 @@ discard block |
||
1332 | 1332 | return $this->getPartFileInfo($path); |
1333 | 1333 | } |
1334 | 1334 | $relativePath = $path; |
1335 | - $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); |
|
1335 | + $path = Filesystem::normalizePath($this->fakeRoot.'/'.$path); |
|
1336 | 1336 | |
1337 | 1337 | $mount = Filesystem::getMountManager()->find($path); |
1338 | 1338 | $storage = $mount->getStorage(); |
@@ -1356,7 +1356,7 @@ discard block |
||
1356 | 1356 | //add the sizes of other mount points to the folder |
1357 | 1357 | $extOnly = ($includeMountPoints === 'ext'); |
1358 | 1358 | $mounts = Filesystem::getMountManager()->findIn($path); |
1359 | - $info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) { |
|
1359 | + $info->setSubMounts(array_filter($mounts, function(IMountPoint $mount) use ($extOnly) { |
|
1360 | 1360 | $subStorage = $mount->getStorage(); |
1361 | 1361 | return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage); |
1362 | 1362 | })); |
@@ -1403,12 +1403,12 @@ discard block |
||
1403 | 1403 | /** |
1404 | 1404 | * @var \OC\Files\FileInfo[] $files |
1405 | 1405 | */ |
1406 | - $files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) { |
|
1406 | + $files = array_map(function(ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) { |
|
1407 | 1407 | if ($sharingDisabled) { |
1408 | 1408 | $content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE; |
1409 | 1409 | } |
1410 | 1410 | $owner = $this->getUserObjectForOwner($storage->getOwner($content['path'])); |
1411 | - return new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount, $owner); |
|
1411 | + return new FileInfo($path.'/'.$content['name'], $storage, $content['path'], $content, $mount, $owner); |
|
1412 | 1412 | }, $contents); |
1413 | 1413 | |
1414 | 1414 | //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders |
@@ -1433,8 +1433,8 @@ discard block |
||
1433 | 1433 | // sometimes when the storage is not available it can be any exception |
1434 | 1434 | \OCP\Util::writeLog( |
1435 | 1435 | 'core', |
1436 | - 'Exception while scanning storage "' . $subStorage->getId() . '": ' . |
|
1437 | - get_class($e) . ': ' . $e->getMessage(), |
|
1436 | + 'Exception while scanning storage "'.$subStorage->getId().'": '. |
|
1437 | + get_class($e).': '.$e->getMessage(), |
|
1438 | 1438 | \OCP\Util::ERROR |
1439 | 1439 | ); |
1440 | 1440 | continue; |
@@ -1471,7 +1471,7 @@ discard block |
||
1471 | 1471 | break; |
1472 | 1472 | } |
1473 | 1473 | } |
1474 | - $rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/ |
|
1474 | + $rootEntry['path'] = substr(Filesystem::normalizePath($path.'/'.$rootEntry['name']), strlen($user) + 2); // full path without /$user/ |
|
1475 | 1475 | |
1476 | 1476 | // if sharing was disabled for the user we remove the share permissions |
1477 | 1477 | if (\OCP\Util::isSharingDisabledForUser()) { |
@@ -1479,14 +1479,14 @@ discard block |
||
1479 | 1479 | } |
1480 | 1480 | |
1481 | 1481 | $owner = $this->getUserObjectForOwner($subStorage->getOwner('')); |
1482 | - $files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner); |
|
1482 | + $files[] = new FileInfo($path.'/'.$rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner); |
|
1483 | 1483 | } |
1484 | 1484 | } |
1485 | 1485 | } |
1486 | 1486 | } |
1487 | 1487 | |
1488 | 1488 | if ($mimetype_filter) { |
1489 | - $files = array_filter($files, function (FileInfo $file) use ($mimetype_filter) { |
|
1489 | + $files = array_filter($files, function(FileInfo $file) use ($mimetype_filter) { |
|
1490 | 1490 | if (strpos($mimetype_filter, '/')) { |
1491 | 1491 | return $file->getMimetype() === $mimetype_filter; |
1492 | 1492 | } else { |
@@ -1515,7 +1515,7 @@ discard block |
||
1515 | 1515 | if ($data instanceof FileInfo) { |
1516 | 1516 | $data = $data->getData(); |
1517 | 1517 | } |
1518 | - $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); |
|
1518 | + $path = Filesystem::normalizePath($this->fakeRoot.'/'.$path); |
|
1519 | 1519 | /** |
1520 | 1520 | * @var \OC\Files\Storage\Storage $storage |
1521 | 1521 | * @var string $internalPath |
@@ -1542,7 +1542,7 @@ discard block |
||
1542 | 1542 | * @return FileInfo[] |
1543 | 1543 | */ |
1544 | 1544 | public function search($query) { |
1545 | - return $this->searchCommon('search', array('%' . $query . '%')); |
|
1545 | + return $this->searchCommon('search', array('%'.$query.'%')); |
|
1546 | 1546 | } |
1547 | 1547 | |
1548 | 1548 | /** |
@@ -1593,10 +1593,10 @@ discard block |
||
1593 | 1593 | |
1594 | 1594 | $results = call_user_func_array(array($cache, $method), $args); |
1595 | 1595 | foreach ($results as $result) { |
1596 | - if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') { |
|
1596 | + if (substr($mountPoint.$result['path'], 0, $rootLength + 1) === $this->fakeRoot.'/') { |
|
1597 | 1597 | $internalPath = $result['path']; |
1598 | - $path = $mountPoint . $result['path']; |
|
1599 | - $result['path'] = substr($mountPoint . $result['path'], $rootLength); |
|
1598 | + $path = $mountPoint.$result['path']; |
|
1599 | + $result['path'] = substr($mountPoint.$result['path'], $rootLength); |
|
1600 | 1600 | $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath)); |
1601 | 1601 | $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner); |
1602 | 1602 | } |
@@ -1614,8 +1614,8 @@ discard block |
||
1614 | 1614 | if ($results) { |
1615 | 1615 | foreach ($results as $result) { |
1616 | 1616 | $internalPath = $result['path']; |
1617 | - $result['path'] = rtrim($relativeMountPoint . $result['path'], '/'); |
|
1618 | - $path = rtrim($mountPoint . $internalPath, '/'); |
|
1617 | + $result['path'] = rtrim($relativeMountPoint.$result['path'], '/'); |
|
1618 | + $path = rtrim($mountPoint.$internalPath, '/'); |
|
1619 | 1619 | $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath)); |
1620 | 1620 | $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner); |
1621 | 1621 | } |
@@ -1636,7 +1636,7 @@ discard block |
||
1636 | 1636 | public function getOwner($path) { |
1637 | 1637 | $info = $this->getFileInfo($path); |
1638 | 1638 | if (!$info) { |
1639 | - throw new NotFoundException($path . ' not found while trying to get owner'); |
|
1639 | + throw new NotFoundException($path.' not found while trying to get owner'); |
|
1640 | 1640 | } |
1641 | 1641 | return $info->getOwner()->getUID(); |
1642 | 1642 | } |
@@ -1670,7 +1670,7 @@ discard block |
||
1670 | 1670 | * @return string |
1671 | 1671 | */ |
1672 | 1672 | public function getPath($id) { |
1673 | - $id = (int)$id; |
|
1673 | + $id = (int) $id; |
|
1674 | 1674 | $manager = Filesystem::getMountManager(); |
1675 | 1675 | $mounts = $manager->findIn($this->fakeRoot); |
1676 | 1676 | $mounts[] = $manager->find($this->fakeRoot); |
@@ -1685,7 +1685,7 @@ discard block |
||
1685 | 1685 | $cache = $mount->getStorage()->getCache(); |
1686 | 1686 | $internalPath = $cache->getPathById($id); |
1687 | 1687 | if (is_string($internalPath)) { |
1688 | - $fullPath = $mount->getMountPoint() . $internalPath; |
|
1688 | + $fullPath = $mount->getMountPoint().$internalPath; |
|
1689 | 1689 | if (!is_null($path = $this->getRelativePath($fullPath))) { |
1690 | 1690 | return $path; |
1691 | 1691 | } |
@@ -1728,10 +1728,10 @@ discard block |
||
1728 | 1728 | } |
1729 | 1729 | |
1730 | 1730 | // note: cannot use the view because the target is already locked |
1731 | - $fileId = (int)$targetStorage->getCache()->getId($targetInternalPath); |
|
1731 | + $fileId = (int) $targetStorage->getCache()->getId($targetInternalPath); |
|
1732 | 1732 | if ($fileId === -1) { |
1733 | 1733 | // target might not exist, need to check parent instead |
1734 | - $fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath)); |
|
1734 | + $fileId = (int) $targetStorage->getCache()->getId(dirname($targetInternalPath)); |
|
1735 | 1735 | } |
1736 | 1736 | |
1737 | 1737 | // check if any of the parents were shared by the current owner (include collections) |
@@ -1831,7 +1831,7 @@ discard block |
||
1831 | 1831 | $resultPath = ''; |
1832 | 1832 | foreach ($parts as $part) { |
1833 | 1833 | if ($part) { |
1834 | - $resultPath .= '/' . $part; |
|
1834 | + $resultPath .= '/'.$part; |
|
1835 | 1835 | $result[] = $resultPath; |
1836 | 1836 | } |
1837 | 1837 | } |
@@ -2081,16 +2081,16 @@ discard block |
||
2081 | 2081 | public function getUidAndFilename($filename) { |
2082 | 2082 | $info = $this->getFileInfo($filename); |
2083 | 2083 | if (!$info instanceof \OCP\Files\FileInfo) { |
2084 | - throw new NotFoundException($this->getAbsolutePath($filename) . ' not found'); |
|
2084 | + throw new NotFoundException($this->getAbsolutePath($filename).' not found'); |
|
2085 | 2085 | } |
2086 | 2086 | $uid = $info->getOwner()->getUID(); |
2087 | 2087 | if ($uid != \OCP\User::getUser()) { |
2088 | 2088 | Filesystem::initMountPoints($uid); |
2089 | - $ownerView = new View('/' . $uid . '/files'); |
|
2089 | + $ownerView = new View('/'.$uid.'/files'); |
|
2090 | 2090 | try { |
2091 | 2091 | $filename = $ownerView->getPath($info['fileid']); |
2092 | 2092 | } catch (NotFoundException $e) { |
2093 | - throw new NotFoundException('File with id ' . $info['fileid'] . ' not found for user ' . $uid); |
|
2093 | + throw new NotFoundException('File with id '.$info['fileid'].' not found for user '.$uid); |
|
2094 | 2094 | } |
2095 | 2095 | } |
2096 | 2096 | return [$uid, $filename]; |
@@ -2107,7 +2107,7 @@ discard block |
||
2107 | 2107 | $directoryParts = array_filter($directoryParts); |
2108 | 2108 | foreach ($directoryParts as $key => $part) { |
2109 | 2109 | $currentPathElements = array_slice($directoryParts, 0, $key); |
2110 | - $currentPath = '/' . implode('/', $currentPathElements); |
|
2110 | + $currentPath = '/'.implode('/', $currentPathElements); |
|
2111 | 2111 | if ($this->is_file($currentPath)) { |
2112 | 2112 | return false; |
2113 | 2113 | } |
@@ -82,2057 +82,2057 @@ |
||
82 | 82 | * \OC\Files\Storage\Storage object |
83 | 83 | */ |
84 | 84 | class View { |
85 | - /** @var string */ |
|
86 | - private $fakeRoot = ''; |
|
87 | - |
|
88 | - /** |
|
89 | - * @var \OCP\Lock\ILockingProvider |
|
90 | - */ |
|
91 | - protected $lockingProvider; |
|
92 | - |
|
93 | - private $lockingEnabled; |
|
94 | - |
|
95 | - private $updaterEnabled = true; |
|
96 | - |
|
97 | - /** @var \OC\User\Manager */ |
|
98 | - private $userManager; |
|
99 | - |
|
100 | - /** @var \OCP\ILogger */ |
|
101 | - private $logger; |
|
102 | - |
|
103 | - /** |
|
104 | - * @param string $root |
|
105 | - * @throws \Exception If $root contains an invalid path |
|
106 | - */ |
|
107 | - public function __construct($root = '') { |
|
108 | - if (is_null($root)) { |
|
109 | - throw new \InvalidArgumentException('Root can\'t be null'); |
|
110 | - } |
|
111 | - if (!Filesystem::isValidPath($root)) { |
|
112 | - throw new \Exception(); |
|
113 | - } |
|
114 | - |
|
115 | - $this->fakeRoot = $root; |
|
116 | - $this->lockingProvider = \OC::$server->getLockingProvider(); |
|
117 | - $this->lockingEnabled = !($this->lockingProvider instanceof \OC\Lock\NoopLockingProvider); |
|
118 | - $this->userManager = \OC::$server->getUserManager(); |
|
119 | - $this->logger = \OC::$server->getLogger(); |
|
120 | - } |
|
121 | - |
|
122 | - public function getAbsolutePath($path = '/') { |
|
123 | - if ($path === null) { |
|
124 | - return null; |
|
125 | - } |
|
126 | - $this->assertPathLength($path); |
|
127 | - if ($path === '') { |
|
128 | - $path = '/'; |
|
129 | - } |
|
130 | - if ($path[0] !== '/') { |
|
131 | - $path = '/' . $path; |
|
132 | - } |
|
133 | - return $this->fakeRoot . $path; |
|
134 | - } |
|
135 | - |
|
136 | - /** |
|
137 | - * change the root to a fake root |
|
138 | - * |
|
139 | - * @param string $fakeRoot |
|
140 | - * @return boolean|null |
|
141 | - */ |
|
142 | - public function chroot($fakeRoot) { |
|
143 | - if (!$fakeRoot == '') { |
|
144 | - if ($fakeRoot[0] !== '/') { |
|
145 | - $fakeRoot = '/' . $fakeRoot; |
|
146 | - } |
|
147 | - } |
|
148 | - $this->fakeRoot = $fakeRoot; |
|
149 | - } |
|
150 | - |
|
151 | - /** |
|
152 | - * get the fake root |
|
153 | - * |
|
154 | - * @return string |
|
155 | - */ |
|
156 | - public function getRoot() { |
|
157 | - return $this->fakeRoot; |
|
158 | - } |
|
159 | - |
|
160 | - /** |
|
161 | - * get path relative to the root of the view |
|
162 | - * |
|
163 | - * @param string $path |
|
164 | - * @return string |
|
165 | - */ |
|
166 | - public function getRelativePath($path) { |
|
167 | - $this->assertPathLength($path); |
|
168 | - if ($this->fakeRoot == '') { |
|
169 | - return $path; |
|
170 | - } |
|
171 | - |
|
172 | - if (rtrim($path, '/') === rtrim($this->fakeRoot, '/')) { |
|
173 | - return '/'; |
|
174 | - } |
|
175 | - |
|
176 | - // missing slashes can cause wrong matches! |
|
177 | - $root = rtrim($this->fakeRoot, '/') . '/'; |
|
178 | - |
|
179 | - if (strpos($path, $root) !== 0) { |
|
180 | - return null; |
|
181 | - } else { |
|
182 | - $path = substr($path, strlen($this->fakeRoot)); |
|
183 | - if (strlen($path) === 0) { |
|
184 | - return '/'; |
|
185 | - } else { |
|
186 | - return $path; |
|
187 | - } |
|
188 | - } |
|
189 | - } |
|
190 | - |
|
191 | - /** |
|
192 | - * get the mountpoint of the storage object for a path |
|
193 | - * ( note: because a storage is not always mounted inside the fakeroot, the |
|
194 | - * returned mountpoint is relative to the absolute root of the filesystem |
|
195 | - * and does not take the chroot into account ) |
|
196 | - * |
|
197 | - * @param string $path |
|
198 | - * @return string |
|
199 | - */ |
|
200 | - public function getMountPoint($path) { |
|
201 | - return Filesystem::getMountPoint($this->getAbsolutePath($path)); |
|
202 | - } |
|
203 | - |
|
204 | - /** |
|
205 | - * get the mountpoint of the storage object for a path |
|
206 | - * ( note: because a storage is not always mounted inside the fakeroot, the |
|
207 | - * returned mountpoint is relative to the absolute root of the filesystem |
|
208 | - * and does not take the chroot into account ) |
|
209 | - * |
|
210 | - * @param string $path |
|
211 | - * @return \OCP\Files\Mount\IMountPoint |
|
212 | - */ |
|
213 | - public function getMount($path) { |
|
214 | - return Filesystem::getMountManager()->find($this->getAbsolutePath($path)); |
|
215 | - } |
|
216 | - |
|
217 | - /** |
|
218 | - * resolve a path to a storage and internal path |
|
219 | - * |
|
220 | - * @param string $path |
|
221 | - * @return array an array consisting of the storage and the internal path |
|
222 | - */ |
|
223 | - public function resolvePath($path) { |
|
224 | - $a = $this->getAbsolutePath($path); |
|
225 | - $p = Filesystem::normalizePath($a); |
|
226 | - return Filesystem::resolvePath($p); |
|
227 | - } |
|
228 | - |
|
229 | - /** |
|
230 | - * return the path to a local version of the file |
|
231 | - * we need this because we can't know if a file is stored local or not from |
|
232 | - * outside the filestorage and for some purposes a local file is needed |
|
233 | - * |
|
234 | - * @param string $path |
|
235 | - * @return string |
|
236 | - */ |
|
237 | - public function getLocalFile($path) { |
|
238 | - $parent = substr($path, 0, strrpos($path, '/')); |
|
239 | - $path = $this->getAbsolutePath($path); |
|
240 | - list($storage, $internalPath) = Filesystem::resolvePath($path); |
|
241 | - if (Filesystem::isValidPath($parent) and $storage) { |
|
242 | - return $storage->getLocalFile($internalPath); |
|
243 | - } else { |
|
244 | - return null; |
|
245 | - } |
|
246 | - } |
|
247 | - |
|
248 | - /** |
|
249 | - * @param string $path |
|
250 | - * @return string |
|
251 | - */ |
|
252 | - public function getLocalFolder($path) { |
|
253 | - $parent = substr($path, 0, strrpos($path, '/')); |
|
254 | - $path = $this->getAbsolutePath($path); |
|
255 | - list($storage, $internalPath) = Filesystem::resolvePath($path); |
|
256 | - if (Filesystem::isValidPath($parent) and $storage) { |
|
257 | - return $storage->getLocalFolder($internalPath); |
|
258 | - } else { |
|
259 | - return null; |
|
260 | - } |
|
261 | - } |
|
262 | - |
|
263 | - /** |
|
264 | - * the following functions operate with arguments and return values identical |
|
265 | - * to those of their PHP built-in equivalents. Mostly they are merely wrappers |
|
266 | - * for \OC\Files\Storage\Storage via basicOperation(). |
|
267 | - */ |
|
268 | - public function mkdir($path) { |
|
269 | - return $this->basicOperation('mkdir', $path, array('create', 'write')); |
|
270 | - } |
|
271 | - |
|
272 | - /** |
|
273 | - * remove mount point |
|
274 | - * |
|
275 | - * @param \OC\Files\Mount\MoveableMount $mount |
|
276 | - * @param string $path relative to data/ |
|
277 | - * @return boolean |
|
278 | - */ |
|
279 | - protected function removeMount($mount, $path) { |
|
280 | - if ($mount instanceof MoveableMount) { |
|
281 | - // cut of /user/files to get the relative path to data/user/files |
|
282 | - $pathParts = explode('/', $path, 4); |
|
283 | - $relPath = '/' . $pathParts[3]; |
|
284 | - $this->lockFile($relPath, ILockingProvider::LOCK_SHARED, true); |
|
285 | - \OC_Hook::emit( |
|
286 | - Filesystem::CLASSNAME, "umount", |
|
287 | - array(Filesystem::signal_param_path => $relPath) |
|
288 | - ); |
|
289 | - $this->changeLock($relPath, ILockingProvider::LOCK_EXCLUSIVE, true); |
|
290 | - $result = $mount->removeMount(); |
|
291 | - $this->changeLock($relPath, ILockingProvider::LOCK_SHARED, true); |
|
292 | - if ($result) { |
|
293 | - \OC_Hook::emit( |
|
294 | - Filesystem::CLASSNAME, "post_umount", |
|
295 | - array(Filesystem::signal_param_path => $relPath) |
|
296 | - ); |
|
297 | - } |
|
298 | - $this->unlockFile($relPath, ILockingProvider::LOCK_SHARED, true); |
|
299 | - return $result; |
|
300 | - } else { |
|
301 | - // do not allow deleting the storage's root / the mount point |
|
302 | - // because for some storages it might delete the whole contents |
|
303 | - // but isn't supposed to work that way |
|
304 | - return false; |
|
305 | - } |
|
306 | - } |
|
307 | - |
|
308 | - public function disableCacheUpdate() { |
|
309 | - $this->updaterEnabled = false; |
|
310 | - } |
|
311 | - |
|
312 | - public function enableCacheUpdate() { |
|
313 | - $this->updaterEnabled = true; |
|
314 | - } |
|
315 | - |
|
316 | - protected function writeUpdate(Storage $storage, $internalPath, $time = null) { |
|
317 | - if ($this->updaterEnabled) { |
|
318 | - if (is_null($time)) { |
|
319 | - $time = time(); |
|
320 | - } |
|
321 | - $storage->getUpdater()->update($internalPath, $time); |
|
322 | - } |
|
323 | - } |
|
324 | - |
|
325 | - protected function removeUpdate(Storage $storage, $internalPath) { |
|
326 | - if ($this->updaterEnabled) { |
|
327 | - $storage->getUpdater()->remove($internalPath); |
|
328 | - } |
|
329 | - } |
|
330 | - |
|
331 | - protected function renameUpdate(Storage $sourceStorage, Storage $targetStorage, $sourceInternalPath, $targetInternalPath) { |
|
332 | - if ($this->updaterEnabled) { |
|
333 | - $targetStorage->getUpdater()->renameFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); |
|
334 | - } |
|
335 | - } |
|
336 | - |
|
337 | - /** |
|
338 | - * @param string $path |
|
339 | - * @return bool|mixed |
|
340 | - */ |
|
341 | - public function rmdir($path) { |
|
342 | - $absolutePath = $this->getAbsolutePath($path); |
|
343 | - $mount = Filesystem::getMountManager()->find($absolutePath); |
|
344 | - if ($mount->getInternalPath($absolutePath) === '') { |
|
345 | - return $this->removeMount($mount, $absolutePath); |
|
346 | - } |
|
347 | - if ($this->is_dir($path)) { |
|
348 | - $result = $this->basicOperation('rmdir', $path, array('delete')); |
|
349 | - } else { |
|
350 | - $result = false; |
|
351 | - } |
|
352 | - |
|
353 | - if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete |
|
354 | - $storage = $mount->getStorage(); |
|
355 | - $internalPath = $mount->getInternalPath($absolutePath); |
|
356 | - $storage->getUpdater()->remove($internalPath); |
|
357 | - } |
|
358 | - return $result; |
|
359 | - } |
|
360 | - |
|
361 | - /** |
|
362 | - * @param string $path |
|
363 | - * @return resource |
|
364 | - */ |
|
365 | - public function opendir($path) { |
|
366 | - return $this->basicOperation('opendir', $path, array('read')); |
|
367 | - } |
|
368 | - |
|
369 | - /** |
|
370 | - * @param $handle |
|
371 | - * @return mixed |
|
372 | - */ |
|
373 | - public function readdir($handle) { |
|
374 | - $fsLocal = new Storage\Local(array('datadir' => '/')); |
|
375 | - return $fsLocal->readdir($handle); |
|
376 | - } |
|
377 | - |
|
378 | - /** |
|
379 | - * @param string $path |
|
380 | - * @return bool|mixed |
|
381 | - */ |
|
382 | - public function is_dir($path) { |
|
383 | - if ($path == '/') { |
|
384 | - return true; |
|
385 | - } |
|
386 | - return $this->basicOperation('is_dir', $path); |
|
387 | - } |
|
388 | - |
|
389 | - /** |
|
390 | - * @param string $path |
|
391 | - * @return bool|mixed |
|
392 | - */ |
|
393 | - public function is_file($path) { |
|
394 | - if ($path == '/') { |
|
395 | - return false; |
|
396 | - } |
|
397 | - return $this->basicOperation('is_file', $path); |
|
398 | - } |
|
399 | - |
|
400 | - /** |
|
401 | - * @param string $path |
|
402 | - * @return mixed |
|
403 | - */ |
|
404 | - public function stat($path) { |
|
405 | - return $this->basicOperation('stat', $path); |
|
406 | - } |
|
407 | - |
|
408 | - /** |
|
409 | - * @param string $path |
|
410 | - * @return mixed |
|
411 | - */ |
|
412 | - public function filetype($path) { |
|
413 | - return $this->basicOperation('filetype', $path); |
|
414 | - } |
|
415 | - |
|
416 | - /** |
|
417 | - * @param string $path |
|
418 | - * @return mixed |
|
419 | - */ |
|
420 | - public function filesize($path) { |
|
421 | - return $this->basicOperation('filesize', $path); |
|
422 | - } |
|
423 | - |
|
424 | - /** |
|
425 | - * @param string $path |
|
426 | - * @return bool|mixed |
|
427 | - * @throws \OCP\Files\InvalidPathException |
|
428 | - */ |
|
429 | - public function readfile($path) { |
|
430 | - $this->assertPathLength($path); |
|
431 | - @ob_end_clean(); |
|
432 | - $handle = $this->fopen($path, 'rb'); |
|
433 | - if ($handle) { |
|
434 | - $chunkSize = 8192; // 8 kB chunks |
|
435 | - while (!feof($handle)) { |
|
436 | - echo fread($handle, $chunkSize); |
|
437 | - flush(); |
|
438 | - } |
|
439 | - fclose($handle); |
|
440 | - $size = $this->filesize($path); |
|
441 | - return $size; |
|
442 | - } |
|
443 | - return false; |
|
444 | - } |
|
445 | - |
|
446 | - /** |
|
447 | - * @param string $path |
|
448 | - * @param int $from |
|
449 | - * @param int $to |
|
450 | - * @return bool|mixed |
|
451 | - * @throws \OCP\Files\InvalidPathException |
|
452 | - * @throws \OCP\Files\UnseekableException |
|
453 | - */ |
|
454 | - public function readfilePart($path, $from, $to) { |
|
455 | - $this->assertPathLength($path); |
|
456 | - @ob_end_clean(); |
|
457 | - $handle = $this->fopen($path, 'rb'); |
|
458 | - if ($handle) { |
|
459 | - if (fseek($handle, $from) === 0) { |
|
460 | - $chunkSize = 8192; // 8 kB chunks |
|
461 | - $end = $to + 1; |
|
462 | - while (!feof($handle) && ftell($handle) < $end) { |
|
463 | - $len = $end - ftell($handle); |
|
464 | - if ($len > $chunkSize) { |
|
465 | - $len = $chunkSize; |
|
466 | - } |
|
467 | - echo fread($handle, $len); |
|
468 | - flush(); |
|
469 | - } |
|
470 | - $size = ftell($handle) - $from; |
|
471 | - return $size; |
|
472 | - } |
|
473 | - |
|
474 | - throw new \OCP\Files\UnseekableException('fseek error'); |
|
475 | - } |
|
476 | - return false; |
|
477 | - } |
|
478 | - |
|
479 | - /** |
|
480 | - * @param string $path |
|
481 | - * @return mixed |
|
482 | - */ |
|
483 | - public function isCreatable($path) { |
|
484 | - return $this->basicOperation('isCreatable', $path); |
|
485 | - } |
|
486 | - |
|
487 | - /** |
|
488 | - * @param string $path |
|
489 | - * @return mixed |
|
490 | - */ |
|
491 | - public function isReadable($path) { |
|
492 | - return $this->basicOperation('isReadable', $path); |
|
493 | - } |
|
494 | - |
|
495 | - /** |
|
496 | - * @param string $path |
|
497 | - * @return mixed |
|
498 | - */ |
|
499 | - public function isUpdatable($path) { |
|
500 | - return $this->basicOperation('isUpdatable', $path); |
|
501 | - } |
|
502 | - |
|
503 | - /** |
|
504 | - * @param string $path |
|
505 | - * @return bool|mixed |
|
506 | - */ |
|
507 | - public function isDeletable($path) { |
|
508 | - $absolutePath = $this->getAbsolutePath($path); |
|
509 | - $mount = Filesystem::getMountManager()->find($absolutePath); |
|
510 | - if ($mount->getInternalPath($absolutePath) === '') { |
|
511 | - return $mount instanceof MoveableMount; |
|
512 | - } |
|
513 | - return $this->basicOperation('isDeletable', $path); |
|
514 | - } |
|
515 | - |
|
516 | - /** |
|
517 | - * @param string $path |
|
518 | - * @return mixed |
|
519 | - */ |
|
520 | - public function isSharable($path) { |
|
521 | - return $this->basicOperation('isSharable', $path); |
|
522 | - } |
|
523 | - |
|
524 | - /** |
|
525 | - * @param string $path |
|
526 | - * @return bool|mixed |
|
527 | - */ |
|
528 | - public function file_exists($path) { |
|
529 | - if ($path == '/') { |
|
530 | - return true; |
|
531 | - } |
|
532 | - return $this->basicOperation('file_exists', $path); |
|
533 | - } |
|
534 | - |
|
535 | - /** |
|
536 | - * @param string $path |
|
537 | - * @return mixed |
|
538 | - */ |
|
539 | - public function filemtime($path) { |
|
540 | - return $this->basicOperation('filemtime', $path); |
|
541 | - } |
|
542 | - |
|
543 | - /** |
|
544 | - * @param string $path |
|
545 | - * @param int|string $mtime |
|
546 | - * @return bool |
|
547 | - */ |
|
548 | - public function touch($path, $mtime = null) { |
|
549 | - if (!is_null($mtime) and !is_numeric($mtime)) { |
|
550 | - $mtime = strtotime($mtime); |
|
551 | - } |
|
552 | - |
|
553 | - $hooks = array('touch'); |
|
554 | - |
|
555 | - if (!$this->file_exists($path)) { |
|
556 | - $hooks[] = 'create'; |
|
557 | - $hooks[] = 'write'; |
|
558 | - } |
|
559 | - $result = $this->basicOperation('touch', $path, $hooks, $mtime); |
|
560 | - if (!$result) { |
|
561 | - // If create file fails because of permissions on external storage like SMB folders, |
|
562 | - // check file exists and return false if not. |
|
563 | - if (!$this->file_exists($path)) { |
|
564 | - return false; |
|
565 | - } |
|
566 | - if (is_null($mtime)) { |
|
567 | - $mtime = time(); |
|
568 | - } |
|
569 | - //if native touch fails, we emulate it by changing the mtime in the cache |
|
570 | - $this->putFileInfo($path, array('mtime' => floor($mtime))); |
|
571 | - } |
|
572 | - return true; |
|
573 | - } |
|
574 | - |
|
575 | - /** |
|
576 | - * @param string $path |
|
577 | - * @return mixed |
|
578 | - */ |
|
579 | - public function file_get_contents($path) { |
|
580 | - return $this->basicOperation('file_get_contents', $path, array('read')); |
|
581 | - } |
|
582 | - |
|
583 | - /** |
|
584 | - * @param bool $exists |
|
585 | - * @param string $path |
|
586 | - * @param bool $run |
|
587 | - */ |
|
588 | - protected function emit_file_hooks_pre($exists, $path, &$run) { |
|
589 | - if (!$exists) { |
|
590 | - \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_create, array( |
|
591 | - Filesystem::signal_param_path => $this->getHookPath($path), |
|
592 | - Filesystem::signal_param_run => &$run, |
|
593 | - )); |
|
594 | - } else { |
|
595 | - \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_update, array( |
|
596 | - Filesystem::signal_param_path => $this->getHookPath($path), |
|
597 | - Filesystem::signal_param_run => &$run, |
|
598 | - )); |
|
599 | - } |
|
600 | - \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_write, array( |
|
601 | - Filesystem::signal_param_path => $this->getHookPath($path), |
|
602 | - Filesystem::signal_param_run => &$run, |
|
603 | - )); |
|
604 | - } |
|
605 | - |
|
606 | - /** |
|
607 | - * @param bool $exists |
|
608 | - * @param string $path |
|
609 | - */ |
|
610 | - protected function emit_file_hooks_post($exists, $path) { |
|
611 | - if (!$exists) { |
|
612 | - \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_create, array( |
|
613 | - Filesystem::signal_param_path => $this->getHookPath($path), |
|
614 | - )); |
|
615 | - } else { |
|
616 | - \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_update, array( |
|
617 | - Filesystem::signal_param_path => $this->getHookPath($path), |
|
618 | - )); |
|
619 | - } |
|
620 | - \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_write, array( |
|
621 | - Filesystem::signal_param_path => $this->getHookPath($path), |
|
622 | - )); |
|
623 | - } |
|
624 | - |
|
625 | - /** |
|
626 | - * @param string $path |
|
627 | - * @param mixed $data |
|
628 | - * @return bool|mixed |
|
629 | - * @throws \Exception |
|
630 | - */ |
|
631 | - public function file_put_contents($path, $data) { |
|
632 | - if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier |
|
633 | - $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
|
634 | - if (Filesystem::isValidPath($path) |
|
635 | - and !Filesystem::isFileBlacklisted($path) |
|
636 | - ) { |
|
637 | - $path = $this->getRelativePath($absolutePath); |
|
638 | - |
|
639 | - $this->lockFile($path, ILockingProvider::LOCK_SHARED); |
|
640 | - |
|
641 | - $exists = $this->file_exists($path); |
|
642 | - $run = true; |
|
643 | - if ($this->shouldEmitHooks($path)) { |
|
644 | - $this->emit_file_hooks_pre($exists, $path, $run); |
|
645 | - } |
|
646 | - if (!$run) { |
|
647 | - $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
648 | - return false; |
|
649 | - } |
|
650 | - |
|
651 | - $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
652 | - |
|
653 | - /** @var \OC\Files\Storage\Storage $storage */ |
|
654 | - list($storage, $internalPath) = $this->resolvePath($path); |
|
655 | - $target = $storage->fopen($internalPath, 'w'); |
|
656 | - if ($target) { |
|
657 | - list (, $result) = \OC_Helper::streamCopy($data, $target); |
|
658 | - fclose($target); |
|
659 | - fclose($data); |
|
660 | - |
|
661 | - $this->writeUpdate($storage, $internalPath); |
|
662 | - |
|
663 | - $this->changeLock($path, ILockingProvider::LOCK_SHARED); |
|
664 | - |
|
665 | - if ($this->shouldEmitHooks($path) && $result !== false) { |
|
666 | - $this->emit_file_hooks_post($exists, $path); |
|
667 | - } |
|
668 | - $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
669 | - return $result; |
|
670 | - } else { |
|
671 | - $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
672 | - return false; |
|
673 | - } |
|
674 | - } else { |
|
675 | - return false; |
|
676 | - } |
|
677 | - } else { |
|
678 | - $hooks = ($this->file_exists($path)) ? array('update', 'write') : array('create', 'write'); |
|
679 | - return $this->basicOperation('file_put_contents', $path, $hooks, $data); |
|
680 | - } |
|
681 | - } |
|
682 | - |
|
683 | - /** |
|
684 | - * @param string $path |
|
685 | - * @return bool|mixed |
|
686 | - */ |
|
687 | - public function unlink($path) { |
|
688 | - if ($path === '' || $path === '/') { |
|
689 | - // do not allow deleting the root |
|
690 | - return false; |
|
691 | - } |
|
692 | - $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; |
|
693 | - $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
|
694 | - $mount = Filesystem::getMountManager()->find($absolutePath . $postFix); |
|
695 | - if ($mount and $mount->getInternalPath($absolutePath) === '') { |
|
696 | - return $this->removeMount($mount, $absolutePath); |
|
697 | - } |
|
698 | - if ($this->is_dir($path)) { |
|
699 | - $result = $this->basicOperation('rmdir', $path, ['delete']); |
|
700 | - } else { |
|
701 | - $result = $this->basicOperation('unlink', $path, ['delete']); |
|
702 | - } |
|
703 | - if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete |
|
704 | - $storage = $mount->getStorage(); |
|
705 | - $internalPath = $mount->getInternalPath($absolutePath); |
|
706 | - $storage->getUpdater()->remove($internalPath); |
|
707 | - return true; |
|
708 | - } else { |
|
709 | - return $result; |
|
710 | - } |
|
711 | - } |
|
712 | - |
|
713 | - /** |
|
714 | - * @param string $directory |
|
715 | - * @return bool|mixed |
|
716 | - */ |
|
717 | - public function deleteAll($directory) { |
|
718 | - return $this->rmdir($directory); |
|
719 | - } |
|
720 | - |
|
721 | - /** |
|
722 | - * Rename/move a file or folder from the source path to target path. |
|
723 | - * |
|
724 | - * @param string $path1 source path |
|
725 | - * @param string $path2 target path |
|
726 | - * |
|
727 | - * @return bool|mixed |
|
728 | - */ |
|
729 | - public function rename($path1, $path2) { |
|
730 | - $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); |
|
731 | - $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); |
|
732 | - $result = false; |
|
733 | - if ( |
|
734 | - Filesystem::isValidPath($path2) |
|
735 | - and Filesystem::isValidPath($path1) |
|
736 | - and !Filesystem::isFileBlacklisted($path2) |
|
737 | - ) { |
|
738 | - $path1 = $this->getRelativePath($absolutePath1); |
|
739 | - $path2 = $this->getRelativePath($absolutePath2); |
|
740 | - $exists = $this->file_exists($path2); |
|
741 | - |
|
742 | - if ($path1 == null or $path2 == null) { |
|
743 | - return false; |
|
744 | - } |
|
745 | - |
|
746 | - $this->lockFile($path1, ILockingProvider::LOCK_SHARED, true); |
|
747 | - try { |
|
748 | - $this->lockFile($path2, ILockingProvider::LOCK_SHARED, true); |
|
749 | - } catch (LockedException $e) { |
|
750 | - $this->unlockFile($path1, ILockingProvider::LOCK_SHARED); |
|
751 | - throw $e; |
|
752 | - } |
|
753 | - |
|
754 | - $run = true; |
|
755 | - if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) { |
|
756 | - // if it was a rename from a part file to a regular file it was a write and not a rename operation |
|
757 | - $this->emit_file_hooks_pre($exists, $path2, $run); |
|
758 | - } elseif ($this->shouldEmitHooks($path1)) { |
|
759 | - \OC_Hook::emit( |
|
760 | - Filesystem::CLASSNAME, Filesystem::signal_rename, |
|
761 | - array( |
|
762 | - Filesystem::signal_param_oldpath => $this->getHookPath($path1), |
|
763 | - Filesystem::signal_param_newpath => $this->getHookPath($path2), |
|
764 | - Filesystem::signal_param_run => &$run |
|
765 | - ) |
|
766 | - ); |
|
767 | - } |
|
768 | - if ($run) { |
|
769 | - $this->verifyPath(dirname($path2), basename($path2)); |
|
770 | - |
|
771 | - $manager = Filesystem::getMountManager(); |
|
772 | - $mount1 = $this->getMount($path1); |
|
773 | - $mount2 = $this->getMount($path2); |
|
774 | - $storage1 = $mount1->getStorage(); |
|
775 | - $storage2 = $mount2->getStorage(); |
|
776 | - $internalPath1 = $mount1->getInternalPath($absolutePath1); |
|
777 | - $internalPath2 = $mount2->getInternalPath($absolutePath2); |
|
778 | - |
|
779 | - $this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE, true); |
|
780 | - $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE, true); |
|
781 | - |
|
782 | - if ($internalPath1 === '' and $mount1 instanceof MoveableMount) { |
|
783 | - if ($this->isTargetAllowed($absolutePath2)) { |
|
784 | - /** |
|
785 | - * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1 |
|
786 | - */ |
|
787 | - $sourceMountPoint = $mount1->getMountPoint(); |
|
788 | - $result = $mount1->moveMount($absolutePath2); |
|
789 | - $manager->moveMount($sourceMountPoint, $mount1->getMountPoint()); |
|
790 | - } else { |
|
791 | - $result = false; |
|
792 | - } |
|
793 | - // moving a file/folder within the same mount point |
|
794 | - } elseif ($storage1 === $storage2) { |
|
795 | - if ($storage1) { |
|
796 | - $result = $storage1->rename($internalPath1, $internalPath2); |
|
797 | - } else { |
|
798 | - $result = false; |
|
799 | - } |
|
800 | - // moving a file/folder between storages (from $storage1 to $storage2) |
|
801 | - } else { |
|
802 | - $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); |
|
803 | - } |
|
804 | - |
|
805 | - if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) { |
|
806 | - // if it was a rename from a part file to a regular file it was a write and not a rename operation |
|
807 | - |
|
808 | - $this->writeUpdate($storage2, $internalPath2); |
|
809 | - } else if ($result) { |
|
810 | - if ($internalPath1 !== '') { // don't do a cache update for moved mounts |
|
811 | - $this->renameUpdate($storage1, $storage2, $internalPath1, $internalPath2); |
|
812 | - } |
|
813 | - } |
|
814 | - |
|
815 | - $this->changeLock($path1, ILockingProvider::LOCK_SHARED, true); |
|
816 | - $this->changeLock($path2, ILockingProvider::LOCK_SHARED, true); |
|
817 | - |
|
818 | - if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) { |
|
819 | - if ($this->shouldEmitHooks()) { |
|
820 | - $this->emit_file_hooks_post($exists, $path2); |
|
821 | - } |
|
822 | - } elseif ($result) { |
|
823 | - if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) { |
|
824 | - \OC_Hook::emit( |
|
825 | - Filesystem::CLASSNAME, |
|
826 | - Filesystem::signal_post_rename, |
|
827 | - array( |
|
828 | - Filesystem::signal_param_oldpath => $this->getHookPath($path1), |
|
829 | - Filesystem::signal_param_newpath => $this->getHookPath($path2) |
|
830 | - ) |
|
831 | - ); |
|
832 | - } |
|
833 | - } |
|
834 | - } |
|
835 | - $this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true); |
|
836 | - $this->unlockFile($path2, ILockingProvider::LOCK_SHARED, true); |
|
837 | - } |
|
838 | - return $result; |
|
839 | - } |
|
840 | - |
|
841 | - /** |
|
842 | - * Copy a file/folder from the source path to target path |
|
843 | - * |
|
844 | - * @param string $path1 source path |
|
845 | - * @param string $path2 target path |
|
846 | - * @param bool $preserveMtime whether to preserve mtime on the copy |
|
847 | - * |
|
848 | - * @return bool|mixed |
|
849 | - */ |
|
850 | - public function copy($path1, $path2, $preserveMtime = false) { |
|
851 | - $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); |
|
852 | - $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); |
|
853 | - $result = false; |
|
854 | - if ( |
|
855 | - Filesystem::isValidPath($path2) |
|
856 | - and Filesystem::isValidPath($path1) |
|
857 | - and !Filesystem::isFileBlacklisted($path2) |
|
858 | - ) { |
|
859 | - $path1 = $this->getRelativePath($absolutePath1); |
|
860 | - $path2 = $this->getRelativePath($absolutePath2); |
|
861 | - |
|
862 | - if ($path1 == null or $path2 == null) { |
|
863 | - return false; |
|
864 | - } |
|
865 | - $run = true; |
|
866 | - |
|
867 | - $this->lockFile($path2, ILockingProvider::LOCK_SHARED); |
|
868 | - $this->lockFile($path1, ILockingProvider::LOCK_SHARED); |
|
869 | - $lockTypePath1 = ILockingProvider::LOCK_SHARED; |
|
870 | - $lockTypePath2 = ILockingProvider::LOCK_SHARED; |
|
871 | - |
|
872 | - try { |
|
873 | - |
|
874 | - $exists = $this->file_exists($path2); |
|
875 | - if ($this->shouldEmitHooks()) { |
|
876 | - \OC_Hook::emit( |
|
877 | - Filesystem::CLASSNAME, |
|
878 | - Filesystem::signal_copy, |
|
879 | - array( |
|
880 | - Filesystem::signal_param_oldpath => $this->getHookPath($path1), |
|
881 | - Filesystem::signal_param_newpath => $this->getHookPath($path2), |
|
882 | - Filesystem::signal_param_run => &$run |
|
883 | - ) |
|
884 | - ); |
|
885 | - $this->emit_file_hooks_pre($exists, $path2, $run); |
|
886 | - } |
|
887 | - if ($run) { |
|
888 | - $mount1 = $this->getMount($path1); |
|
889 | - $mount2 = $this->getMount($path2); |
|
890 | - $storage1 = $mount1->getStorage(); |
|
891 | - $internalPath1 = $mount1->getInternalPath($absolutePath1); |
|
892 | - $storage2 = $mount2->getStorage(); |
|
893 | - $internalPath2 = $mount2->getInternalPath($absolutePath2); |
|
894 | - |
|
895 | - $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE); |
|
896 | - $lockTypePath2 = ILockingProvider::LOCK_EXCLUSIVE; |
|
897 | - |
|
898 | - if ($mount1->getMountPoint() == $mount2->getMountPoint()) { |
|
899 | - if ($storage1) { |
|
900 | - $result = $storage1->copy($internalPath1, $internalPath2); |
|
901 | - } else { |
|
902 | - $result = false; |
|
903 | - } |
|
904 | - } else { |
|
905 | - $result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2); |
|
906 | - } |
|
907 | - |
|
908 | - $this->writeUpdate($storage2, $internalPath2); |
|
909 | - |
|
910 | - $this->changeLock($path2, ILockingProvider::LOCK_SHARED); |
|
911 | - $lockTypePath2 = ILockingProvider::LOCK_SHARED; |
|
912 | - |
|
913 | - if ($this->shouldEmitHooks() && $result !== false) { |
|
914 | - \OC_Hook::emit( |
|
915 | - Filesystem::CLASSNAME, |
|
916 | - Filesystem::signal_post_copy, |
|
917 | - array( |
|
918 | - Filesystem::signal_param_oldpath => $this->getHookPath($path1), |
|
919 | - Filesystem::signal_param_newpath => $this->getHookPath($path2) |
|
920 | - ) |
|
921 | - ); |
|
922 | - $this->emit_file_hooks_post($exists, $path2); |
|
923 | - } |
|
924 | - |
|
925 | - } |
|
926 | - } catch (\Exception $e) { |
|
927 | - $this->unlockFile($path2, $lockTypePath2); |
|
928 | - $this->unlockFile($path1, $lockTypePath1); |
|
929 | - throw $e; |
|
930 | - } |
|
931 | - |
|
932 | - $this->unlockFile($path2, $lockTypePath2); |
|
933 | - $this->unlockFile($path1, $lockTypePath1); |
|
934 | - |
|
935 | - } |
|
936 | - return $result; |
|
937 | - } |
|
938 | - |
|
939 | - /** |
|
940 | - * @param string $path |
|
941 | - * @param string $mode 'r' or 'w' |
|
942 | - * @return resource |
|
943 | - */ |
|
944 | - public function fopen($path, $mode) { |
|
945 | - $mode = str_replace('b', '', $mode); // the binary flag is a windows only feature which we do not support |
|
946 | - $hooks = array(); |
|
947 | - switch ($mode) { |
|
948 | - case 'r': |
|
949 | - $hooks[] = 'read'; |
|
950 | - break; |
|
951 | - case 'r+': |
|
952 | - case 'w+': |
|
953 | - case 'x+': |
|
954 | - case 'a+': |
|
955 | - $hooks[] = 'read'; |
|
956 | - $hooks[] = 'write'; |
|
957 | - break; |
|
958 | - case 'w': |
|
959 | - case 'x': |
|
960 | - case 'a': |
|
961 | - $hooks[] = 'write'; |
|
962 | - break; |
|
963 | - default: |
|
964 | - \OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR); |
|
965 | - } |
|
966 | - |
|
967 | - if ($mode !== 'r' && $mode !== 'w') { |
|
968 | - \OC::$server->getLogger()->info('Trying to open a file with a mode other than "r" or "w" can cause severe performance issues with some backends'); |
|
969 | - } |
|
970 | - |
|
971 | - return $this->basicOperation('fopen', $path, $hooks, $mode); |
|
972 | - } |
|
973 | - |
|
974 | - /** |
|
975 | - * @param string $path |
|
976 | - * @return bool|string |
|
977 | - * @throws \OCP\Files\InvalidPathException |
|
978 | - */ |
|
979 | - public function toTmpFile($path) { |
|
980 | - $this->assertPathLength($path); |
|
981 | - if (Filesystem::isValidPath($path)) { |
|
982 | - $source = $this->fopen($path, 'r'); |
|
983 | - if ($source) { |
|
984 | - $extension = pathinfo($path, PATHINFO_EXTENSION); |
|
985 | - $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension); |
|
986 | - file_put_contents($tmpFile, $source); |
|
987 | - return $tmpFile; |
|
988 | - } else { |
|
989 | - return false; |
|
990 | - } |
|
991 | - } else { |
|
992 | - return false; |
|
993 | - } |
|
994 | - } |
|
995 | - |
|
996 | - /** |
|
997 | - * @param string $tmpFile |
|
998 | - * @param string $path |
|
999 | - * @return bool|mixed |
|
1000 | - * @throws \OCP\Files\InvalidPathException |
|
1001 | - */ |
|
1002 | - public function fromTmpFile($tmpFile, $path) { |
|
1003 | - $this->assertPathLength($path); |
|
1004 | - if (Filesystem::isValidPath($path)) { |
|
1005 | - |
|
1006 | - // Get directory that the file is going into |
|
1007 | - $filePath = dirname($path); |
|
1008 | - |
|
1009 | - // Create the directories if any |
|
1010 | - if (!$this->file_exists($filePath)) { |
|
1011 | - $result = $this->createParentDirectories($filePath); |
|
1012 | - if ($result === false) { |
|
1013 | - return false; |
|
1014 | - } |
|
1015 | - } |
|
1016 | - |
|
1017 | - $source = fopen($tmpFile, 'r'); |
|
1018 | - if ($source) { |
|
1019 | - $result = $this->file_put_contents($path, $source); |
|
1020 | - // $this->file_put_contents() might have already closed |
|
1021 | - // the resource, so we check it, before trying to close it |
|
1022 | - // to avoid messages in the error log. |
|
1023 | - if (is_resource($source)) { |
|
1024 | - fclose($source); |
|
1025 | - } |
|
1026 | - unlink($tmpFile); |
|
1027 | - return $result; |
|
1028 | - } else { |
|
1029 | - return false; |
|
1030 | - } |
|
1031 | - } else { |
|
1032 | - return false; |
|
1033 | - } |
|
1034 | - } |
|
1035 | - |
|
1036 | - |
|
1037 | - /** |
|
1038 | - * @param string $path |
|
1039 | - * @return mixed |
|
1040 | - * @throws \OCP\Files\InvalidPathException |
|
1041 | - */ |
|
1042 | - public function getMimeType($path) { |
|
1043 | - $this->assertPathLength($path); |
|
1044 | - return $this->basicOperation('getMimeType', $path); |
|
1045 | - } |
|
1046 | - |
|
1047 | - /** |
|
1048 | - * @param string $type |
|
1049 | - * @param string $path |
|
1050 | - * @param bool $raw |
|
1051 | - * @return bool|null|string |
|
1052 | - */ |
|
1053 | - public function hash($type, $path, $raw = false) { |
|
1054 | - $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; |
|
1055 | - $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
|
1056 | - if (Filesystem::isValidPath($path)) { |
|
1057 | - $path = $this->getRelativePath($absolutePath); |
|
1058 | - if ($path == null) { |
|
1059 | - return false; |
|
1060 | - } |
|
1061 | - if ($this->shouldEmitHooks($path)) { |
|
1062 | - \OC_Hook::emit( |
|
1063 | - Filesystem::CLASSNAME, |
|
1064 | - Filesystem::signal_read, |
|
1065 | - array(Filesystem::signal_param_path => $this->getHookPath($path)) |
|
1066 | - ); |
|
1067 | - } |
|
1068 | - list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); |
|
1069 | - if ($storage) { |
|
1070 | - $result = $storage->hash($type, $internalPath, $raw); |
|
1071 | - return $result; |
|
1072 | - } |
|
1073 | - } |
|
1074 | - return null; |
|
1075 | - } |
|
1076 | - |
|
1077 | - /** |
|
1078 | - * @param string $path |
|
1079 | - * @return mixed |
|
1080 | - * @throws \OCP\Files\InvalidPathException |
|
1081 | - */ |
|
1082 | - public function free_space($path = '/') { |
|
1083 | - $this->assertPathLength($path); |
|
1084 | - $result = $this->basicOperation('free_space', $path); |
|
1085 | - if ($result === null) { |
|
1086 | - throw new InvalidPathException(); |
|
1087 | - } |
|
1088 | - return $result; |
|
1089 | - } |
|
1090 | - |
|
1091 | - /** |
|
1092 | - * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage |
|
1093 | - * |
|
1094 | - * @param string $operation |
|
1095 | - * @param string $path |
|
1096 | - * @param array $hooks (optional) |
|
1097 | - * @param mixed $extraParam (optional) |
|
1098 | - * @return mixed |
|
1099 | - * @throws \Exception |
|
1100 | - * |
|
1101 | - * This method takes requests for basic filesystem functions (e.g. reading & writing |
|
1102 | - * files), processes hooks and proxies, sanitises paths, and finally passes them on to |
|
1103 | - * \OC\Files\Storage\Storage for delegation to a storage backend for execution |
|
1104 | - */ |
|
1105 | - private function basicOperation($operation, $path, $hooks = [], $extraParam = null) { |
|
1106 | - $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; |
|
1107 | - $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
|
1108 | - if (Filesystem::isValidPath($path) |
|
1109 | - and !Filesystem::isFileBlacklisted($path) |
|
1110 | - ) { |
|
1111 | - $path = $this->getRelativePath($absolutePath); |
|
1112 | - if ($path == null) { |
|
1113 | - return false; |
|
1114 | - } |
|
1115 | - |
|
1116 | - if (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) { |
|
1117 | - // always a shared lock during pre-hooks so the hook can read the file |
|
1118 | - $this->lockFile($path, ILockingProvider::LOCK_SHARED); |
|
1119 | - } |
|
1120 | - |
|
1121 | - $run = $this->runHooks($hooks, $path); |
|
1122 | - /** @var \OC\Files\Storage\Storage $storage */ |
|
1123 | - list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); |
|
1124 | - if ($run and $storage) { |
|
1125 | - if (in_array('write', $hooks) || in_array('delete', $hooks)) { |
|
1126 | - $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
1127 | - } |
|
1128 | - try { |
|
1129 | - if (!is_null($extraParam)) { |
|
1130 | - $result = $storage->$operation($internalPath, $extraParam); |
|
1131 | - } else { |
|
1132 | - $result = $storage->$operation($internalPath); |
|
1133 | - } |
|
1134 | - } catch (\Exception $e) { |
|
1135 | - if (in_array('write', $hooks) || in_array('delete', $hooks)) { |
|
1136 | - $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
1137 | - } else if (in_array('read', $hooks)) { |
|
1138 | - $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
1139 | - } |
|
1140 | - throw $e; |
|
1141 | - } |
|
1142 | - |
|
1143 | - if ($result && in_array('delete', $hooks) and $result) { |
|
1144 | - $this->removeUpdate($storage, $internalPath); |
|
1145 | - } |
|
1146 | - if ($result && in_array('write', $hooks) and $operation !== 'fopen') { |
|
1147 | - $this->writeUpdate($storage, $internalPath); |
|
1148 | - } |
|
1149 | - if ($result && in_array('touch', $hooks)) { |
|
1150 | - $this->writeUpdate($storage, $internalPath, $extraParam); |
|
1151 | - } |
|
1152 | - |
|
1153 | - if ((in_array('write', $hooks) || in_array('delete', $hooks)) && ($operation !== 'fopen' || $result === false)) { |
|
1154 | - $this->changeLock($path, ILockingProvider::LOCK_SHARED); |
|
1155 | - } |
|
1156 | - |
|
1157 | - $unlockLater = false; |
|
1158 | - if ($this->lockingEnabled && $operation === 'fopen' && is_resource($result)) { |
|
1159 | - $unlockLater = true; |
|
1160 | - // make sure our unlocking callback will still be called if connection is aborted |
|
1161 | - ignore_user_abort(true); |
|
1162 | - $result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) { |
|
1163 | - if (in_array('write', $hooks)) { |
|
1164 | - $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
1165 | - } else if (in_array('read', $hooks)) { |
|
1166 | - $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
1167 | - } |
|
1168 | - }); |
|
1169 | - } |
|
1170 | - |
|
1171 | - if ($this->shouldEmitHooks($path) && $result !== false) { |
|
1172 | - if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open |
|
1173 | - $this->runHooks($hooks, $path, true); |
|
1174 | - } |
|
1175 | - } |
|
1176 | - |
|
1177 | - if (!$unlockLater |
|
1178 | - && (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) |
|
1179 | - ) { |
|
1180 | - $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
1181 | - } |
|
1182 | - return $result; |
|
1183 | - } else { |
|
1184 | - $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
1185 | - } |
|
1186 | - } |
|
1187 | - return null; |
|
1188 | - } |
|
1189 | - |
|
1190 | - /** |
|
1191 | - * get the path relative to the default root for hook usage |
|
1192 | - * |
|
1193 | - * @param string $path |
|
1194 | - * @return string |
|
1195 | - */ |
|
1196 | - private function getHookPath($path) { |
|
1197 | - if (!Filesystem::getView()) { |
|
1198 | - return $path; |
|
1199 | - } |
|
1200 | - return Filesystem::getView()->getRelativePath($this->getAbsolutePath($path)); |
|
1201 | - } |
|
1202 | - |
|
1203 | - private function shouldEmitHooks($path = '') { |
|
1204 | - if ($path && Cache\Scanner::isPartialFile($path)) { |
|
1205 | - return false; |
|
1206 | - } |
|
1207 | - if (!Filesystem::$loaded) { |
|
1208 | - return false; |
|
1209 | - } |
|
1210 | - $defaultRoot = Filesystem::getRoot(); |
|
1211 | - if ($defaultRoot === null) { |
|
1212 | - return false; |
|
1213 | - } |
|
1214 | - if ($this->fakeRoot === $defaultRoot) { |
|
1215 | - return true; |
|
1216 | - } |
|
1217 | - $fullPath = $this->getAbsolutePath($path); |
|
1218 | - |
|
1219 | - if ($fullPath === $defaultRoot) { |
|
1220 | - return true; |
|
1221 | - } |
|
1222 | - |
|
1223 | - return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/'); |
|
1224 | - } |
|
1225 | - |
|
1226 | - /** |
|
1227 | - * @param string[] $hooks |
|
1228 | - * @param string $path |
|
1229 | - * @param bool $post |
|
1230 | - * @return bool |
|
1231 | - */ |
|
1232 | - private function runHooks($hooks, $path, $post = false) { |
|
1233 | - $relativePath = $path; |
|
1234 | - $path = $this->getHookPath($path); |
|
1235 | - $prefix = ($post) ? 'post_' : ''; |
|
1236 | - $run = true; |
|
1237 | - if ($this->shouldEmitHooks($relativePath)) { |
|
1238 | - foreach ($hooks as $hook) { |
|
1239 | - if ($hook != 'read') { |
|
1240 | - \OC_Hook::emit( |
|
1241 | - Filesystem::CLASSNAME, |
|
1242 | - $prefix . $hook, |
|
1243 | - array( |
|
1244 | - Filesystem::signal_param_run => &$run, |
|
1245 | - Filesystem::signal_param_path => $path |
|
1246 | - ) |
|
1247 | - ); |
|
1248 | - } elseif (!$post) { |
|
1249 | - \OC_Hook::emit( |
|
1250 | - Filesystem::CLASSNAME, |
|
1251 | - $prefix . $hook, |
|
1252 | - array( |
|
1253 | - Filesystem::signal_param_path => $path |
|
1254 | - ) |
|
1255 | - ); |
|
1256 | - } |
|
1257 | - } |
|
1258 | - } |
|
1259 | - return $run; |
|
1260 | - } |
|
1261 | - |
|
1262 | - /** |
|
1263 | - * check if a file or folder has been updated since $time |
|
1264 | - * |
|
1265 | - * @param string $path |
|
1266 | - * @param int $time |
|
1267 | - * @return bool |
|
1268 | - */ |
|
1269 | - public function hasUpdated($path, $time) { |
|
1270 | - return $this->basicOperation('hasUpdated', $path, array(), $time); |
|
1271 | - } |
|
1272 | - |
|
1273 | - /** |
|
1274 | - * @param string $ownerId |
|
1275 | - * @return \OC\User\User |
|
1276 | - */ |
|
1277 | - private function getUserObjectForOwner($ownerId) { |
|
1278 | - $owner = $this->userManager->get($ownerId); |
|
1279 | - if ($owner instanceof IUser) { |
|
1280 | - return $owner; |
|
1281 | - } else { |
|
1282 | - return new User($ownerId, null); |
|
1283 | - } |
|
1284 | - } |
|
1285 | - |
|
1286 | - /** |
|
1287 | - * Get file info from cache |
|
1288 | - * |
|
1289 | - * If the file is not in cached it will be scanned |
|
1290 | - * If the file has changed on storage the cache will be updated |
|
1291 | - * |
|
1292 | - * @param \OC\Files\Storage\Storage $storage |
|
1293 | - * @param string $internalPath |
|
1294 | - * @param string $relativePath |
|
1295 | - * @return array|bool |
|
1296 | - */ |
|
1297 | - private function getCacheEntry($storage, $internalPath, $relativePath) { |
|
1298 | - $cache = $storage->getCache($internalPath); |
|
1299 | - $data = $cache->get($internalPath); |
|
1300 | - $watcher = $storage->getWatcher($internalPath); |
|
1301 | - |
|
1302 | - try { |
|
1303 | - // if the file is not in the cache or needs to be updated, trigger the scanner and reload the data |
|
1304 | - if (!$data || $data['size'] === -1) { |
|
1305 | - $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1306 | - if (!$storage->file_exists($internalPath)) { |
|
1307 | - $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1308 | - return false; |
|
1309 | - } |
|
1310 | - $scanner = $storage->getScanner($internalPath); |
|
1311 | - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); |
|
1312 | - $data = $cache->get($internalPath); |
|
1313 | - $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1314 | - } else if (!Cache\Scanner::isPartialFile($internalPath) && $watcher->needsUpdate($internalPath, $data)) { |
|
1315 | - $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1316 | - $watcher->update($internalPath, $data); |
|
1317 | - $storage->getPropagator()->propagateChange($internalPath, time()); |
|
1318 | - $data = $cache->get($internalPath); |
|
1319 | - $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1320 | - } |
|
1321 | - } catch (LockedException $e) { |
|
1322 | - // if the file is locked we just use the old cache info |
|
1323 | - } |
|
1324 | - |
|
1325 | - return $data; |
|
1326 | - } |
|
1327 | - |
|
1328 | - /** |
|
1329 | - * get the filesystem info |
|
1330 | - * |
|
1331 | - * @param string $path |
|
1332 | - * @param boolean|string $includeMountPoints true to add mountpoint sizes, |
|
1333 | - * 'ext' to add only ext storage mount point sizes. Defaults to true. |
|
1334 | - * defaults to true |
|
1335 | - * @return \OC\Files\FileInfo|false False if file does not exist |
|
1336 | - */ |
|
1337 | - public function getFileInfo($path, $includeMountPoints = true) { |
|
1338 | - $this->assertPathLength($path); |
|
1339 | - if (!Filesystem::isValidPath($path)) { |
|
1340 | - return false; |
|
1341 | - } |
|
1342 | - if (Cache\Scanner::isPartialFile($path)) { |
|
1343 | - return $this->getPartFileInfo($path); |
|
1344 | - } |
|
1345 | - $relativePath = $path; |
|
1346 | - $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); |
|
1347 | - |
|
1348 | - $mount = Filesystem::getMountManager()->find($path); |
|
1349 | - $storage = $mount->getStorage(); |
|
1350 | - $internalPath = $mount->getInternalPath($path); |
|
1351 | - if ($storage) { |
|
1352 | - $data = $this->getCacheEntry($storage, $internalPath, $relativePath); |
|
1353 | - |
|
1354 | - if (!$data instanceof ICacheEntry) { |
|
1355 | - return false; |
|
1356 | - } |
|
1357 | - |
|
1358 | - if ($mount instanceof MoveableMount && $internalPath === '') { |
|
1359 | - $data['permissions'] |= \OCP\Constants::PERMISSION_DELETE; |
|
1360 | - } |
|
1361 | - |
|
1362 | - $owner = $this->getUserObjectForOwner($storage->getOwner($internalPath)); |
|
1363 | - $info = new FileInfo($path, $storage, $internalPath, $data, $mount, $owner); |
|
1364 | - |
|
1365 | - if ($data and isset($data['fileid'])) { |
|
1366 | - if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { |
|
1367 | - //add the sizes of other mount points to the folder |
|
1368 | - $extOnly = ($includeMountPoints === 'ext'); |
|
1369 | - $mounts = Filesystem::getMountManager()->findIn($path); |
|
1370 | - $info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) { |
|
1371 | - $subStorage = $mount->getStorage(); |
|
1372 | - return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage); |
|
1373 | - })); |
|
1374 | - } |
|
1375 | - } |
|
1376 | - |
|
1377 | - return $info; |
|
1378 | - } |
|
1379 | - |
|
1380 | - return false; |
|
1381 | - } |
|
1382 | - |
|
1383 | - /** |
|
1384 | - * get the content of a directory |
|
1385 | - * |
|
1386 | - * @param string $directory path under datadirectory |
|
1387 | - * @param string $mimetype_filter limit returned content to this mimetype or mimepart |
|
1388 | - * @return FileInfo[] |
|
1389 | - */ |
|
1390 | - public function getDirectoryContent($directory, $mimetype_filter = '') { |
|
1391 | - $this->assertPathLength($directory); |
|
1392 | - if (!Filesystem::isValidPath($directory)) { |
|
1393 | - return []; |
|
1394 | - } |
|
1395 | - $path = $this->getAbsolutePath($directory); |
|
1396 | - $path = Filesystem::normalizePath($path); |
|
1397 | - $mount = $this->getMount($directory); |
|
1398 | - $storage = $mount->getStorage(); |
|
1399 | - $internalPath = $mount->getInternalPath($path); |
|
1400 | - if ($storage) { |
|
1401 | - $cache = $storage->getCache($internalPath); |
|
1402 | - $user = \OC_User::getUser(); |
|
1403 | - |
|
1404 | - $data = $this->getCacheEntry($storage, $internalPath, $directory); |
|
1405 | - |
|
1406 | - if (!$data instanceof ICacheEntry || !isset($data['fileid']) || !($data->getPermissions() && Constants::PERMISSION_READ)) { |
|
1407 | - return []; |
|
1408 | - } |
|
1409 | - |
|
1410 | - $folderId = $data['fileid']; |
|
1411 | - $contents = $cache->getFolderContentsById($folderId); //TODO: mimetype_filter |
|
1412 | - |
|
1413 | - $sharingDisabled = \OCP\Util::isSharingDisabledForUser(); |
|
1414 | - /** |
|
1415 | - * @var \OC\Files\FileInfo[] $files |
|
1416 | - */ |
|
1417 | - $files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) { |
|
1418 | - if ($sharingDisabled) { |
|
1419 | - $content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE; |
|
1420 | - } |
|
1421 | - $owner = $this->getUserObjectForOwner($storage->getOwner($content['path'])); |
|
1422 | - return new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount, $owner); |
|
1423 | - }, $contents); |
|
1424 | - |
|
1425 | - //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders |
|
1426 | - $mounts = Filesystem::getMountManager()->findIn($path); |
|
1427 | - $dirLength = strlen($path); |
|
1428 | - foreach ($mounts as $mount) { |
|
1429 | - $mountPoint = $mount->getMountPoint(); |
|
1430 | - $subStorage = $mount->getStorage(); |
|
1431 | - if ($subStorage) { |
|
1432 | - $subCache = $subStorage->getCache(''); |
|
1433 | - |
|
1434 | - $rootEntry = $subCache->get(''); |
|
1435 | - if (!$rootEntry) { |
|
1436 | - $subScanner = $subStorage->getScanner(''); |
|
1437 | - try { |
|
1438 | - $subScanner->scanFile(''); |
|
1439 | - } catch (\OCP\Files\StorageNotAvailableException $e) { |
|
1440 | - continue; |
|
1441 | - } catch (\OCP\Files\StorageInvalidException $e) { |
|
1442 | - continue; |
|
1443 | - } catch (\Exception $e) { |
|
1444 | - // sometimes when the storage is not available it can be any exception |
|
1445 | - \OCP\Util::writeLog( |
|
1446 | - 'core', |
|
1447 | - 'Exception while scanning storage "' . $subStorage->getId() . '": ' . |
|
1448 | - get_class($e) . ': ' . $e->getMessage(), |
|
1449 | - \OCP\Util::ERROR |
|
1450 | - ); |
|
1451 | - continue; |
|
1452 | - } |
|
1453 | - $rootEntry = $subCache->get(''); |
|
1454 | - } |
|
1455 | - |
|
1456 | - if ($rootEntry && ($rootEntry->getPermissions() && Constants::PERMISSION_READ)) { |
|
1457 | - $relativePath = trim(substr($mountPoint, $dirLength), '/'); |
|
1458 | - if ($pos = strpos($relativePath, '/')) { |
|
1459 | - //mountpoint inside subfolder add size to the correct folder |
|
1460 | - $entryName = substr($relativePath, 0, $pos); |
|
1461 | - foreach ($files as &$entry) { |
|
1462 | - if ($entry->getName() === $entryName) { |
|
1463 | - $entry->addSubEntry($rootEntry, $mountPoint); |
|
1464 | - } |
|
1465 | - } |
|
1466 | - } else { //mountpoint in this folder, add an entry for it |
|
1467 | - $rootEntry['name'] = $relativePath; |
|
1468 | - $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; |
|
1469 | - $permissions = $rootEntry['permissions']; |
|
1470 | - // do not allow renaming/deleting the mount point if they are not shared files/folders |
|
1471 | - // for shared files/folders we use the permissions given by the owner |
|
1472 | - if ($mount instanceof MoveableMount) { |
|
1473 | - $rootEntry['permissions'] = $permissions | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE; |
|
1474 | - } else { |
|
1475 | - $rootEntry['permissions'] = $permissions & (\OCP\Constants::PERMISSION_ALL - (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)); |
|
1476 | - } |
|
1477 | - |
|
1478 | - //remove any existing entry with the same name |
|
1479 | - foreach ($files as $i => $file) { |
|
1480 | - if ($file['name'] === $rootEntry['name']) { |
|
1481 | - unset($files[$i]); |
|
1482 | - break; |
|
1483 | - } |
|
1484 | - } |
|
1485 | - $rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/ |
|
1486 | - |
|
1487 | - // if sharing was disabled for the user we remove the share permissions |
|
1488 | - if (\OCP\Util::isSharingDisabledForUser()) { |
|
1489 | - $rootEntry['permissions'] = $rootEntry['permissions'] & ~\OCP\Constants::PERMISSION_SHARE; |
|
1490 | - } |
|
1491 | - |
|
1492 | - $owner = $this->getUserObjectForOwner($subStorage->getOwner('')); |
|
1493 | - $files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner); |
|
1494 | - } |
|
1495 | - } |
|
1496 | - } |
|
1497 | - } |
|
1498 | - |
|
1499 | - if ($mimetype_filter) { |
|
1500 | - $files = array_filter($files, function (FileInfo $file) use ($mimetype_filter) { |
|
1501 | - if (strpos($mimetype_filter, '/')) { |
|
1502 | - return $file->getMimetype() === $mimetype_filter; |
|
1503 | - } else { |
|
1504 | - return $file->getMimePart() === $mimetype_filter; |
|
1505 | - } |
|
1506 | - }); |
|
1507 | - } |
|
1508 | - |
|
1509 | - return $files; |
|
1510 | - } else { |
|
1511 | - return []; |
|
1512 | - } |
|
1513 | - } |
|
1514 | - |
|
1515 | - /** |
|
1516 | - * change file metadata |
|
1517 | - * |
|
1518 | - * @param string $path |
|
1519 | - * @param array|\OCP\Files\FileInfo $data |
|
1520 | - * @return int |
|
1521 | - * |
|
1522 | - * returns the fileid of the updated file |
|
1523 | - */ |
|
1524 | - public function putFileInfo($path, $data) { |
|
1525 | - $this->assertPathLength($path); |
|
1526 | - if ($data instanceof FileInfo) { |
|
1527 | - $data = $data->getData(); |
|
1528 | - } |
|
1529 | - $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); |
|
1530 | - /** |
|
1531 | - * @var \OC\Files\Storage\Storage $storage |
|
1532 | - * @var string $internalPath |
|
1533 | - */ |
|
1534 | - list($storage, $internalPath) = Filesystem::resolvePath($path); |
|
1535 | - if ($storage) { |
|
1536 | - $cache = $storage->getCache($path); |
|
1537 | - |
|
1538 | - if (!$cache->inCache($internalPath)) { |
|
1539 | - $scanner = $storage->getScanner($internalPath); |
|
1540 | - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); |
|
1541 | - } |
|
1542 | - |
|
1543 | - return $cache->put($internalPath, $data); |
|
1544 | - } else { |
|
1545 | - return -1; |
|
1546 | - } |
|
1547 | - } |
|
1548 | - |
|
1549 | - /** |
|
1550 | - * search for files with the name matching $query |
|
1551 | - * |
|
1552 | - * @param string $query |
|
1553 | - * @return FileInfo[] |
|
1554 | - */ |
|
1555 | - public function search($query) { |
|
1556 | - return $this->searchCommon('search', array('%' . $query . '%')); |
|
1557 | - } |
|
1558 | - |
|
1559 | - /** |
|
1560 | - * search for files with the name matching $query |
|
1561 | - * |
|
1562 | - * @param string $query |
|
1563 | - * @return FileInfo[] |
|
1564 | - */ |
|
1565 | - public function searchRaw($query) { |
|
1566 | - return $this->searchCommon('search', array($query)); |
|
1567 | - } |
|
1568 | - |
|
1569 | - /** |
|
1570 | - * search for files by mimetype |
|
1571 | - * |
|
1572 | - * @param string $mimetype |
|
1573 | - * @return FileInfo[] |
|
1574 | - */ |
|
1575 | - public function searchByMime($mimetype) { |
|
1576 | - return $this->searchCommon('searchByMime', array($mimetype)); |
|
1577 | - } |
|
1578 | - |
|
1579 | - /** |
|
1580 | - * search for files by tag |
|
1581 | - * |
|
1582 | - * @param string|int $tag name or tag id |
|
1583 | - * @param string $userId owner of the tags |
|
1584 | - * @return FileInfo[] |
|
1585 | - */ |
|
1586 | - public function searchByTag($tag, $userId) { |
|
1587 | - return $this->searchCommon('searchByTag', array($tag, $userId)); |
|
1588 | - } |
|
1589 | - |
|
1590 | - /** |
|
1591 | - * @param string $method cache method |
|
1592 | - * @param array $args |
|
1593 | - * @return FileInfo[] |
|
1594 | - */ |
|
1595 | - private function searchCommon($method, $args) { |
|
1596 | - $files = array(); |
|
1597 | - $rootLength = strlen($this->fakeRoot); |
|
1598 | - |
|
1599 | - $mount = $this->getMount(''); |
|
1600 | - $mountPoint = $mount->getMountPoint(); |
|
1601 | - $storage = $mount->getStorage(); |
|
1602 | - if ($storage) { |
|
1603 | - $cache = $storage->getCache(''); |
|
1604 | - |
|
1605 | - $results = call_user_func_array(array($cache, $method), $args); |
|
1606 | - foreach ($results as $result) { |
|
1607 | - if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') { |
|
1608 | - $internalPath = $result['path']; |
|
1609 | - $path = $mountPoint . $result['path']; |
|
1610 | - $result['path'] = substr($mountPoint . $result['path'], $rootLength); |
|
1611 | - $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath)); |
|
1612 | - $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner); |
|
1613 | - } |
|
1614 | - } |
|
1615 | - |
|
1616 | - $mounts = Filesystem::getMountManager()->findIn($this->fakeRoot); |
|
1617 | - foreach ($mounts as $mount) { |
|
1618 | - $mountPoint = $mount->getMountPoint(); |
|
1619 | - $storage = $mount->getStorage(); |
|
1620 | - if ($storage) { |
|
1621 | - $cache = $storage->getCache(''); |
|
1622 | - |
|
1623 | - $relativeMountPoint = substr($mountPoint, $rootLength); |
|
1624 | - $results = call_user_func_array(array($cache, $method), $args); |
|
1625 | - if ($results) { |
|
1626 | - foreach ($results as $result) { |
|
1627 | - $internalPath = $result['path']; |
|
1628 | - $result['path'] = rtrim($relativeMountPoint . $result['path'], '/'); |
|
1629 | - $path = rtrim($mountPoint . $internalPath, '/'); |
|
1630 | - $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath)); |
|
1631 | - $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner); |
|
1632 | - } |
|
1633 | - } |
|
1634 | - } |
|
1635 | - } |
|
1636 | - } |
|
1637 | - return $files; |
|
1638 | - } |
|
1639 | - |
|
1640 | - /** |
|
1641 | - * Get the owner for a file or folder |
|
1642 | - * |
|
1643 | - * @param string $path |
|
1644 | - * @return string the user id of the owner |
|
1645 | - * @throws NotFoundException |
|
1646 | - */ |
|
1647 | - public function getOwner($path) { |
|
1648 | - $info = $this->getFileInfo($path); |
|
1649 | - if (!$info) { |
|
1650 | - throw new NotFoundException($path . ' not found while trying to get owner'); |
|
1651 | - } |
|
1652 | - return $info->getOwner()->getUID(); |
|
1653 | - } |
|
1654 | - |
|
1655 | - /** |
|
1656 | - * get the ETag for a file or folder |
|
1657 | - * |
|
1658 | - * @param string $path |
|
1659 | - * @return string |
|
1660 | - */ |
|
1661 | - public function getETag($path) { |
|
1662 | - /** |
|
1663 | - * @var Storage\Storage $storage |
|
1664 | - * @var string $internalPath |
|
1665 | - */ |
|
1666 | - list($storage, $internalPath) = $this->resolvePath($path); |
|
1667 | - if ($storage) { |
|
1668 | - return $storage->getETag($internalPath); |
|
1669 | - } else { |
|
1670 | - return null; |
|
1671 | - } |
|
1672 | - } |
|
1673 | - |
|
1674 | - /** |
|
1675 | - * Get the path of a file by id, relative to the view |
|
1676 | - * |
|
1677 | - * Note that the resulting path is not guarantied to be unique for the id, multiple paths can point to the same file |
|
1678 | - * |
|
1679 | - * @param int $id |
|
1680 | - * @throws NotFoundException |
|
1681 | - * @return string |
|
1682 | - */ |
|
1683 | - public function getPath($id) { |
|
1684 | - $id = (int)$id; |
|
1685 | - $manager = Filesystem::getMountManager(); |
|
1686 | - $mounts = $manager->findIn($this->fakeRoot); |
|
1687 | - $mounts[] = $manager->find($this->fakeRoot); |
|
1688 | - // reverse the array so we start with the storage this view is in |
|
1689 | - // which is the most likely to contain the file we're looking for |
|
1690 | - $mounts = array_reverse($mounts); |
|
1691 | - foreach ($mounts as $mount) { |
|
1692 | - /** |
|
1693 | - * @var \OC\Files\Mount\MountPoint $mount |
|
1694 | - */ |
|
1695 | - if ($mount->getStorage()) { |
|
1696 | - $cache = $mount->getStorage()->getCache(); |
|
1697 | - $internalPath = $cache->getPathById($id); |
|
1698 | - if (is_string($internalPath)) { |
|
1699 | - $fullPath = $mount->getMountPoint() . $internalPath; |
|
1700 | - if (!is_null($path = $this->getRelativePath($fullPath))) { |
|
1701 | - return $path; |
|
1702 | - } |
|
1703 | - } |
|
1704 | - } |
|
1705 | - } |
|
1706 | - throw new NotFoundException(sprintf('File with id "%s" has not been found.', $id)); |
|
1707 | - } |
|
1708 | - |
|
1709 | - /** |
|
1710 | - * @param string $path |
|
1711 | - * @throws InvalidPathException |
|
1712 | - */ |
|
1713 | - private function assertPathLength($path) { |
|
1714 | - $maxLen = min(PHP_MAXPATHLEN, 4000); |
|
1715 | - // Check for the string length - performed using isset() instead of strlen() |
|
1716 | - // because isset() is about 5x-40x faster. |
|
1717 | - if (isset($path[$maxLen])) { |
|
1718 | - $pathLen = strlen($path); |
|
1719 | - throw new \OCP\Files\InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path"); |
|
1720 | - } |
|
1721 | - } |
|
1722 | - |
|
1723 | - /** |
|
1724 | - * check if it is allowed to move a mount point to a given target. |
|
1725 | - * It is not allowed to move a mount point into a different mount point or |
|
1726 | - * into an already shared folder |
|
1727 | - * |
|
1728 | - * @param string $target path |
|
1729 | - * @return boolean |
|
1730 | - */ |
|
1731 | - private function isTargetAllowed($target) { |
|
1732 | - |
|
1733 | - list($targetStorage, $targetInternalPath) = \OC\Files\Filesystem::resolvePath($target); |
|
1734 | - if (!$targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage')) { |
|
1735 | - \OCP\Util::writeLog('files', |
|
1736 | - 'It is not allowed to move one mount point into another one', |
|
1737 | - \OCP\Util::DEBUG); |
|
1738 | - return false; |
|
1739 | - } |
|
1740 | - |
|
1741 | - // note: cannot use the view because the target is already locked |
|
1742 | - $fileId = (int)$targetStorage->getCache()->getId($targetInternalPath); |
|
1743 | - if ($fileId === -1) { |
|
1744 | - // target might not exist, need to check parent instead |
|
1745 | - $fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath)); |
|
1746 | - } |
|
1747 | - |
|
1748 | - // check if any of the parents were shared by the current owner (include collections) |
|
1749 | - $shares = \OCP\Share::getItemShared( |
|
1750 | - 'folder', |
|
1751 | - $fileId, |
|
1752 | - \OCP\Share::FORMAT_NONE, |
|
1753 | - null, |
|
1754 | - true |
|
1755 | - ); |
|
1756 | - |
|
1757 | - if (count($shares) > 0) { |
|
1758 | - \OCP\Util::writeLog('files', |
|
1759 | - 'It is not allowed to move one mount point into a shared folder', |
|
1760 | - \OCP\Util::DEBUG); |
|
1761 | - return false; |
|
1762 | - } |
|
1763 | - |
|
1764 | - return true; |
|
1765 | - } |
|
1766 | - |
|
1767 | - /** |
|
1768 | - * Get a fileinfo object for files that are ignored in the cache (part files) |
|
1769 | - * |
|
1770 | - * @param string $path |
|
1771 | - * @return \OCP\Files\FileInfo |
|
1772 | - */ |
|
1773 | - private function getPartFileInfo($path) { |
|
1774 | - $mount = $this->getMount($path); |
|
1775 | - $storage = $mount->getStorage(); |
|
1776 | - $internalPath = $mount->getInternalPath($this->getAbsolutePath($path)); |
|
1777 | - $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath)); |
|
1778 | - return new FileInfo( |
|
1779 | - $this->getAbsolutePath($path), |
|
1780 | - $storage, |
|
1781 | - $internalPath, |
|
1782 | - [ |
|
1783 | - 'fileid' => null, |
|
1784 | - 'mimetype' => $storage->getMimeType($internalPath), |
|
1785 | - 'name' => basename($path), |
|
1786 | - 'etag' => null, |
|
1787 | - 'size' => $storage->filesize($internalPath), |
|
1788 | - 'mtime' => $storage->filemtime($internalPath), |
|
1789 | - 'encrypted' => false, |
|
1790 | - 'permissions' => \OCP\Constants::PERMISSION_ALL |
|
1791 | - ], |
|
1792 | - $mount, |
|
1793 | - $owner |
|
1794 | - ); |
|
1795 | - } |
|
1796 | - |
|
1797 | - /** |
|
1798 | - * @param string $path |
|
1799 | - * @param string $fileName |
|
1800 | - * @throws InvalidPathException |
|
1801 | - */ |
|
1802 | - public function verifyPath($path, $fileName) { |
|
1803 | - try { |
|
1804 | - /** @type \OCP\Files\Storage $storage */ |
|
1805 | - list($storage, $internalPath) = $this->resolvePath($path); |
|
1806 | - $storage->verifyPath($internalPath, $fileName); |
|
1807 | - } catch (ReservedWordException $ex) { |
|
1808 | - $l = \OC::$server->getL10N('lib'); |
|
1809 | - throw new InvalidPathException($l->t('File name is a reserved word')); |
|
1810 | - } catch (InvalidCharacterInPathException $ex) { |
|
1811 | - $l = \OC::$server->getL10N('lib'); |
|
1812 | - throw new InvalidPathException($l->t('File name contains at least one invalid character')); |
|
1813 | - } catch (FileNameTooLongException $ex) { |
|
1814 | - $l = \OC::$server->getL10N('lib'); |
|
1815 | - throw new InvalidPathException($l->t('File name is too long')); |
|
1816 | - } catch (InvalidDirectoryException $ex) { |
|
1817 | - $l = \OC::$server->getL10N('lib'); |
|
1818 | - throw new InvalidPathException($l->t('Dot files are not allowed')); |
|
1819 | - } catch (EmptyFileNameException $ex) { |
|
1820 | - $l = \OC::$server->getL10N('lib'); |
|
1821 | - throw new InvalidPathException($l->t('Empty filename is not allowed')); |
|
1822 | - } |
|
1823 | - } |
|
1824 | - |
|
1825 | - /** |
|
1826 | - * get all parent folders of $path |
|
1827 | - * |
|
1828 | - * @param string $path |
|
1829 | - * @return string[] |
|
1830 | - */ |
|
1831 | - private function getParents($path) { |
|
1832 | - $path = trim($path, '/'); |
|
1833 | - if (!$path) { |
|
1834 | - return []; |
|
1835 | - } |
|
1836 | - |
|
1837 | - $parts = explode('/', $path); |
|
1838 | - |
|
1839 | - // remove the single file |
|
1840 | - array_pop($parts); |
|
1841 | - $result = array('/'); |
|
1842 | - $resultPath = ''; |
|
1843 | - foreach ($parts as $part) { |
|
1844 | - if ($part) { |
|
1845 | - $resultPath .= '/' . $part; |
|
1846 | - $result[] = $resultPath; |
|
1847 | - } |
|
1848 | - } |
|
1849 | - return $result; |
|
1850 | - } |
|
1851 | - |
|
1852 | - /** |
|
1853 | - * Returns the mount point for which to lock |
|
1854 | - * |
|
1855 | - * @param string $absolutePath absolute path |
|
1856 | - * @param bool $useParentMount true to return parent mount instead of whatever |
|
1857 | - * is mounted directly on the given path, false otherwise |
|
1858 | - * @return \OC\Files\Mount\MountPoint mount point for which to apply locks |
|
1859 | - */ |
|
1860 | - private function getMountForLock($absolutePath, $useParentMount = false) { |
|
1861 | - $results = []; |
|
1862 | - $mount = Filesystem::getMountManager()->find($absolutePath); |
|
1863 | - if (!$mount) { |
|
1864 | - return $results; |
|
1865 | - } |
|
1866 | - |
|
1867 | - if ($useParentMount) { |
|
1868 | - // find out if something is mounted directly on the path |
|
1869 | - $internalPath = $mount->getInternalPath($absolutePath); |
|
1870 | - if ($internalPath === '') { |
|
1871 | - // resolve the parent mount instead |
|
1872 | - $mount = Filesystem::getMountManager()->find(dirname($absolutePath)); |
|
1873 | - } |
|
1874 | - } |
|
1875 | - |
|
1876 | - return $mount; |
|
1877 | - } |
|
1878 | - |
|
1879 | - /** |
|
1880 | - * Lock the given path |
|
1881 | - * |
|
1882 | - * @param string $path the path of the file to lock, relative to the view |
|
1883 | - * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
1884 | - * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
1885 | - * |
|
1886 | - * @return bool False if the path is excluded from locking, true otherwise |
|
1887 | - * @throws \OCP\Lock\LockedException if the path is already locked |
|
1888 | - */ |
|
1889 | - private function lockPath($path, $type, $lockMountPoint = false) { |
|
1890 | - $absolutePath = $this->getAbsolutePath($path); |
|
1891 | - $absolutePath = Filesystem::normalizePath($absolutePath); |
|
1892 | - if (!$this->shouldLockFile($absolutePath)) { |
|
1893 | - return false; |
|
1894 | - } |
|
1895 | - |
|
1896 | - $mount = $this->getMountForLock($absolutePath, $lockMountPoint); |
|
1897 | - if ($mount) { |
|
1898 | - try { |
|
1899 | - $storage = $mount->getStorage(); |
|
1900 | - if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { |
|
1901 | - $storage->acquireLock( |
|
1902 | - $mount->getInternalPath($absolutePath), |
|
1903 | - $type, |
|
1904 | - $this->lockingProvider |
|
1905 | - ); |
|
1906 | - } |
|
1907 | - } catch (\OCP\Lock\LockedException $e) { |
|
1908 | - // rethrow with the a human-readable path |
|
1909 | - throw new \OCP\Lock\LockedException( |
|
1910 | - $this->getPathRelativeToFiles($absolutePath), |
|
1911 | - $e |
|
1912 | - ); |
|
1913 | - } |
|
1914 | - } |
|
1915 | - |
|
1916 | - return true; |
|
1917 | - } |
|
1918 | - |
|
1919 | - /** |
|
1920 | - * Change the lock type |
|
1921 | - * |
|
1922 | - * @param string $path the path of the file to lock, relative to the view |
|
1923 | - * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
1924 | - * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
1925 | - * |
|
1926 | - * @return bool False if the path is excluded from locking, true otherwise |
|
1927 | - * @throws \OCP\Lock\LockedException if the path is already locked |
|
1928 | - */ |
|
1929 | - public function changeLock($path, $type, $lockMountPoint = false) { |
|
1930 | - $path = Filesystem::normalizePath($path); |
|
1931 | - $absolutePath = $this->getAbsolutePath($path); |
|
1932 | - $absolutePath = Filesystem::normalizePath($absolutePath); |
|
1933 | - if (!$this->shouldLockFile($absolutePath)) { |
|
1934 | - return false; |
|
1935 | - } |
|
1936 | - |
|
1937 | - $mount = $this->getMountForLock($absolutePath, $lockMountPoint); |
|
1938 | - if ($mount) { |
|
1939 | - try { |
|
1940 | - $storage = $mount->getStorage(); |
|
1941 | - if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { |
|
1942 | - $storage->changeLock( |
|
1943 | - $mount->getInternalPath($absolutePath), |
|
1944 | - $type, |
|
1945 | - $this->lockingProvider |
|
1946 | - ); |
|
1947 | - } |
|
1948 | - } catch (\OCP\Lock\LockedException $e) { |
|
1949 | - // rethrow with the a human-readable path |
|
1950 | - throw new \OCP\Lock\LockedException( |
|
1951 | - $this->getPathRelativeToFiles($absolutePath), |
|
1952 | - $e |
|
1953 | - ); |
|
1954 | - } |
|
1955 | - } |
|
1956 | - |
|
1957 | - return true; |
|
1958 | - } |
|
1959 | - |
|
1960 | - /** |
|
1961 | - * Unlock the given path |
|
1962 | - * |
|
1963 | - * @param string $path the path of the file to unlock, relative to the view |
|
1964 | - * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
1965 | - * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
1966 | - * |
|
1967 | - * @return bool False if the path is excluded from locking, true otherwise |
|
1968 | - */ |
|
1969 | - private function unlockPath($path, $type, $lockMountPoint = false) { |
|
1970 | - $absolutePath = $this->getAbsolutePath($path); |
|
1971 | - $absolutePath = Filesystem::normalizePath($absolutePath); |
|
1972 | - if (!$this->shouldLockFile($absolutePath)) { |
|
1973 | - return false; |
|
1974 | - } |
|
1975 | - |
|
1976 | - $mount = $this->getMountForLock($absolutePath, $lockMountPoint); |
|
1977 | - if ($mount) { |
|
1978 | - $storage = $mount->getStorage(); |
|
1979 | - if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { |
|
1980 | - $storage->releaseLock( |
|
1981 | - $mount->getInternalPath($absolutePath), |
|
1982 | - $type, |
|
1983 | - $this->lockingProvider |
|
1984 | - ); |
|
1985 | - } |
|
1986 | - } |
|
1987 | - |
|
1988 | - return true; |
|
1989 | - } |
|
1990 | - |
|
1991 | - /** |
|
1992 | - * Lock a path and all its parents up to the root of the view |
|
1993 | - * |
|
1994 | - * @param string $path the path of the file to lock relative to the view |
|
1995 | - * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
1996 | - * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
1997 | - * |
|
1998 | - * @return bool False if the path is excluded from locking, true otherwise |
|
1999 | - */ |
|
2000 | - public function lockFile($path, $type, $lockMountPoint = false) { |
|
2001 | - $absolutePath = $this->getAbsolutePath($path); |
|
2002 | - $absolutePath = Filesystem::normalizePath($absolutePath); |
|
2003 | - if (!$this->shouldLockFile($absolutePath)) { |
|
2004 | - return false; |
|
2005 | - } |
|
2006 | - |
|
2007 | - $this->lockPath($path, $type, $lockMountPoint); |
|
2008 | - |
|
2009 | - $parents = $this->getParents($path); |
|
2010 | - foreach ($parents as $parent) { |
|
2011 | - $this->lockPath($parent, ILockingProvider::LOCK_SHARED); |
|
2012 | - } |
|
2013 | - |
|
2014 | - return true; |
|
2015 | - } |
|
2016 | - |
|
2017 | - /** |
|
2018 | - * Unlock a path and all its parents up to the root of the view |
|
2019 | - * |
|
2020 | - * @param string $path the path of the file to lock relative to the view |
|
2021 | - * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
2022 | - * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
2023 | - * |
|
2024 | - * @return bool False if the path is excluded from locking, true otherwise |
|
2025 | - */ |
|
2026 | - public function unlockFile($path, $type, $lockMountPoint = false) { |
|
2027 | - $absolutePath = $this->getAbsolutePath($path); |
|
2028 | - $absolutePath = Filesystem::normalizePath($absolutePath); |
|
2029 | - if (!$this->shouldLockFile($absolutePath)) { |
|
2030 | - return false; |
|
2031 | - } |
|
2032 | - |
|
2033 | - $this->unlockPath($path, $type, $lockMountPoint); |
|
2034 | - |
|
2035 | - $parents = $this->getParents($path); |
|
2036 | - foreach ($parents as $parent) { |
|
2037 | - $this->unlockPath($parent, ILockingProvider::LOCK_SHARED); |
|
2038 | - } |
|
2039 | - |
|
2040 | - return true; |
|
2041 | - } |
|
2042 | - |
|
2043 | - /** |
|
2044 | - * Only lock files in data/user/files/ |
|
2045 | - * |
|
2046 | - * @param string $path Absolute path to the file/folder we try to (un)lock |
|
2047 | - * @return bool |
|
2048 | - */ |
|
2049 | - protected function shouldLockFile($path) { |
|
2050 | - $path = Filesystem::normalizePath($path); |
|
2051 | - |
|
2052 | - $pathSegments = explode('/', $path); |
|
2053 | - if (isset($pathSegments[2])) { |
|
2054 | - // E.g.: /username/files/path-to-file |
|
2055 | - return ($pathSegments[2] === 'files') && (count($pathSegments) > 3); |
|
2056 | - } |
|
2057 | - |
|
2058 | - return true; |
|
2059 | - } |
|
2060 | - |
|
2061 | - /** |
|
2062 | - * Shortens the given absolute path to be relative to |
|
2063 | - * "$user/files". |
|
2064 | - * |
|
2065 | - * @param string $absolutePath absolute path which is under "files" |
|
2066 | - * |
|
2067 | - * @return string path relative to "files" with trimmed slashes or null |
|
2068 | - * if the path was NOT relative to files |
|
2069 | - * |
|
2070 | - * @throws \InvalidArgumentException if the given path was not under "files" |
|
2071 | - * @since 8.1.0 |
|
2072 | - */ |
|
2073 | - public function getPathRelativeToFiles($absolutePath) { |
|
2074 | - $path = Filesystem::normalizePath($absolutePath); |
|
2075 | - $parts = explode('/', trim($path, '/'), 3); |
|
2076 | - // "$user", "files", "path/to/dir" |
|
2077 | - if (!isset($parts[1]) || $parts[1] !== 'files') { |
|
2078 | - $this->logger->error( |
|
2079 | - '$absolutePath must be relative to "files", value is "%s"', |
|
2080 | - [ |
|
2081 | - $absolutePath |
|
2082 | - ] |
|
2083 | - ); |
|
2084 | - throw new \InvalidArgumentException('$absolutePath must be relative to "files"'); |
|
2085 | - } |
|
2086 | - if (isset($parts[2])) { |
|
2087 | - return $parts[2]; |
|
2088 | - } |
|
2089 | - return ''; |
|
2090 | - } |
|
2091 | - |
|
2092 | - /** |
|
2093 | - * @param string $filename |
|
2094 | - * @return array |
|
2095 | - * @throws \OC\User\NoUserException |
|
2096 | - * @throws NotFoundException |
|
2097 | - */ |
|
2098 | - public function getUidAndFilename($filename) { |
|
2099 | - $info = $this->getFileInfo($filename); |
|
2100 | - if (!$info instanceof \OCP\Files\FileInfo) { |
|
2101 | - throw new NotFoundException($this->getAbsolutePath($filename) . ' not found'); |
|
2102 | - } |
|
2103 | - $uid = $info->getOwner()->getUID(); |
|
2104 | - if ($uid != \OCP\User::getUser()) { |
|
2105 | - Filesystem::initMountPoints($uid); |
|
2106 | - $ownerView = new View('/' . $uid . '/files'); |
|
2107 | - try { |
|
2108 | - $filename = $ownerView->getPath($info['fileid']); |
|
2109 | - } catch (NotFoundException $e) { |
|
2110 | - throw new NotFoundException('File with id ' . $info['fileid'] . ' not found for user ' . $uid); |
|
2111 | - } |
|
2112 | - } |
|
2113 | - return [$uid, $filename]; |
|
2114 | - } |
|
2115 | - |
|
2116 | - /** |
|
2117 | - * Creates parent non-existing folders |
|
2118 | - * |
|
2119 | - * @param string $filePath |
|
2120 | - * @return bool |
|
2121 | - */ |
|
2122 | - private function createParentDirectories($filePath) { |
|
2123 | - $directoryParts = explode('/', $filePath); |
|
2124 | - $directoryParts = array_filter($directoryParts); |
|
2125 | - foreach ($directoryParts as $key => $part) { |
|
2126 | - $currentPathElements = array_slice($directoryParts, 0, $key); |
|
2127 | - $currentPath = '/' . implode('/', $currentPathElements); |
|
2128 | - if ($this->is_file($currentPath)) { |
|
2129 | - return false; |
|
2130 | - } |
|
2131 | - if (!$this->file_exists($currentPath)) { |
|
2132 | - $this->mkdir($currentPath); |
|
2133 | - } |
|
2134 | - } |
|
2135 | - |
|
2136 | - return true; |
|
2137 | - } |
|
85 | + /** @var string */ |
|
86 | + private $fakeRoot = ''; |
|
87 | + |
|
88 | + /** |
|
89 | + * @var \OCP\Lock\ILockingProvider |
|
90 | + */ |
|
91 | + protected $lockingProvider; |
|
92 | + |
|
93 | + private $lockingEnabled; |
|
94 | + |
|
95 | + private $updaterEnabled = true; |
|
96 | + |
|
97 | + /** @var \OC\User\Manager */ |
|
98 | + private $userManager; |
|
99 | + |
|
100 | + /** @var \OCP\ILogger */ |
|
101 | + private $logger; |
|
102 | + |
|
103 | + /** |
|
104 | + * @param string $root |
|
105 | + * @throws \Exception If $root contains an invalid path |
|
106 | + */ |
|
107 | + public function __construct($root = '') { |
|
108 | + if (is_null($root)) { |
|
109 | + throw new \InvalidArgumentException('Root can\'t be null'); |
|
110 | + } |
|
111 | + if (!Filesystem::isValidPath($root)) { |
|
112 | + throw new \Exception(); |
|
113 | + } |
|
114 | + |
|
115 | + $this->fakeRoot = $root; |
|
116 | + $this->lockingProvider = \OC::$server->getLockingProvider(); |
|
117 | + $this->lockingEnabled = !($this->lockingProvider instanceof \OC\Lock\NoopLockingProvider); |
|
118 | + $this->userManager = \OC::$server->getUserManager(); |
|
119 | + $this->logger = \OC::$server->getLogger(); |
|
120 | + } |
|
121 | + |
|
122 | + public function getAbsolutePath($path = '/') { |
|
123 | + if ($path === null) { |
|
124 | + return null; |
|
125 | + } |
|
126 | + $this->assertPathLength($path); |
|
127 | + if ($path === '') { |
|
128 | + $path = '/'; |
|
129 | + } |
|
130 | + if ($path[0] !== '/') { |
|
131 | + $path = '/' . $path; |
|
132 | + } |
|
133 | + return $this->fakeRoot . $path; |
|
134 | + } |
|
135 | + |
|
136 | + /** |
|
137 | + * change the root to a fake root |
|
138 | + * |
|
139 | + * @param string $fakeRoot |
|
140 | + * @return boolean|null |
|
141 | + */ |
|
142 | + public function chroot($fakeRoot) { |
|
143 | + if (!$fakeRoot == '') { |
|
144 | + if ($fakeRoot[0] !== '/') { |
|
145 | + $fakeRoot = '/' . $fakeRoot; |
|
146 | + } |
|
147 | + } |
|
148 | + $this->fakeRoot = $fakeRoot; |
|
149 | + } |
|
150 | + |
|
151 | + /** |
|
152 | + * get the fake root |
|
153 | + * |
|
154 | + * @return string |
|
155 | + */ |
|
156 | + public function getRoot() { |
|
157 | + return $this->fakeRoot; |
|
158 | + } |
|
159 | + |
|
160 | + /** |
|
161 | + * get path relative to the root of the view |
|
162 | + * |
|
163 | + * @param string $path |
|
164 | + * @return string |
|
165 | + */ |
|
166 | + public function getRelativePath($path) { |
|
167 | + $this->assertPathLength($path); |
|
168 | + if ($this->fakeRoot == '') { |
|
169 | + return $path; |
|
170 | + } |
|
171 | + |
|
172 | + if (rtrim($path, '/') === rtrim($this->fakeRoot, '/')) { |
|
173 | + return '/'; |
|
174 | + } |
|
175 | + |
|
176 | + // missing slashes can cause wrong matches! |
|
177 | + $root = rtrim($this->fakeRoot, '/') . '/'; |
|
178 | + |
|
179 | + if (strpos($path, $root) !== 0) { |
|
180 | + return null; |
|
181 | + } else { |
|
182 | + $path = substr($path, strlen($this->fakeRoot)); |
|
183 | + if (strlen($path) === 0) { |
|
184 | + return '/'; |
|
185 | + } else { |
|
186 | + return $path; |
|
187 | + } |
|
188 | + } |
|
189 | + } |
|
190 | + |
|
191 | + /** |
|
192 | + * get the mountpoint of the storage object for a path |
|
193 | + * ( note: because a storage is not always mounted inside the fakeroot, the |
|
194 | + * returned mountpoint is relative to the absolute root of the filesystem |
|
195 | + * and does not take the chroot into account ) |
|
196 | + * |
|
197 | + * @param string $path |
|
198 | + * @return string |
|
199 | + */ |
|
200 | + public function getMountPoint($path) { |
|
201 | + return Filesystem::getMountPoint($this->getAbsolutePath($path)); |
|
202 | + } |
|
203 | + |
|
204 | + /** |
|
205 | + * get the mountpoint of the storage object for a path |
|
206 | + * ( note: because a storage is not always mounted inside the fakeroot, the |
|
207 | + * returned mountpoint is relative to the absolute root of the filesystem |
|
208 | + * and does not take the chroot into account ) |
|
209 | + * |
|
210 | + * @param string $path |
|
211 | + * @return \OCP\Files\Mount\IMountPoint |
|
212 | + */ |
|
213 | + public function getMount($path) { |
|
214 | + return Filesystem::getMountManager()->find($this->getAbsolutePath($path)); |
|
215 | + } |
|
216 | + |
|
217 | + /** |
|
218 | + * resolve a path to a storage and internal path |
|
219 | + * |
|
220 | + * @param string $path |
|
221 | + * @return array an array consisting of the storage and the internal path |
|
222 | + */ |
|
223 | + public function resolvePath($path) { |
|
224 | + $a = $this->getAbsolutePath($path); |
|
225 | + $p = Filesystem::normalizePath($a); |
|
226 | + return Filesystem::resolvePath($p); |
|
227 | + } |
|
228 | + |
|
229 | + /** |
|
230 | + * return the path to a local version of the file |
|
231 | + * we need this because we can't know if a file is stored local or not from |
|
232 | + * outside the filestorage and for some purposes a local file is needed |
|
233 | + * |
|
234 | + * @param string $path |
|
235 | + * @return string |
|
236 | + */ |
|
237 | + public function getLocalFile($path) { |
|
238 | + $parent = substr($path, 0, strrpos($path, '/')); |
|
239 | + $path = $this->getAbsolutePath($path); |
|
240 | + list($storage, $internalPath) = Filesystem::resolvePath($path); |
|
241 | + if (Filesystem::isValidPath($parent) and $storage) { |
|
242 | + return $storage->getLocalFile($internalPath); |
|
243 | + } else { |
|
244 | + return null; |
|
245 | + } |
|
246 | + } |
|
247 | + |
|
248 | + /** |
|
249 | + * @param string $path |
|
250 | + * @return string |
|
251 | + */ |
|
252 | + public function getLocalFolder($path) { |
|
253 | + $parent = substr($path, 0, strrpos($path, '/')); |
|
254 | + $path = $this->getAbsolutePath($path); |
|
255 | + list($storage, $internalPath) = Filesystem::resolvePath($path); |
|
256 | + if (Filesystem::isValidPath($parent) and $storage) { |
|
257 | + return $storage->getLocalFolder($internalPath); |
|
258 | + } else { |
|
259 | + return null; |
|
260 | + } |
|
261 | + } |
|
262 | + |
|
263 | + /** |
|
264 | + * the following functions operate with arguments and return values identical |
|
265 | + * to those of their PHP built-in equivalents. Mostly they are merely wrappers |
|
266 | + * for \OC\Files\Storage\Storage via basicOperation(). |
|
267 | + */ |
|
268 | + public function mkdir($path) { |
|
269 | + return $this->basicOperation('mkdir', $path, array('create', 'write')); |
|
270 | + } |
|
271 | + |
|
272 | + /** |
|
273 | + * remove mount point |
|
274 | + * |
|
275 | + * @param \OC\Files\Mount\MoveableMount $mount |
|
276 | + * @param string $path relative to data/ |
|
277 | + * @return boolean |
|
278 | + */ |
|
279 | + protected function removeMount($mount, $path) { |
|
280 | + if ($mount instanceof MoveableMount) { |
|
281 | + // cut of /user/files to get the relative path to data/user/files |
|
282 | + $pathParts = explode('/', $path, 4); |
|
283 | + $relPath = '/' . $pathParts[3]; |
|
284 | + $this->lockFile($relPath, ILockingProvider::LOCK_SHARED, true); |
|
285 | + \OC_Hook::emit( |
|
286 | + Filesystem::CLASSNAME, "umount", |
|
287 | + array(Filesystem::signal_param_path => $relPath) |
|
288 | + ); |
|
289 | + $this->changeLock($relPath, ILockingProvider::LOCK_EXCLUSIVE, true); |
|
290 | + $result = $mount->removeMount(); |
|
291 | + $this->changeLock($relPath, ILockingProvider::LOCK_SHARED, true); |
|
292 | + if ($result) { |
|
293 | + \OC_Hook::emit( |
|
294 | + Filesystem::CLASSNAME, "post_umount", |
|
295 | + array(Filesystem::signal_param_path => $relPath) |
|
296 | + ); |
|
297 | + } |
|
298 | + $this->unlockFile($relPath, ILockingProvider::LOCK_SHARED, true); |
|
299 | + return $result; |
|
300 | + } else { |
|
301 | + // do not allow deleting the storage's root / the mount point |
|
302 | + // because for some storages it might delete the whole contents |
|
303 | + // but isn't supposed to work that way |
|
304 | + return false; |
|
305 | + } |
|
306 | + } |
|
307 | + |
|
308 | + public function disableCacheUpdate() { |
|
309 | + $this->updaterEnabled = false; |
|
310 | + } |
|
311 | + |
|
312 | + public function enableCacheUpdate() { |
|
313 | + $this->updaterEnabled = true; |
|
314 | + } |
|
315 | + |
|
316 | + protected function writeUpdate(Storage $storage, $internalPath, $time = null) { |
|
317 | + if ($this->updaterEnabled) { |
|
318 | + if (is_null($time)) { |
|
319 | + $time = time(); |
|
320 | + } |
|
321 | + $storage->getUpdater()->update($internalPath, $time); |
|
322 | + } |
|
323 | + } |
|
324 | + |
|
325 | + protected function removeUpdate(Storage $storage, $internalPath) { |
|
326 | + if ($this->updaterEnabled) { |
|
327 | + $storage->getUpdater()->remove($internalPath); |
|
328 | + } |
|
329 | + } |
|
330 | + |
|
331 | + protected function renameUpdate(Storage $sourceStorage, Storage $targetStorage, $sourceInternalPath, $targetInternalPath) { |
|
332 | + if ($this->updaterEnabled) { |
|
333 | + $targetStorage->getUpdater()->renameFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); |
|
334 | + } |
|
335 | + } |
|
336 | + |
|
337 | + /** |
|
338 | + * @param string $path |
|
339 | + * @return bool|mixed |
|
340 | + */ |
|
341 | + public function rmdir($path) { |
|
342 | + $absolutePath = $this->getAbsolutePath($path); |
|
343 | + $mount = Filesystem::getMountManager()->find($absolutePath); |
|
344 | + if ($mount->getInternalPath($absolutePath) === '') { |
|
345 | + return $this->removeMount($mount, $absolutePath); |
|
346 | + } |
|
347 | + if ($this->is_dir($path)) { |
|
348 | + $result = $this->basicOperation('rmdir', $path, array('delete')); |
|
349 | + } else { |
|
350 | + $result = false; |
|
351 | + } |
|
352 | + |
|
353 | + if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete |
|
354 | + $storage = $mount->getStorage(); |
|
355 | + $internalPath = $mount->getInternalPath($absolutePath); |
|
356 | + $storage->getUpdater()->remove($internalPath); |
|
357 | + } |
|
358 | + return $result; |
|
359 | + } |
|
360 | + |
|
361 | + /** |
|
362 | + * @param string $path |
|
363 | + * @return resource |
|
364 | + */ |
|
365 | + public function opendir($path) { |
|
366 | + return $this->basicOperation('opendir', $path, array('read')); |
|
367 | + } |
|
368 | + |
|
369 | + /** |
|
370 | + * @param $handle |
|
371 | + * @return mixed |
|
372 | + */ |
|
373 | + public function readdir($handle) { |
|
374 | + $fsLocal = new Storage\Local(array('datadir' => '/')); |
|
375 | + return $fsLocal->readdir($handle); |
|
376 | + } |
|
377 | + |
|
378 | + /** |
|
379 | + * @param string $path |
|
380 | + * @return bool|mixed |
|
381 | + */ |
|
382 | + public function is_dir($path) { |
|
383 | + if ($path == '/') { |
|
384 | + return true; |
|
385 | + } |
|
386 | + return $this->basicOperation('is_dir', $path); |
|
387 | + } |
|
388 | + |
|
389 | + /** |
|
390 | + * @param string $path |
|
391 | + * @return bool|mixed |
|
392 | + */ |
|
393 | + public function is_file($path) { |
|
394 | + if ($path == '/') { |
|
395 | + return false; |
|
396 | + } |
|
397 | + return $this->basicOperation('is_file', $path); |
|
398 | + } |
|
399 | + |
|
400 | + /** |
|
401 | + * @param string $path |
|
402 | + * @return mixed |
|
403 | + */ |
|
404 | + public function stat($path) { |
|
405 | + return $this->basicOperation('stat', $path); |
|
406 | + } |
|
407 | + |
|
408 | + /** |
|
409 | + * @param string $path |
|
410 | + * @return mixed |
|
411 | + */ |
|
412 | + public function filetype($path) { |
|
413 | + return $this->basicOperation('filetype', $path); |
|
414 | + } |
|
415 | + |
|
416 | + /** |
|
417 | + * @param string $path |
|
418 | + * @return mixed |
|
419 | + */ |
|
420 | + public function filesize($path) { |
|
421 | + return $this->basicOperation('filesize', $path); |
|
422 | + } |
|
423 | + |
|
424 | + /** |
|
425 | + * @param string $path |
|
426 | + * @return bool|mixed |
|
427 | + * @throws \OCP\Files\InvalidPathException |
|
428 | + */ |
|
429 | + public function readfile($path) { |
|
430 | + $this->assertPathLength($path); |
|
431 | + @ob_end_clean(); |
|
432 | + $handle = $this->fopen($path, 'rb'); |
|
433 | + if ($handle) { |
|
434 | + $chunkSize = 8192; // 8 kB chunks |
|
435 | + while (!feof($handle)) { |
|
436 | + echo fread($handle, $chunkSize); |
|
437 | + flush(); |
|
438 | + } |
|
439 | + fclose($handle); |
|
440 | + $size = $this->filesize($path); |
|
441 | + return $size; |
|
442 | + } |
|
443 | + return false; |
|
444 | + } |
|
445 | + |
|
446 | + /** |
|
447 | + * @param string $path |
|
448 | + * @param int $from |
|
449 | + * @param int $to |
|
450 | + * @return bool|mixed |
|
451 | + * @throws \OCP\Files\InvalidPathException |
|
452 | + * @throws \OCP\Files\UnseekableException |
|
453 | + */ |
|
454 | + public function readfilePart($path, $from, $to) { |
|
455 | + $this->assertPathLength($path); |
|
456 | + @ob_end_clean(); |
|
457 | + $handle = $this->fopen($path, 'rb'); |
|
458 | + if ($handle) { |
|
459 | + if (fseek($handle, $from) === 0) { |
|
460 | + $chunkSize = 8192; // 8 kB chunks |
|
461 | + $end = $to + 1; |
|
462 | + while (!feof($handle) && ftell($handle) < $end) { |
|
463 | + $len = $end - ftell($handle); |
|
464 | + if ($len > $chunkSize) { |
|
465 | + $len = $chunkSize; |
|
466 | + } |
|
467 | + echo fread($handle, $len); |
|
468 | + flush(); |
|
469 | + } |
|
470 | + $size = ftell($handle) - $from; |
|
471 | + return $size; |
|
472 | + } |
|
473 | + |
|
474 | + throw new \OCP\Files\UnseekableException('fseek error'); |
|
475 | + } |
|
476 | + return false; |
|
477 | + } |
|
478 | + |
|
479 | + /** |
|
480 | + * @param string $path |
|
481 | + * @return mixed |
|
482 | + */ |
|
483 | + public function isCreatable($path) { |
|
484 | + return $this->basicOperation('isCreatable', $path); |
|
485 | + } |
|
486 | + |
|
487 | + /** |
|
488 | + * @param string $path |
|
489 | + * @return mixed |
|
490 | + */ |
|
491 | + public function isReadable($path) { |
|
492 | + return $this->basicOperation('isReadable', $path); |
|
493 | + } |
|
494 | + |
|
495 | + /** |
|
496 | + * @param string $path |
|
497 | + * @return mixed |
|
498 | + */ |
|
499 | + public function isUpdatable($path) { |
|
500 | + return $this->basicOperation('isUpdatable', $path); |
|
501 | + } |
|
502 | + |
|
503 | + /** |
|
504 | + * @param string $path |
|
505 | + * @return bool|mixed |
|
506 | + */ |
|
507 | + public function isDeletable($path) { |
|
508 | + $absolutePath = $this->getAbsolutePath($path); |
|
509 | + $mount = Filesystem::getMountManager()->find($absolutePath); |
|
510 | + if ($mount->getInternalPath($absolutePath) === '') { |
|
511 | + return $mount instanceof MoveableMount; |
|
512 | + } |
|
513 | + return $this->basicOperation('isDeletable', $path); |
|
514 | + } |
|
515 | + |
|
516 | + /** |
|
517 | + * @param string $path |
|
518 | + * @return mixed |
|
519 | + */ |
|
520 | + public function isSharable($path) { |
|
521 | + return $this->basicOperation('isSharable', $path); |
|
522 | + } |
|
523 | + |
|
524 | + /** |
|
525 | + * @param string $path |
|
526 | + * @return bool|mixed |
|
527 | + */ |
|
528 | + public function file_exists($path) { |
|
529 | + if ($path == '/') { |
|
530 | + return true; |
|
531 | + } |
|
532 | + return $this->basicOperation('file_exists', $path); |
|
533 | + } |
|
534 | + |
|
535 | + /** |
|
536 | + * @param string $path |
|
537 | + * @return mixed |
|
538 | + */ |
|
539 | + public function filemtime($path) { |
|
540 | + return $this->basicOperation('filemtime', $path); |
|
541 | + } |
|
542 | + |
|
543 | + /** |
|
544 | + * @param string $path |
|
545 | + * @param int|string $mtime |
|
546 | + * @return bool |
|
547 | + */ |
|
548 | + public function touch($path, $mtime = null) { |
|
549 | + if (!is_null($mtime) and !is_numeric($mtime)) { |
|
550 | + $mtime = strtotime($mtime); |
|
551 | + } |
|
552 | + |
|
553 | + $hooks = array('touch'); |
|
554 | + |
|
555 | + if (!$this->file_exists($path)) { |
|
556 | + $hooks[] = 'create'; |
|
557 | + $hooks[] = 'write'; |
|
558 | + } |
|
559 | + $result = $this->basicOperation('touch', $path, $hooks, $mtime); |
|
560 | + if (!$result) { |
|
561 | + // If create file fails because of permissions on external storage like SMB folders, |
|
562 | + // check file exists and return false if not. |
|
563 | + if (!$this->file_exists($path)) { |
|
564 | + return false; |
|
565 | + } |
|
566 | + if (is_null($mtime)) { |
|
567 | + $mtime = time(); |
|
568 | + } |
|
569 | + //if native touch fails, we emulate it by changing the mtime in the cache |
|
570 | + $this->putFileInfo($path, array('mtime' => floor($mtime))); |
|
571 | + } |
|
572 | + return true; |
|
573 | + } |
|
574 | + |
|
575 | + /** |
|
576 | + * @param string $path |
|
577 | + * @return mixed |
|
578 | + */ |
|
579 | + public function file_get_contents($path) { |
|
580 | + return $this->basicOperation('file_get_contents', $path, array('read')); |
|
581 | + } |
|
582 | + |
|
583 | + /** |
|
584 | + * @param bool $exists |
|
585 | + * @param string $path |
|
586 | + * @param bool $run |
|
587 | + */ |
|
588 | + protected function emit_file_hooks_pre($exists, $path, &$run) { |
|
589 | + if (!$exists) { |
|
590 | + \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_create, array( |
|
591 | + Filesystem::signal_param_path => $this->getHookPath($path), |
|
592 | + Filesystem::signal_param_run => &$run, |
|
593 | + )); |
|
594 | + } else { |
|
595 | + \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_update, array( |
|
596 | + Filesystem::signal_param_path => $this->getHookPath($path), |
|
597 | + Filesystem::signal_param_run => &$run, |
|
598 | + )); |
|
599 | + } |
|
600 | + \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_write, array( |
|
601 | + Filesystem::signal_param_path => $this->getHookPath($path), |
|
602 | + Filesystem::signal_param_run => &$run, |
|
603 | + )); |
|
604 | + } |
|
605 | + |
|
606 | + /** |
|
607 | + * @param bool $exists |
|
608 | + * @param string $path |
|
609 | + */ |
|
610 | + protected function emit_file_hooks_post($exists, $path) { |
|
611 | + if (!$exists) { |
|
612 | + \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_create, array( |
|
613 | + Filesystem::signal_param_path => $this->getHookPath($path), |
|
614 | + )); |
|
615 | + } else { |
|
616 | + \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_update, array( |
|
617 | + Filesystem::signal_param_path => $this->getHookPath($path), |
|
618 | + )); |
|
619 | + } |
|
620 | + \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_write, array( |
|
621 | + Filesystem::signal_param_path => $this->getHookPath($path), |
|
622 | + )); |
|
623 | + } |
|
624 | + |
|
625 | + /** |
|
626 | + * @param string $path |
|
627 | + * @param mixed $data |
|
628 | + * @return bool|mixed |
|
629 | + * @throws \Exception |
|
630 | + */ |
|
631 | + public function file_put_contents($path, $data) { |
|
632 | + if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier |
|
633 | + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
|
634 | + if (Filesystem::isValidPath($path) |
|
635 | + and !Filesystem::isFileBlacklisted($path) |
|
636 | + ) { |
|
637 | + $path = $this->getRelativePath($absolutePath); |
|
638 | + |
|
639 | + $this->lockFile($path, ILockingProvider::LOCK_SHARED); |
|
640 | + |
|
641 | + $exists = $this->file_exists($path); |
|
642 | + $run = true; |
|
643 | + if ($this->shouldEmitHooks($path)) { |
|
644 | + $this->emit_file_hooks_pre($exists, $path, $run); |
|
645 | + } |
|
646 | + if (!$run) { |
|
647 | + $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
648 | + return false; |
|
649 | + } |
|
650 | + |
|
651 | + $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
652 | + |
|
653 | + /** @var \OC\Files\Storage\Storage $storage */ |
|
654 | + list($storage, $internalPath) = $this->resolvePath($path); |
|
655 | + $target = $storage->fopen($internalPath, 'w'); |
|
656 | + if ($target) { |
|
657 | + list (, $result) = \OC_Helper::streamCopy($data, $target); |
|
658 | + fclose($target); |
|
659 | + fclose($data); |
|
660 | + |
|
661 | + $this->writeUpdate($storage, $internalPath); |
|
662 | + |
|
663 | + $this->changeLock($path, ILockingProvider::LOCK_SHARED); |
|
664 | + |
|
665 | + if ($this->shouldEmitHooks($path) && $result !== false) { |
|
666 | + $this->emit_file_hooks_post($exists, $path); |
|
667 | + } |
|
668 | + $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
669 | + return $result; |
|
670 | + } else { |
|
671 | + $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
672 | + return false; |
|
673 | + } |
|
674 | + } else { |
|
675 | + return false; |
|
676 | + } |
|
677 | + } else { |
|
678 | + $hooks = ($this->file_exists($path)) ? array('update', 'write') : array('create', 'write'); |
|
679 | + return $this->basicOperation('file_put_contents', $path, $hooks, $data); |
|
680 | + } |
|
681 | + } |
|
682 | + |
|
683 | + /** |
|
684 | + * @param string $path |
|
685 | + * @return bool|mixed |
|
686 | + */ |
|
687 | + public function unlink($path) { |
|
688 | + if ($path === '' || $path === '/') { |
|
689 | + // do not allow deleting the root |
|
690 | + return false; |
|
691 | + } |
|
692 | + $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; |
|
693 | + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
|
694 | + $mount = Filesystem::getMountManager()->find($absolutePath . $postFix); |
|
695 | + if ($mount and $mount->getInternalPath($absolutePath) === '') { |
|
696 | + return $this->removeMount($mount, $absolutePath); |
|
697 | + } |
|
698 | + if ($this->is_dir($path)) { |
|
699 | + $result = $this->basicOperation('rmdir', $path, ['delete']); |
|
700 | + } else { |
|
701 | + $result = $this->basicOperation('unlink', $path, ['delete']); |
|
702 | + } |
|
703 | + if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete |
|
704 | + $storage = $mount->getStorage(); |
|
705 | + $internalPath = $mount->getInternalPath($absolutePath); |
|
706 | + $storage->getUpdater()->remove($internalPath); |
|
707 | + return true; |
|
708 | + } else { |
|
709 | + return $result; |
|
710 | + } |
|
711 | + } |
|
712 | + |
|
713 | + /** |
|
714 | + * @param string $directory |
|
715 | + * @return bool|mixed |
|
716 | + */ |
|
717 | + public function deleteAll($directory) { |
|
718 | + return $this->rmdir($directory); |
|
719 | + } |
|
720 | + |
|
721 | + /** |
|
722 | + * Rename/move a file or folder from the source path to target path. |
|
723 | + * |
|
724 | + * @param string $path1 source path |
|
725 | + * @param string $path2 target path |
|
726 | + * |
|
727 | + * @return bool|mixed |
|
728 | + */ |
|
729 | + public function rename($path1, $path2) { |
|
730 | + $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); |
|
731 | + $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); |
|
732 | + $result = false; |
|
733 | + if ( |
|
734 | + Filesystem::isValidPath($path2) |
|
735 | + and Filesystem::isValidPath($path1) |
|
736 | + and !Filesystem::isFileBlacklisted($path2) |
|
737 | + ) { |
|
738 | + $path1 = $this->getRelativePath($absolutePath1); |
|
739 | + $path2 = $this->getRelativePath($absolutePath2); |
|
740 | + $exists = $this->file_exists($path2); |
|
741 | + |
|
742 | + if ($path1 == null or $path2 == null) { |
|
743 | + return false; |
|
744 | + } |
|
745 | + |
|
746 | + $this->lockFile($path1, ILockingProvider::LOCK_SHARED, true); |
|
747 | + try { |
|
748 | + $this->lockFile($path2, ILockingProvider::LOCK_SHARED, true); |
|
749 | + } catch (LockedException $e) { |
|
750 | + $this->unlockFile($path1, ILockingProvider::LOCK_SHARED); |
|
751 | + throw $e; |
|
752 | + } |
|
753 | + |
|
754 | + $run = true; |
|
755 | + if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) { |
|
756 | + // if it was a rename from a part file to a regular file it was a write and not a rename operation |
|
757 | + $this->emit_file_hooks_pre($exists, $path2, $run); |
|
758 | + } elseif ($this->shouldEmitHooks($path1)) { |
|
759 | + \OC_Hook::emit( |
|
760 | + Filesystem::CLASSNAME, Filesystem::signal_rename, |
|
761 | + array( |
|
762 | + Filesystem::signal_param_oldpath => $this->getHookPath($path1), |
|
763 | + Filesystem::signal_param_newpath => $this->getHookPath($path2), |
|
764 | + Filesystem::signal_param_run => &$run |
|
765 | + ) |
|
766 | + ); |
|
767 | + } |
|
768 | + if ($run) { |
|
769 | + $this->verifyPath(dirname($path2), basename($path2)); |
|
770 | + |
|
771 | + $manager = Filesystem::getMountManager(); |
|
772 | + $mount1 = $this->getMount($path1); |
|
773 | + $mount2 = $this->getMount($path2); |
|
774 | + $storage1 = $mount1->getStorage(); |
|
775 | + $storage2 = $mount2->getStorage(); |
|
776 | + $internalPath1 = $mount1->getInternalPath($absolutePath1); |
|
777 | + $internalPath2 = $mount2->getInternalPath($absolutePath2); |
|
778 | + |
|
779 | + $this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE, true); |
|
780 | + $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE, true); |
|
781 | + |
|
782 | + if ($internalPath1 === '' and $mount1 instanceof MoveableMount) { |
|
783 | + if ($this->isTargetAllowed($absolutePath2)) { |
|
784 | + /** |
|
785 | + * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1 |
|
786 | + */ |
|
787 | + $sourceMountPoint = $mount1->getMountPoint(); |
|
788 | + $result = $mount1->moveMount($absolutePath2); |
|
789 | + $manager->moveMount($sourceMountPoint, $mount1->getMountPoint()); |
|
790 | + } else { |
|
791 | + $result = false; |
|
792 | + } |
|
793 | + // moving a file/folder within the same mount point |
|
794 | + } elseif ($storage1 === $storage2) { |
|
795 | + if ($storage1) { |
|
796 | + $result = $storage1->rename($internalPath1, $internalPath2); |
|
797 | + } else { |
|
798 | + $result = false; |
|
799 | + } |
|
800 | + // moving a file/folder between storages (from $storage1 to $storage2) |
|
801 | + } else { |
|
802 | + $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); |
|
803 | + } |
|
804 | + |
|
805 | + if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) { |
|
806 | + // if it was a rename from a part file to a regular file it was a write and not a rename operation |
|
807 | + |
|
808 | + $this->writeUpdate($storage2, $internalPath2); |
|
809 | + } else if ($result) { |
|
810 | + if ($internalPath1 !== '') { // don't do a cache update for moved mounts |
|
811 | + $this->renameUpdate($storage1, $storage2, $internalPath1, $internalPath2); |
|
812 | + } |
|
813 | + } |
|
814 | + |
|
815 | + $this->changeLock($path1, ILockingProvider::LOCK_SHARED, true); |
|
816 | + $this->changeLock($path2, ILockingProvider::LOCK_SHARED, true); |
|
817 | + |
|
818 | + if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) { |
|
819 | + if ($this->shouldEmitHooks()) { |
|
820 | + $this->emit_file_hooks_post($exists, $path2); |
|
821 | + } |
|
822 | + } elseif ($result) { |
|
823 | + if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) { |
|
824 | + \OC_Hook::emit( |
|
825 | + Filesystem::CLASSNAME, |
|
826 | + Filesystem::signal_post_rename, |
|
827 | + array( |
|
828 | + Filesystem::signal_param_oldpath => $this->getHookPath($path1), |
|
829 | + Filesystem::signal_param_newpath => $this->getHookPath($path2) |
|
830 | + ) |
|
831 | + ); |
|
832 | + } |
|
833 | + } |
|
834 | + } |
|
835 | + $this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true); |
|
836 | + $this->unlockFile($path2, ILockingProvider::LOCK_SHARED, true); |
|
837 | + } |
|
838 | + return $result; |
|
839 | + } |
|
840 | + |
|
841 | + /** |
|
842 | + * Copy a file/folder from the source path to target path |
|
843 | + * |
|
844 | + * @param string $path1 source path |
|
845 | + * @param string $path2 target path |
|
846 | + * @param bool $preserveMtime whether to preserve mtime on the copy |
|
847 | + * |
|
848 | + * @return bool|mixed |
|
849 | + */ |
|
850 | + public function copy($path1, $path2, $preserveMtime = false) { |
|
851 | + $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); |
|
852 | + $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); |
|
853 | + $result = false; |
|
854 | + if ( |
|
855 | + Filesystem::isValidPath($path2) |
|
856 | + and Filesystem::isValidPath($path1) |
|
857 | + and !Filesystem::isFileBlacklisted($path2) |
|
858 | + ) { |
|
859 | + $path1 = $this->getRelativePath($absolutePath1); |
|
860 | + $path2 = $this->getRelativePath($absolutePath2); |
|
861 | + |
|
862 | + if ($path1 == null or $path2 == null) { |
|
863 | + return false; |
|
864 | + } |
|
865 | + $run = true; |
|
866 | + |
|
867 | + $this->lockFile($path2, ILockingProvider::LOCK_SHARED); |
|
868 | + $this->lockFile($path1, ILockingProvider::LOCK_SHARED); |
|
869 | + $lockTypePath1 = ILockingProvider::LOCK_SHARED; |
|
870 | + $lockTypePath2 = ILockingProvider::LOCK_SHARED; |
|
871 | + |
|
872 | + try { |
|
873 | + |
|
874 | + $exists = $this->file_exists($path2); |
|
875 | + if ($this->shouldEmitHooks()) { |
|
876 | + \OC_Hook::emit( |
|
877 | + Filesystem::CLASSNAME, |
|
878 | + Filesystem::signal_copy, |
|
879 | + array( |
|
880 | + Filesystem::signal_param_oldpath => $this->getHookPath($path1), |
|
881 | + Filesystem::signal_param_newpath => $this->getHookPath($path2), |
|
882 | + Filesystem::signal_param_run => &$run |
|
883 | + ) |
|
884 | + ); |
|
885 | + $this->emit_file_hooks_pre($exists, $path2, $run); |
|
886 | + } |
|
887 | + if ($run) { |
|
888 | + $mount1 = $this->getMount($path1); |
|
889 | + $mount2 = $this->getMount($path2); |
|
890 | + $storage1 = $mount1->getStorage(); |
|
891 | + $internalPath1 = $mount1->getInternalPath($absolutePath1); |
|
892 | + $storage2 = $mount2->getStorage(); |
|
893 | + $internalPath2 = $mount2->getInternalPath($absolutePath2); |
|
894 | + |
|
895 | + $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE); |
|
896 | + $lockTypePath2 = ILockingProvider::LOCK_EXCLUSIVE; |
|
897 | + |
|
898 | + if ($mount1->getMountPoint() == $mount2->getMountPoint()) { |
|
899 | + if ($storage1) { |
|
900 | + $result = $storage1->copy($internalPath1, $internalPath2); |
|
901 | + } else { |
|
902 | + $result = false; |
|
903 | + } |
|
904 | + } else { |
|
905 | + $result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2); |
|
906 | + } |
|
907 | + |
|
908 | + $this->writeUpdate($storage2, $internalPath2); |
|
909 | + |
|
910 | + $this->changeLock($path2, ILockingProvider::LOCK_SHARED); |
|
911 | + $lockTypePath2 = ILockingProvider::LOCK_SHARED; |
|
912 | + |
|
913 | + if ($this->shouldEmitHooks() && $result !== false) { |
|
914 | + \OC_Hook::emit( |
|
915 | + Filesystem::CLASSNAME, |
|
916 | + Filesystem::signal_post_copy, |
|
917 | + array( |
|
918 | + Filesystem::signal_param_oldpath => $this->getHookPath($path1), |
|
919 | + Filesystem::signal_param_newpath => $this->getHookPath($path2) |
|
920 | + ) |
|
921 | + ); |
|
922 | + $this->emit_file_hooks_post($exists, $path2); |
|
923 | + } |
|
924 | + |
|
925 | + } |
|
926 | + } catch (\Exception $e) { |
|
927 | + $this->unlockFile($path2, $lockTypePath2); |
|
928 | + $this->unlockFile($path1, $lockTypePath1); |
|
929 | + throw $e; |
|
930 | + } |
|
931 | + |
|
932 | + $this->unlockFile($path2, $lockTypePath2); |
|
933 | + $this->unlockFile($path1, $lockTypePath1); |
|
934 | + |
|
935 | + } |
|
936 | + return $result; |
|
937 | + } |
|
938 | + |
|
939 | + /** |
|
940 | + * @param string $path |
|
941 | + * @param string $mode 'r' or 'w' |
|
942 | + * @return resource |
|
943 | + */ |
|
944 | + public function fopen($path, $mode) { |
|
945 | + $mode = str_replace('b', '', $mode); // the binary flag is a windows only feature which we do not support |
|
946 | + $hooks = array(); |
|
947 | + switch ($mode) { |
|
948 | + case 'r': |
|
949 | + $hooks[] = 'read'; |
|
950 | + break; |
|
951 | + case 'r+': |
|
952 | + case 'w+': |
|
953 | + case 'x+': |
|
954 | + case 'a+': |
|
955 | + $hooks[] = 'read'; |
|
956 | + $hooks[] = 'write'; |
|
957 | + break; |
|
958 | + case 'w': |
|
959 | + case 'x': |
|
960 | + case 'a': |
|
961 | + $hooks[] = 'write'; |
|
962 | + break; |
|
963 | + default: |
|
964 | + \OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR); |
|
965 | + } |
|
966 | + |
|
967 | + if ($mode !== 'r' && $mode !== 'w') { |
|
968 | + \OC::$server->getLogger()->info('Trying to open a file with a mode other than "r" or "w" can cause severe performance issues with some backends'); |
|
969 | + } |
|
970 | + |
|
971 | + return $this->basicOperation('fopen', $path, $hooks, $mode); |
|
972 | + } |
|
973 | + |
|
974 | + /** |
|
975 | + * @param string $path |
|
976 | + * @return bool|string |
|
977 | + * @throws \OCP\Files\InvalidPathException |
|
978 | + */ |
|
979 | + public function toTmpFile($path) { |
|
980 | + $this->assertPathLength($path); |
|
981 | + if (Filesystem::isValidPath($path)) { |
|
982 | + $source = $this->fopen($path, 'r'); |
|
983 | + if ($source) { |
|
984 | + $extension = pathinfo($path, PATHINFO_EXTENSION); |
|
985 | + $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension); |
|
986 | + file_put_contents($tmpFile, $source); |
|
987 | + return $tmpFile; |
|
988 | + } else { |
|
989 | + return false; |
|
990 | + } |
|
991 | + } else { |
|
992 | + return false; |
|
993 | + } |
|
994 | + } |
|
995 | + |
|
996 | + /** |
|
997 | + * @param string $tmpFile |
|
998 | + * @param string $path |
|
999 | + * @return bool|mixed |
|
1000 | + * @throws \OCP\Files\InvalidPathException |
|
1001 | + */ |
|
1002 | + public function fromTmpFile($tmpFile, $path) { |
|
1003 | + $this->assertPathLength($path); |
|
1004 | + if (Filesystem::isValidPath($path)) { |
|
1005 | + |
|
1006 | + // Get directory that the file is going into |
|
1007 | + $filePath = dirname($path); |
|
1008 | + |
|
1009 | + // Create the directories if any |
|
1010 | + if (!$this->file_exists($filePath)) { |
|
1011 | + $result = $this->createParentDirectories($filePath); |
|
1012 | + if ($result === false) { |
|
1013 | + return false; |
|
1014 | + } |
|
1015 | + } |
|
1016 | + |
|
1017 | + $source = fopen($tmpFile, 'r'); |
|
1018 | + if ($source) { |
|
1019 | + $result = $this->file_put_contents($path, $source); |
|
1020 | + // $this->file_put_contents() might have already closed |
|
1021 | + // the resource, so we check it, before trying to close it |
|
1022 | + // to avoid messages in the error log. |
|
1023 | + if (is_resource($source)) { |
|
1024 | + fclose($source); |
|
1025 | + } |
|
1026 | + unlink($tmpFile); |
|
1027 | + return $result; |
|
1028 | + } else { |
|
1029 | + return false; |
|
1030 | + } |
|
1031 | + } else { |
|
1032 | + return false; |
|
1033 | + } |
|
1034 | + } |
|
1035 | + |
|
1036 | + |
|
1037 | + /** |
|
1038 | + * @param string $path |
|
1039 | + * @return mixed |
|
1040 | + * @throws \OCP\Files\InvalidPathException |
|
1041 | + */ |
|
1042 | + public function getMimeType($path) { |
|
1043 | + $this->assertPathLength($path); |
|
1044 | + return $this->basicOperation('getMimeType', $path); |
|
1045 | + } |
|
1046 | + |
|
1047 | + /** |
|
1048 | + * @param string $type |
|
1049 | + * @param string $path |
|
1050 | + * @param bool $raw |
|
1051 | + * @return bool|null|string |
|
1052 | + */ |
|
1053 | + public function hash($type, $path, $raw = false) { |
|
1054 | + $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; |
|
1055 | + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
|
1056 | + if (Filesystem::isValidPath($path)) { |
|
1057 | + $path = $this->getRelativePath($absolutePath); |
|
1058 | + if ($path == null) { |
|
1059 | + return false; |
|
1060 | + } |
|
1061 | + if ($this->shouldEmitHooks($path)) { |
|
1062 | + \OC_Hook::emit( |
|
1063 | + Filesystem::CLASSNAME, |
|
1064 | + Filesystem::signal_read, |
|
1065 | + array(Filesystem::signal_param_path => $this->getHookPath($path)) |
|
1066 | + ); |
|
1067 | + } |
|
1068 | + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); |
|
1069 | + if ($storage) { |
|
1070 | + $result = $storage->hash($type, $internalPath, $raw); |
|
1071 | + return $result; |
|
1072 | + } |
|
1073 | + } |
|
1074 | + return null; |
|
1075 | + } |
|
1076 | + |
|
1077 | + /** |
|
1078 | + * @param string $path |
|
1079 | + * @return mixed |
|
1080 | + * @throws \OCP\Files\InvalidPathException |
|
1081 | + */ |
|
1082 | + public function free_space($path = '/') { |
|
1083 | + $this->assertPathLength($path); |
|
1084 | + $result = $this->basicOperation('free_space', $path); |
|
1085 | + if ($result === null) { |
|
1086 | + throw new InvalidPathException(); |
|
1087 | + } |
|
1088 | + return $result; |
|
1089 | + } |
|
1090 | + |
|
1091 | + /** |
|
1092 | + * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage |
|
1093 | + * |
|
1094 | + * @param string $operation |
|
1095 | + * @param string $path |
|
1096 | + * @param array $hooks (optional) |
|
1097 | + * @param mixed $extraParam (optional) |
|
1098 | + * @return mixed |
|
1099 | + * @throws \Exception |
|
1100 | + * |
|
1101 | + * This method takes requests for basic filesystem functions (e.g. reading & writing |
|
1102 | + * files), processes hooks and proxies, sanitises paths, and finally passes them on to |
|
1103 | + * \OC\Files\Storage\Storage for delegation to a storage backend for execution |
|
1104 | + */ |
|
1105 | + private function basicOperation($operation, $path, $hooks = [], $extraParam = null) { |
|
1106 | + $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; |
|
1107 | + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); |
|
1108 | + if (Filesystem::isValidPath($path) |
|
1109 | + and !Filesystem::isFileBlacklisted($path) |
|
1110 | + ) { |
|
1111 | + $path = $this->getRelativePath($absolutePath); |
|
1112 | + if ($path == null) { |
|
1113 | + return false; |
|
1114 | + } |
|
1115 | + |
|
1116 | + if (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) { |
|
1117 | + // always a shared lock during pre-hooks so the hook can read the file |
|
1118 | + $this->lockFile($path, ILockingProvider::LOCK_SHARED); |
|
1119 | + } |
|
1120 | + |
|
1121 | + $run = $this->runHooks($hooks, $path); |
|
1122 | + /** @var \OC\Files\Storage\Storage $storage */ |
|
1123 | + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); |
|
1124 | + if ($run and $storage) { |
|
1125 | + if (in_array('write', $hooks) || in_array('delete', $hooks)) { |
|
1126 | + $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
1127 | + } |
|
1128 | + try { |
|
1129 | + if (!is_null($extraParam)) { |
|
1130 | + $result = $storage->$operation($internalPath, $extraParam); |
|
1131 | + } else { |
|
1132 | + $result = $storage->$operation($internalPath); |
|
1133 | + } |
|
1134 | + } catch (\Exception $e) { |
|
1135 | + if (in_array('write', $hooks) || in_array('delete', $hooks)) { |
|
1136 | + $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
1137 | + } else if (in_array('read', $hooks)) { |
|
1138 | + $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
1139 | + } |
|
1140 | + throw $e; |
|
1141 | + } |
|
1142 | + |
|
1143 | + if ($result && in_array('delete', $hooks) and $result) { |
|
1144 | + $this->removeUpdate($storage, $internalPath); |
|
1145 | + } |
|
1146 | + if ($result && in_array('write', $hooks) and $operation !== 'fopen') { |
|
1147 | + $this->writeUpdate($storage, $internalPath); |
|
1148 | + } |
|
1149 | + if ($result && in_array('touch', $hooks)) { |
|
1150 | + $this->writeUpdate($storage, $internalPath, $extraParam); |
|
1151 | + } |
|
1152 | + |
|
1153 | + if ((in_array('write', $hooks) || in_array('delete', $hooks)) && ($operation !== 'fopen' || $result === false)) { |
|
1154 | + $this->changeLock($path, ILockingProvider::LOCK_SHARED); |
|
1155 | + } |
|
1156 | + |
|
1157 | + $unlockLater = false; |
|
1158 | + if ($this->lockingEnabled && $operation === 'fopen' && is_resource($result)) { |
|
1159 | + $unlockLater = true; |
|
1160 | + // make sure our unlocking callback will still be called if connection is aborted |
|
1161 | + ignore_user_abort(true); |
|
1162 | + $result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) { |
|
1163 | + if (in_array('write', $hooks)) { |
|
1164 | + $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE); |
|
1165 | + } else if (in_array('read', $hooks)) { |
|
1166 | + $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
1167 | + } |
|
1168 | + }); |
|
1169 | + } |
|
1170 | + |
|
1171 | + if ($this->shouldEmitHooks($path) && $result !== false) { |
|
1172 | + if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open |
|
1173 | + $this->runHooks($hooks, $path, true); |
|
1174 | + } |
|
1175 | + } |
|
1176 | + |
|
1177 | + if (!$unlockLater |
|
1178 | + && (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) |
|
1179 | + ) { |
|
1180 | + $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
1181 | + } |
|
1182 | + return $result; |
|
1183 | + } else { |
|
1184 | + $this->unlockFile($path, ILockingProvider::LOCK_SHARED); |
|
1185 | + } |
|
1186 | + } |
|
1187 | + return null; |
|
1188 | + } |
|
1189 | + |
|
1190 | + /** |
|
1191 | + * get the path relative to the default root for hook usage |
|
1192 | + * |
|
1193 | + * @param string $path |
|
1194 | + * @return string |
|
1195 | + */ |
|
1196 | + private function getHookPath($path) { |
|
1197 | + if (!Filesystem::getView()) { |
|
1198 | + return $path; |
|
1199 | + } |
|
1200 | + return Filesystem::getView()->getRelativePath($this->getAbsolutePath($path)); |
|
1201 | + } |
|
1202 | + |
|
1203 | + private function shouldEmitHooks($path = '') { |
|
1204 | + if ($path && Cache\Scanner::isPartialFile($path)) { |
|
1205 | + return false; |
|
1206 | + } |
|
1207 | + if (!Filesystem::$loaded) { |
|
1208 | + return false; |
|
1209 | + } |
|
1210 | + $defaultRoot = Filesystem::getRoot(); |
|
1211 | + if ($defaultRoot === null) { |
|
1212 | + return false; |
|
1213 | + } |
|
1214 | + if ($this->fakeRoot === $defaultRoot) { |
|
1215 | + return true; |
|
1216 | + } |
|
1217 | + $fullPath = $this->getAbsolutePath($path); |
|
1218 | + |
|
1219 | + if ($fullPath === $defaultRoot) { |
|
1220 | + return true; |
|
1221 | + } |
|
1222 | + |
|
1223 | + return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/'); |
|
1224 | + } |
|
1225 | + |
|
1226 | + /** |
|
1227 | + * @param string[] $hooks |
|
1228 | + * @param string $path |
|
1229 | + * @param bool $post |
|
1230 | + * @return bool |
|
1231 | + */ |
|
1232 | + private function runHooks($hooks, $path, $post = false) { |
|
1233 | + $relativePath = $path; |
|
1234 | + $path = $this->getHookPath($path); |
|
1235 | + $prefix = ($post) ? 'post_' : ''; |
|
1236 | + $run = true; |
|
1237 | + if ($this->shouldEmitHooks($relativePath)) { |
|
1238 | + foreach ($hooks as $hook) { |
|
1239 | + if ($hook != 'read') { |
|
1240 | + \OC_Hook::emit( |
|
1241 | + Filesystem::CLASSNAME, |
|
1242 | + $prefix . $hook, |
|
1243 | + array( |
|
1244 | + Filesystem::signal_param_run => &$run, |
|
1245 | + Filesystem::signal_param_path => $path |
|
1246 | + ) |
|
1247 | + ); |
|
1248 | + } elseif (!$post) { |
|
1249 | + \OC_Hook::emit( |
|
1250 | + Filesystem::CLASSNAME, |
|
1251 | + $prefix . $hook, |
|
1252 | + array( |
|
1253 | + Filesystem::signal_param_path => $path |
|
1254 | + ) |
|
1255 | + ); |
|
1256 | + } |
|
1257 | + } |
|
1258 | + } |
|
1259 | + return $run; |
|
1260 | + } |
|
1261 | + |
|
1262 | + /** |
|
1263 | + * check if a file or folder has been updated since $time |
|
1264 | + * |
|
1265 | + * @param string $path |
|
1266 | + * @param int $time |
|
1267 | + * @return bool |
|
1268 | + */ |
|
1269 | + public function hasUpdated($path, $time) { |
|
1270 | + return $this->basicOperation('hasUpdated', $path, array(), $time); |
|
1271 | + } |
|
1272 | + |
|
1273 | + /** |
|
1274 | + * @param string $ownerId |
|
1275 | + * @return \OC\User\User |
|
1276 | + */ |
|
1277 | + private function getUserObjectForOwner($ownerId) { |
|
1278 | + $owner = $this->userManager->get($ownerId); |
|
1279 | + if ($owner instanceof IUser) { |
|
1280 | + return $owner; |
|
1281 | + } else { |
|
1282 | + return new User($ownerId, null); |
|
1283 | + } |
|
1284 | + } |
|
1285 | + |
|
1286 | + /** |
|
1287 | + * Get file info from cache |
|
1288 | + * |
|
1289 | + * If the file is not in cached it will be scanned |
|
1290 | + * If the file has changed on storage the cache will be updated |
|
1291 | + * |
|
1292 | + * @param \OC\Files\Storage\Storage $storage |
|
1293 | + * @param string $internalPath |
|
1294 | + * @param string $relativePath |
|
1295 | + * @return array|bool |
|
1296 | + */ |
|
1297 | + private function getCacheEntry($storage, $internalPath, $relativePath) { |
|
1298 | + $cache = $storage->getCache($internalPath); |
|
1299 | + $data = $cache->get($internalPath); |
|
1300 | + $watcher = $storage->getWatcher($internalPath); |
|
1301 | + |
|
1302 | + try { |
|
1303 | + // if the file is not in the cache or needs to be updated, trigger the scanner and reload the data |
|
1304 | + if (!$data || $data['size'] === -1) { |
|
1305 | + $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1306 | + if (!$storage->file_exists($internalPath)) { |
|
1307 | + $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1308 | + return false; |
|
1309 | + } |
|
1310 | + $scanner = $storage->getScanner($internalPath); |
|
1311 | + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); |
|
1312 | + $data = $cache->get($internalPath); |
|
1313 | + $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1314 | + } else if (!Cache\Scanner::isPartialFile($internalPath) && $watcher->needsUpdate($internalPath, $data)) { |
|
1315 | + $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1316 | + $watcher->update($internalPath, $data); |
|
1317 | + $storage->getPropagator()->propagateChange($internalPath, time()); |
|
1318 | + $data = $cache->get($internalPath); |
|
1319 | + $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED); |
|
1320 | + } |
|
1321 | + } catch (LockedException $e) { |
|
1322 | + // if the file is locked we just use the old cache info |
|
1323 | + } |
|
1324 | + |
|
1325 | + return $data; |
|
1326 | + } |
|
1327 | + |
|
1328 | + /** |
|
1329 | + * get the filesystem info |
|
1330 | + * |
|
1331 | + * @param string $path |
|
1332 | + * @param boolean|string $includeMountPoints true to add mountpoint sizes, |
|
1333 | + * 'ext' to add only ext storage mount point sizes. Defaults to true. |
|
1334 | + * defaults to true |
|
1335 | + * @return \OC\Files\FileInfo|false False if file does not exist |
|
1336 | + */ |
|
1337 | + public function getFileInfo($path, $includeMountPoints = true) { |
|
1338 | + $this->assertPathLength($path); |
|
1339 | + if (!Filesystem::isValidPath($path)) { |
|
1340 | + return false; |
|
1341 | + } |
|
1342 | + if (Cache\Scanner::isPartialFile($path)) { |
|
1343 | + return $this->getPartFileInfo($path); |
|
1344 | + } |
|
1345 | + $relativePath = $path; |
|
1346 | + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); |
|
1347 | + |
|
1348 | + $mount = Filesystem::getMountManager()->find($path); |
|
1349 | + $storage = $mount->getStorage(); |
|
1350 | + $internalPath = $mount->getInternalPath($path); |
|
1351 | + if ($storage) { |
|
1352 | + $data = $this->getCacheEntry($storage, $internalPath, $relativePath); |
|
1353 | + |
|
1354 | + if (!$data instanceof ICacheEntry) { |
|
1355 | + return false; |
|
1356 | + } |
|
1357 | + |
|
1358 | + if ($mount instanceof MoveableMount && $internalPath === '') { |
|
1359 | + $data['permissions'] |= \OCP\Constants::PERMISSION_DELETE; |
|
1360 | + } |
|
1361 | + |
|
1362 | + $owner = $this->getUserObjectForOwner($storage->getOwner($internalPath)); |
|
1363 | + $info = new FileInfo($path, $storage, $internalPath, $data, $mount, $owner); |
|
1364 | + |
|
1365 | + if ($data and isset($data['fileid'])) { |
|
1366 | + if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { |
|
1367 | + //add the sizes of other mount points to the folder |
|
1368 | + $extOnly = ($includeMountPoints === 'ext'); |
|
1369 | + $mounts = Filesystem::getMountManager()->findIn($path); |
|
1370 | + $info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) { |
|
1371 | + $subStorage = $mount->getStorage(); |
|
1372 | + return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage); |
|
1373 | + })); |
|
1374 | + } |
|
1375 | + } |
|
1376 | + |
|
1377 | + return $info; |
|
1378 | + } |
|
1379 | + |
|
1380 | + return false; |
|
1381 | + } |
|
1382 | + |
|
1383 | + /** |
|
1384 | + * get the content of a directory |
|
1385 | + * |
|
1386 | + * @param string $directory path under datadirectory |
|
1387 | + * @param string $mimetype_filter limit returned content to this mimetype or mimepart |
|
1388 | + * @return FileInfo[] |
|
1389 | + */ |
|
1390 | + public function getDirectoryContent($directory, $mimetype_filter = '') { |
|
1391 | + $this->assertPathLength($directory); |
|
1392 | + if (!Filesystem::isValidPath($directory)) { |
|
1393 | + return []; |
|
1394 | + } |
|
1395 | + $path = $this->getAbsolutePath($directory); |
|
1396 | + $path = Filesystem::normalizePath($path); |
|
1397 | + $mount = $this->getMount($directory); |
|
1398 | + $storage = $mount->getStorage(); |
|
1399 | + $internalPath = $mount->getInternalPath($path); |
|
1400 | + if ($storage) { |
|
1401 | + $cache = $storage->getCache($internalPath); |
|
1402 | + $user = \OC_User::getUser(); |
|
1403 | + |
|
1404 | + $data = $this->getCacheEntry($storage, $internalPath, $directory); |
|
1405 | + |
|
1406 | + if (!$data instanceof ICacheEntry || !isset($data['fileid']) || !($data->getPermissions() && Constants::PERMISSION_READ)) { |
|
1407 | + return []; |
|
1408 | + } |
|
1409 | + |
|
1410 | + $folderId = $data['fileid']; |
|
1411 | + $contents = $cache->getFolderContentsById($folderId); //TODO: mimetype_filter |
|
1412 | + |
|
1413 | + $sharingDisabled = \OCP\Util::isSharingDisabledForUser(); |
|
1414 | + /** |
|
1415 | + * @var \OC\Files\FileInfo[] $files |
|
1416 | + */ |
|
1417 | + $files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) { |
|
1418 | + if ($sharingDisabled) { |
|
1419 | + $content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE; |
|
1420 | + } |
|
1421 | + $owner = $this->getUserObjectForOwner($storage->getOwner($content['path'])); |
|
1422 | + return new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount, $owner); |
|
1423 | + }, $contents); |
|
1424 | + |
|
1425 | + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders |
|
1426 | + $mounts = Filesystem::getMountManager()->findIn($path); |
|
1427 | + $dirLength = strlen($path); |
|
1428 | + foreach ($mounts as $mount) { |
|
1429 | + $mountPoint = $mount->getMountPoint(); |
|
1430 | + $subStorage = $mount->getStorage(); |
|
1431 | + if ($subStorage) { |
|
1432 | + $subCache = $subStorage->getCache(''); |
|
1433 | + |
|
1434 | + $rootEntry = $subCache->get(''); |
|
1435 | + if (!$rootEntry) { |
|
1436 | + $subScanner = $subStorage->getScanner(''); |
|
1437 | + try { |
|
1438 | + $subScanner->scanFile(''); |
|
1439 | + } catch (\OCP\Files\StorageNotAvailableException $e) { |
|
1440 | + continue; |
|
1441 | + } catch (\OCP\Files\StorageInvalidException $e) { |
|
1442 | + continue; |
|
1443 | + } catch (\Exception $e) { |
|
1444 | + // sometimes when the storage is not available it can be any exception |
|
1445 | + \OCP\Util::writeLog( |
|
1446 | + 'core', |
|
1447 | + 'Exception while scanning storage "' . $subStorage->getId() . '": ' . |
|
1448 | + get_class($e) . ': ' . $e->getMessage(), |
|
1449 | + \OCP\Util::ERROR |
|
1450 | + ); |
|
1451 | + continue; |
|
1452 | + } |
|
1453 | + $rootEntry = $subCache->get(''); |
|
1454 | + } |
|
1455 | + |
|
1456 | + if ($rootEntry && ($rootEntry->getPermissions() && Constants::PERMISSION_READ)) { |
|
1457 | + $relativePath = trim(substr($mountPoint, $dirLength), '/'); |
|
1458 | + if ($pos = strpos($relativePath, '/')) { |
|
1459 | + //mountpoint inside subfolder add size to the correct folder |
|
1460 | + $entryName = substr($relativePath, 0, $pos); |
|
1461 | + foreach ($files as &$entry) { |
|
1462 | + if ($entry->getName() === $entryName) { |
|
1463 | + $entry->addSubEntry($rootEntry, $mountPoint); |
|
1464 | + } |
|
1465 | + } |
|
1466 | + } else { //mountpoint in this folder, add an entry for it |
|
1467 | + $rootEntry['name'] = $relativePath; |
|
1468 | + $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; |
|
1469 | + $permissions = $rootEntry['permissions']; |
|
1470 | + // do not allow renaming/deleting the mount point if they are not shared files/folders |
|
1471 | + // for shared files/folders we use the permissions given by the owner |
|
1472 | + if ($mount instanceof MoveableMount) { |
|
1473 | + $rootEntry['permissions'] = $permissions | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE; |
|
1474 | + } else { |
|
1475 | + $rootEntry['permissions'] = $permissions & (\OCP\Constants::PERMISSION_ALL - (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)); |
|
1476 | + } |
|
1477 | + |
|
1478 | + //remove any existing entry with the same name |
|
1479 | + foreach ($files as $i => $file) { |
|
1480 | + if ($file['name'] === $rootEntry['name']) { |
|
1481 | + unset($files[$i]); |
|
1482 | + break; |
|
1483 | + } |
|
1484 | + } |
|
1485 | + $rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/ |
|
1486 | + |
|
1487 | + // if sharing was disabled for the user we remove the share permissions |
|
1488 | + if (\OCP\Util::isSharingDisabledForUser()) { |
|
1489 | + $rootEntry['permissions'] = $rootEntry['permissions'] & ~\OCP\Constants::PERMISSION_SHARE; |
|
1490 | + } |
|
1491 | + |
|
1492 | + $owner = $this->getUserObjectForOwner($subStorage->getOwner('')); |
|
1493 | + $files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner); |
|
1494 | + } |
|
1495 | + } |
|
1496 | + } |
|
1497 | + } |
|
1498 | + |
|
1499 | + if ($mimetype_filter) { |
|
1500 | + $files = array_filter($files, function (FileInfo $file) use ($mimetype_filter) { |
|
1501 | + if (strpos($mimetype_filter, '/')) { |
|
1502 | + return $file->getMimetype() === $mimetype_filter; |
|
1503 | + } else { |
|
1504 | + return $file->getMimePart() === $mimetype_filter; |
|
1505 | + } |
|
1506 | + }); |
|
1507 | + } |
|
1508 | + |
|
1509 | + return $files; |
|
1510 | + } else { |
|
1511 | + return []; |
|
1512 | + } |
|
1513 | + } |
|
1514 | + |
|
1515 | + /** |
|
1516 | + * change file metadata |
|
1517 | + * |
|
1518 | + * @param string $path |
|
1519 | + * @param array|\OCP\Files\FileInfo $data |
|
1520 | + * @return int |
|
1521 | + * |
|
1522 | + * returns the fileid of the updated file |
|
1523 | + */ |
|
1524 | + public function putFileInfo($path, $data) { |
|
1525 | + $this->assertPathLength($path); |
|
1526 | + if ($data instanceof FileInfo) { |
|
1527 | + $data = $data->getData(); |
|
1528 | + } |
|
1529 | + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); |
|
1530 | + /** |
|
1531 | + * @var \OC\Files\Storage\Storage $storage |
|
1532 | + * @var string $internalPath |
|
1533 | + */ |
|
1534 | + list($storage, $internalPath) = Filesystem::resolvePath($path); |
|
1535 | + if ($storage) { |
|
1536 | + $cache = $storage->getCache($path); |
|
1537 | + |
|
1538 | + if (!$cache->inCache($internalPath)) { |
|
1539 | + $scanner = $storage->getScanner($internalPath); |
|
1540 | + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); |
|
1541 | + } |
|
1542 | + |
|
1543 | + return $cache->put($internalPath, $data); |
|
1544 | + } else { |
|
1545 | + return -1; |
|
1546 | + } |
|
1547 | + } |
|
1548 | + |
|
1549 | + /** |
|
1550 | + * search for files with the name matching $query |
|
1551 | + * |
|
1552 | + * @param string $query |
|
1553 | + * @return FileInfo[] |
|
1554 | + */ |
|
1555 | + public function search($query) { |
|
1556 | + return $this->searchCommon('search', array('%' . $query . '%')); |
|
1557 | + } |
|
1558 | + |
|
1559 | + /** |
|
1560 | + * search for files with the name matching $query |
|
1561 | + * |
|
1562 | + * @param string $query |
|
1563 | + * @return FileInfo[] |
|
1564 | + */ |
|
1565 | + public function searchRaw($query) { |
|
1566 | + return $this->searchCommon('search', array($query)); |
|
1567 | + } |
|
1568 | + |
|
1569 | + /** |
|
1570 | + * search for files by mimetype |
|
1571 | + * |
|
1572 | + * @param string $mimetype |
|
1573 | + * @return FileInfo[] |
|
1574 | + */ |
|
1575 | + public function searchByMime($mimetype) { |
|
1576 | + return $this->searchCommon('searchByMime', array($mimetype)); |
|
1577 | + } |
|
1578 | + |
|
1579 | + /** |
|
1580 | + * search for files by tag |
|
1581 | + * |
|
1582 | + * @param string|int $tag name or tag id |
|
1583 | + * @param string $userId owner of the tags |
|
1584 | + * @return FileInfo[] |
|
1585 | + */ |
|
1586 | + public function searchByTag($tag, $userId) { |
|
1587 | + return $this->searchCommon('searchByTag', array($tag, $userId)); |
|
1588 | + } |
|
1589 | + |
|
1590 | + /** |
|
1591 | + * @param string $method cache method |
|
1592 | + * @param array $args |
|
1593 | + * @return FileInfo[] |
|
1594 | + */ |
|
1595 | + private function searchCommon($method, $args) { |
|
1596 | + $files = array(); |
|
1597 | + $rootLength = strlen($this->fakeRoot); |
|
1598 | + |
|
1599 | + $mount = $this->getMount(''); |
|
1600 | + $mountPoint = $mount->getMountPoint(); |
|
1601 | + $storage = $mount->getStorage(); |
|
1602 | + if ($storage) { |
|
1603 | + $cache = $storage->getCache(''); |
|
1604 | + |
|
1605 | + $results = call_user_func_array(array($cache, $method), $args); |
|
1606 | + foreach ($results as $result) { |
|
1607 | + if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') { |
|
1608 | + $internalPath = $result['path']; |
|
1609 | + $path = $mountPoint . $result['path']; |
|
1610 | + $result['path'] = substr($mountPoint . $result['path'], $rootLength); |
|
1611 | + $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath)); |
|
1612 | + $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner); |
|
1613 | + } |
|
1614 | + } |
|
1615 | + |
|
1616 | + $mounts = Filesystem::getMountManager()->findIn($this->fakeRoot); |
|
1617 | + foreach ($mounts as $mount) { |
|
1618 | + $mountPoint = $mount->getMountPoint(); |
|
1619 | + $storage = $mount->getStorage(); |
|
1620 | + if ($storage) { |
|
1621 | + $cache = $storage->getCache(''); |
|
1622 | + |
|
1623 | + $relativeMountPoint = substr($mountPoint, $rootLength); |
|
1624 | + $results = call_user_func_array(array($cache, $method), $args); |
|
1625 | + if ($results) { |
|
1626 | + foreach ($results as $result) { |
|
1627 | + $internalPath = $result['path']; |
|
1628 | + $result['path'] = rtrim($relativeMountPoint . $result['path'], '/'); |
|
1629 | + $path = rtrim($mountPoint . $internalPath, '/'); |
|
1630 | + $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath)); |
|
1631 | + $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner); |
|
1632 | + } |
|
1633 | + } |
|
1634 | + } |
|
1635 | + } |
|
1636 | + } |
|
1637 | + return $files; |
|
1638 | + } |
|
1639 | + |
|
1640 | + /** |
|
1641 | + * Get the owner for a file or folder |
|
1642 | + * |
|
1643 | + * @param string $path |
|
1644 | + * @return string the user id of the owner |
|
1645 | + * @throws NotFoundException |
|
1646 | + */ |
|
1647 | + public function getOwner($path) { |
|
1648 | + $info = $this->getFileInfo($path); |
|
1649 | + if (!$info) { |
|
1650 | + throw new NotFoundException($path . ' not found while trying to get owner'); |
|
1651 | + } |
|
1652 | + return $info->getOwner()->getUID(); |
|
1653 | + } |
|
1654 | + |
|
1655 | + /** |
|
1656 | + * get the ETag for a file or folder |
|
1657 | + * |
|
1658 | + * @param string $path |
|
1659 | + * @return string |
|
1660 | + */ |
|
1661 | + public function getETag($path) { |
|
1662 | + /** |
|
1663 | + * @var Storage\Storage $storage |
|
1664 | + * @var string $internalPath |
|
1665 | + */ |
|
1666 | + list($storage, $internalPath) = $this->resolvePath($path); |
|
1667 | + if ($storage) { |
|
1668 | + return $storage->getETag($internalPath); |
|
1669 | + } else { |
|
1670 | + return null; |
|
1671 | + } |
|
1672 | + } |
|
1673 | + |
|
1674 | + /** |
|
1675 | + * Get the path of a file by id, relative to the view |
|
1676 | + * |
|
1677 | + * Note that the resulting path is not guarantied to be unique for the id, multiple paths can point to the same file |
|
1678 | + * |
|
1679 | + * @param int $id |
|
1680 | + * @throws NotFoundException |
|
1681 | + * @return string |
|
1682 | + */ |
|
1683 | + public function getPath($id) { |
|
1684 | + $id = (int)$id; |
|
1685 | + $manager = Filesystem::getMountManager(); |
|
1686 | + $mounts = $manager->findIn($this->fakeRoot); |
|
1687 | + $mounts[] = $manager->find($this->fakeRoot); |
|
1688 | + // reverse the array so we start with the storage this view is in |
|
1689 | + // which is the most likely to contain the file we're looking for |
|
1690 | + $mounts = array_reverse($mounts); |
|
1691 | + foreach ($mounts as $mount) { |
|
1692 | + /** |
|
1693 | + * @var \OC\Files\Mount\MountPoint $mount |
|
1694 | + */ |
|
1695 | + if ($mount->getStorage()) { |
|
1696 | + $cache = $mount->getStorage()->getCache(); |
|
1697 | + $internalPath = $cache->getPathById($id); |
|
1698 | + if (is_string($internalPath)) { |
|
1699 | + $fullPath = $mount->getMountPoint() . $internalPath; |
|
1700 | + if (!is_null($path = $this->getRelativePath($fullPath))) { |
|
1701 | + return $path; |
|
1702 | + } |
|
1703 | + } |
|
1704 | + } |
|
1705 | + } |
|
1706 | + throw new NotFoundException(sprintf('File with id "%s" has not been found.', $id)); |
|
1707 | + } |
|
1708 | + |
|
1709 | + /** |
|
1710 | + * @param string $path |
|
1711 | + * @throws InvalidPathException |
|
1712 | + */ |
|
1713 | + private function assertPathLength($path) { |
|
1714 | + $maxLen = min(PHP_MAXPATHLEN, 4000); |
|
1715 | + // Check for the string length - performed using isset() instead of strlen() |
|
1716 | + // because isset() is about 5x-40x faster. |
|
1717 | + if (isset($path[$maxLen])) { |
|
1718 | + $pathLen = strlen($path); |
|
1719 | + throw new \OCP\Files\InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path"); |
|
1720 | + } |
|
1721 | + } |
|
1722 | + |
|
1723 | + /** |
|
1724 | + * check if it is allowed to move a mount point to a given target. |
|
1725 | + * It is not allowed to move a mount point into a different mount point or |
|
1726 | + * into an already shared folder |
|
1727 | + * |
|
1728 | + * @param string $target path |
|
1729 | + * @return boolean |
|
1730 | + */ |
|
1731 | + private function isTargetAllowed($target) { |
|
1732 | + |
|
1733 | + list($targetStorage, $targetInternalPath) = \OC\Files\Filesystem::resolvePath($target); |
|
1734 | + if (!$targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage')) { |
|
1735 | + \OCP\Util::writeLog('files', |
|
1736 | + 'It is not allowed to move one mount point into another one', |
|
1737 | + \OCP\Util::DEBUG); |
|
1738 | + return false; |
|
1739 | + } |
|
1740 | + |
|
1741 | + // note: cannot use the view because the target is already locked |
|
1742 | + $fileId = (int)$targetStorage->getCache()->getId($targetInternalPath); |
|
1743 | + if ($fileId === -1) { |
|
1744 | + // target might not exist, need to check parent instead |
|
1745 | + $fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath)); |
|
1746 | + } |
|
1747 | + |
|
1748 | + // check if any of the parents were shared by the current owner (include collections) |
|
1749 | + $shares = \OCP\Share::getItemShared( |
|
1750 | + 'folder', |
|
1751 | + $fileId, |
|
1752 | + \OCP\Share::FORMAT_NONE, |
|
1753 | + null, |
|
1754 | + true |
|
1755 | + ); |
|
1756 | + |
|
1757 | + if (count($shares) > 0) { |
|
1758 | + \OCP\Util::writeLog('files', |
|
1759 | + 'It is not allowed to move one mount point into a shared folder', |
|
1760 | + \OCP\Util::DEBUG); |
|
1761 | + return false; |
|
1762 | + } |
|
1763 | + |
|
1764 | + return true; |
|
1765 | + } |
|
1766 | + |
|
1767 | + /** |
|
1768 | + * Get a fileinfo object for files that are ignored in the cache (part files) |
|
1769 | + * |
|
1770 | + * @param string $path |
|
1771 | + * @return \OCP\Files\FileInfo |
|
1772 | + */ |
|
1773 | + private function getPartFileInfo($path) { |
|
1774 | + $mount = $this->getMount($path); |
|
1775 | + $storage = $mount->getStorage(); |
|
1776 | + $internalPath = $mount->getInternalPath($this->getAbsolutePath($path)); |
|
1777 | + $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath)); |
|
1778 | + return new FileInfo( |
|
1779 | + $this->getAbsolutePath($path), |
|
1780 | + $storage, |
|
1781 | + $internalPath, |
|
1782 | + [ |
|
1783 | + 'fileid' => null, |
|
1784 | + 'mimetype' => $storage->getMimeType($internalPath), |
|
1785 | + 'name' => basename($path), |
|
1786 | + 'etag' => null, |
|
1787 | + 'size' => $storage->filesize($internalPath), |
|
1788 | + 'mtime' => $storage->filemtime($internalPath), |
|
1789 | + 'encrypted' => false, |
|
1790 | + 'permissions' => \OCP\Constants::PERMISSION_ALL |
|
1791 | + ], |
|
1792 | + $mount, |
|
1793 | + $owner |
|
1794 | + ); |
|
1795 | + } |
|
1796 | + |
|
1797 | + /** |
|
1798 | + * @param string $path |
|
1799 | + * @param string $fileName |
|
1800 | + * @throws InvalidPathException |
|
1801 | + */ |
|
1802 | + public function verifyPath($path, $fileName) { |
|
1803 | + try { |
|
1804 | + /** @type \OCP\Files\Storage $storage */ |
|
1805 | + list($storage, $internalPath) = $this->resolvePath($path); |
|
1806 | + $storage->verifyPath($internalPath, $fileName); |
|
1807 | + } catch (ReservedWordException $ex) { |
|
1808 | + $l = \OC::$server->getL10N('lib'); |
|
1809 | + throw new InvalidPathException($l->t('File name is a reserved word')); |
|
1810 | + } catch (InvalidCharacterInPathException $ex) { |
|
1811 | + $l = \OC::$server->getL10N('lib'); |
|
1812 | + throw new InvalidPathException($l->t('File name contains at least one invalid character')); |
|
1813 | + } catch (FileNameTooLongException $ex) { |
|
1814 | + $l = \OC::$server->getL10N('lib'); |
|
1815 | + throw new InvalidPathException($l->t('File name is too long')); |
|
1816 | + } catch (InvalidDirectoryException $ex) { |
|
1817 | + $l = \OC::$server->getL10N('lib'); |
|
1818 | + throw new InvalidPathException($l->t('Dot files are not allowed')); |
|
1819 | + } catch (EmptyFileNameException $ex) { |
|
1820 | + $l = \OC::$server->getL10N('lib'); |
|
1821 | + throw new InvalidPathException($l->t('Empty filename is not allowed')); |
|
1822 | + } |
|
1823 | + } |
|
1824 | + |
|
1825 | + /** |
|
1826 | + * get all parent folders of $path |
|
1827 | + * |
|
1828 | + * @param string $path |
|
1829 | + * @return string[] |
|
1830 | + */ |
|
1831 | + private function getParents($path) { |
|
1832 | + $path = trim($path, '/'); |
|
1833 | + if (!$path) { |
|
1834 | + return []; |
|
1835 | + } |
|
1836 | + |
|
1837 | + $parts = explode('/', $path); |
|
1838 | + |
|
1839 | + // remove the single file |
|
1840 | + array_pop($parts); |
|
1841 | + $result = array('/'); |
|
1842 | + $resultPath = ''; |
|
1843 | + foreach ($parts as $part) { |
|
1844 | + if ($part) { |
|
1845 | + $resultPath .= '/' . $part; |
|
1846 | + $result[] = $resultPath; |
|
1847 | + } |
|
1848 | + } |
|
1849 | + return $result; |
|
1850 | + } |
|
1851 | + |
|
1852 | + /** |
|
1853 | + * Returns the mount point for which to lock |
|
1854 | + * |
|
1855 | + * @param string $absolutePath absolute path |
|
1856 | + * @param bool $useParentMount true to return parent mount instead of whatever |
|
1857 | + * is mounted directly on the given path, false otherwise |
|
1858 | + * @return \OC\Files\Mount\MountPoint mount point for which to apply locks |
|
1859 | + */ |
|
1860 | + private function getMountForLock($absolutePath, $useParentMount = false) { |
|
1861 | + $results = []; |
|
1862 | + $mount = Filesystem::getMountManager()->find($absolutePath); |
|
1863 | + if (!$mount) { |
|
1864 | + return $results; |
|
1865 | + } |
|
1866 | + |
|
1867 | + if ($useParentMount) { |
|
1868 | + // find out if something is mounted directly on the path |
|
1869 | + $internalPath = $mount->getInternalPath($absolutePath); |
|
1870 | + if ($internalPath === '') { |
|
1871 | + // resolve the parent mount instead |
|
1872 | + $mount = Filesystem::getMountManager()->find(dirname($absolutePath)); |
|
1873 | + } |
|
1874 | + } |
|
1875 | + |
|
1876 | + return $mount; |
|
1877 | + } |
|
1878 | + |
|
1879 | + /** |
|
1880 | + * Lock the given path |
|
1881 | + * |
|
1882 | + * @param string $path the path of the file to lock, relative to the view |
|
1883 | + * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
1884 | + * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
1885 | + * |
|
1886 | + * @return bool False if the path is excluded from locking, true otherwise |
|
1887 | + * @throws \OCP\Lock\LockedException if the path is already locked |
|
1888 | + */ |
|
1889 | + private function lockPath($path, $type, $lockMountPoint = false) { |
|
1890 | + $absolutePath = $this->getAbsolutePath($path); |
|
1891 | + $absolutePath = Filesystem::normalizePath($absolutePath); |
|
1892 | + if (!$this->shouldLockFile($absolutePath)) { |
|
1893 | + return false; |
|
1894 | + } |
|
1895 | + |
|
1896 | + $mount = $this->getMountForLock($absolutePath, $lockMountPoint); |
|
1897 | + if ($mount) { |
|
1898 | + try { |
|
1899 | + $storage = $mount->getStorage(); |
|
1900 | + if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { |
|
1901 | + $storage->acquireLock( |
|
1902 | + $mount->getInternalPath($absolutePath), |
|
1903 | + $type, |
|
1904 | + $this->lockingProvider |
|
1905 | + ); |
|
1906 | + } |
|
1907 | + } catch (\OCP\Lock\LockedException $e) { |
|
1908 | + // rethrow with the a human-readable path |
|
1909 | + throw new \OCP\Lock\LockedException( |
|
1910 | + $this->getPathRelativeToFiles($absolutePath), |
|
1911 | + $e |
|
1912 | + ); |
|
1913 | + } |
|
1914 | + } |
|
1915 | + |
|
1916 | + return true; |
|
1917 | + } |
|
1918 | + |
|
1919 | + /** |
|
1920 | + * Change the lock type |
|
1921 | + * |
|
1922 | + * @param string $path the path of the file to lock, relative to the view |
|
1923 | + * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
1924 | + * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
1925 | + * |
|
1926 | + * @return bool False if the path is excluded from locking, true otherwise |
|
1927 | + * @throws \OCP\Lock\LockedException if the path is already locked |
|
1928 | + */ |
|
1929 | + public function changeLock($path, $type, $lockMountPoint = false) { |
|
1930 | + $path = Filesystem::normalizePath($path); |
|
1931 | + $absolutePath = $this->getAbsolutePath($path); |
|
1932 | + $absolutePath = Filesystem::normalizePath($absolutePath); |
|
1933 | + if (!$this->shouldLockFile($absolutePath)) { |
|
1934 | + return false; |
|
1935 | + } |
|
1936 | + |
|
1937 | + $mount = $this->getMountForLock($absolutePath, $lockMountPoint); |
|
1938 | + if ($mount) { |
|
1939 | + try { |
|
1940 | + $storage = $mount->getStorage(); |
|
1941 | + if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { |
|
1942 | + $storage->changeLock( |
|
1943 | + $mount->getInternalPath($absolutePath), |
|
1944 | + $type, |
|
1945 | + $this->lockingProvider |
|
1946 | + ); |
|
1947 | + } |
|
1948 | + } catch (\OCP\Lock\LockedException $e) { |
|
1949 | + // rethrow with the a human-readable path |
|
1950 | + throw new \OCP\Lock\LockedException( |
|
1951 | + $this->getPathRelativeToFiles($absolutePath), |
|
1952 | + $e |
|
1953 | + ); |
|
1954 | + } |
|
1955 | + } |
|
1956 | + |
|
1957 | + return true; |
|
1958 | + } |
|
1959 | + |
|
1960 | + /** |
|
1961 | + * Unlock the given path |
|
1962 | + * |
|
1963 | + * @param string $path the path of the file to unlock, relative to the view |
|
1964 | + * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
1965 | + * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
1966 | + * |
|
1967 | + * @return bool False if the path is excluded from locking, true otherwise |
|
1968 | + */ |
|
1969 | + private function unlockPath($path, $type, $lockMountPoint = false) { |
|
1970 | + $absolutePath = $this->getAbsolutePath($path); |
|
1971 | + $absolutePath = Filesystem::normalizePath($absolutePath); |
|
1972 | + if (!$this->shouldLockFile($absolutePath)) { |
|
1973 | + return false; |
|
1974 | + } |
|
1975 | + |
|
1976 | + $mount = $this->getMountForLock($absolutePath, $lockMountPoint); |
|
1977 | + if ($mount) { |
|
1978 | + $storage = $mount->getStorage(); |
|
1979 | + if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) { |
|
1980 | + $storage->releaseLock( |
|
1981 | + $mount->getInternalPath($absolutePath), |
|
1982 | + $type, |
|
1983 | + $this->lockingProvider |
|
1984 | + ); |
|
1985 | + } |
|
1986 | + } |
|
1987 | + |
|
1988 | + return true; |
|
1989 | + } |
|
1990 | + |
|
1991 | + /** |
|
1992 | + * Lock a path and all its parents up to the root of the view |
|
1993 | + * |
|
1994 | + * @param string $path the path of the file to lock relative to the view |
|
1995 | + * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
1996 | + * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
1997 | + * |
|
1998 | + * @return bool False if the path is excluded from locking, true otherwise |
|
1999 | + */ |
|
2000 | + public function lockFile($path, $type, $lockMountPoint = false) { |
|
2001 | + $absolutePath = $this->getAbsolutePath($path); |
|
2002 | + $absolutePath = Filesystem::normalizePath($absolutePath); |
|
2003 | + if (!$this->shouldLockFile($absolutePath)) { |
|
2004 | + return false; |
|
2005 | + } |
|
2006 | + |
|
2007 | + $this->lockPath($path, $type, $lockMountPoint); |
|
2008 | + |
|
2009 | + $parents = $this->getParents($path); |
|
2010 | + foreach ($parents as $parent) { |
|
2011 | + $this->lockPath($parent, ILockingProvider::LOCK_SHARED); |
|
2012 | + } |
|
2013 | + |
|
2014 | + return true; |
|
2015 | + } |
|
2016 | + |
|
2017 | + /** |
|
2018 | + * Unlock a path and all its parents up to the root of the view |
|
2019 | + * |
|
2020 | + * @param string $path the path of the file to lock relative to the view |
|
2021 | + * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE |
|
2022 | + * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage |
|
2023 | + * |
|
2024 | + * @return bool False if the path is excluded from locking, true otherwise |
|
2025 | + */ |
|
2026 | + public function unlockFile($path, $type, $lockMountPoint = false) { |
|
2027 | + $absolutePath = $this->getAbsolutePath($path); |
|
2028 | + $absolutePath = Filesystem::normalizePath($absolutePath); |
|
2029 | + if (!$this->shouldLockFile($absolutePath)) { |
|
2030 | + return false; |
|
2031 | + } |
|
2032 | + |
|
2033 | + $this->unlockPath($path, $type, $lockMountPoint); |
|
2034 | + |
|
2035 | + $parents = $this->getParents($path); |
|
2036 | + foreach ($parents as $parent) { |
|
2037 | + $this->unlockPath($parent, ILockingProvider::LOCK_SHARED); |
|
2038 | + } |
|
2039 | + |
|
2040 | + return true; |
|
2041 | + } |
|
2042 | + |
|
2043 | + /** |
|
2044 | + * Only lock files in data/user/files/ |
|
2045 | + * |
|
2046 | + * @param string $path Absolute path to the file/folder we try to (un)lock |
|
2047 | + * @return bool |
|
2048 | + */ |
|
2049 | + protected function shouldLockFile($path) { |
|
2050 | + $path = Filesystem::normalizePath($path); |
|
2051 | + |
|
2052 | + $pathSegments = explode('/', $path); |
|
2053 | + if (isset($pathSegments[2])) { |
|
2054 | + // E.g.: /username/files/path-to-file |
|
2055 | + return ($pathSegments[2] === 'files') && (count($pathSegments) > 3); |
|
2056 | + } |
|
2057 | + |
|
2058 | + return true; |
|
2059 | + } |
|
2060 | + |
|
2061 | + /** |
|
2062 | + * Shortens the given absolute path to be relative to |
|
2063 | + * "$user/files". |
|
2064 | + * |
|
2065 | + * @param string $absolutePath absolute path which is under "files" |
|
2066 | + * |
|
2067 | + * @return string path relative to "files" with trimmed slashes or null |
|
2068 | + * if the path was NOT relative to files |
|
2069 | + * |
|
2070 | + * @throws \InvalidArgumentException if the given path was not under "files" |
|
2071 | + * @since 8.1.0 |
|
2072 | + */ |
|
2073 | + public function getPathRelativeToFiles($absolutePath) { |
|
2074 | + $path = Filesystem::normalizePath($absolutePath); |
|
2075 | + $parts = explode('/', trim($path, '/'), 3); |
|
2076 | + // "$user", "files", "path/to/dir" |
|
2077 | + if (!isset($parts[1]) || $parts[1] !== 'files') { |
|
2078 | + $this->logger->error( |
|
2079 | + '$absolutePath must be relative to "files", value is "%s"', |
|
2080 | + [ |
|
2081 | + $absolutePath |
|
2082 | + ] |
|
2083 | + ); |
|
2084 | + throw new \InvalidArgumentException('$absolutePath must be relative to "files"'); |
|
2085 | + } |
|
2086 | + if (isset($parts[2])) { |
|
2087 | + return $parts[2]; |
|
2088 | + } |
|
2089 | + return ''; |
|
2090 | + } |
|
2091 | + |
|
2092 | + /** |
|
2093 | + * @param string $filename |
|
2094 | + * @return array |
|
2095 | + * @throws \OC\User\NoUserException |
|
2096 | + * @throws NotFoundException |
|
2097 | + */ |
|
2098 | + public function getUidAndFilename($filename) { |
|
2099 | + $info = $this->getFileInfo($filename); |
|
2100 | + if (!$info instanceof \OCP\Files\FileInfo) { |
|
2101 | + throw new NotFoundException($this->getAbsolutePath($filename) . ' not found'); |
|
2102 | + } |
|
2103 | + $uid = $info->getOwner()->getUID(); |
|
2104 | + if ($uid != \OCP\User::getUser()) { |
|
2105 | + Filesystem::initMountPoints($uid); |
|
2106 | + $ownerView = new View('/' . $uid . '/files'); |
|
2107 | + try { |
|
2108 | + $filename = $ownerView->getPath($info['fileid']); |
|
2109 | + } catch (NotFoundException $e) { |
|
2110 | + throw new NotFoundException('File with id ' . $info['fileid'] . ' not found for user ' . $uid); |
|
2111 | + } |
|
2112 | + } |
|
2113 | + return [$uid, $filename]; |
|
2114 | + } |
|
2115 | + |
|
2116 | + /** |
|
2117 | + * Creates parent non-existing folders |
|
2118 | + * |
|
2119 | + * @param string $filePath |
|
2120 | + * @return bool |
|
2121 | + */ |
|
2122 | + private function createParentDirectories($filePath) { |
|
2123 | + $directoryParts = explode('/', $filePath); |
|
2124 | + $directoryParts = array_filter($directoryParts); |
|
2125 | + foreach ($directoryParts as $key => $part) { |
|
2126 | + $currentPathElements = array_slice($directoryParts, 0, $key); |
|
2127 | + $currentPath = '/' . implode('/', $currentPathElements); |
|
2128 | + if ($this->is_file($currentPath)) { |
|
2129 | + return false; |
|
2130 | + } |
|
2131 | + if (!$this->file_exists($currentPath)) { |
|
2132 | + $this->mkdir($currentPath); |
|
2133 | + } |
|
2134 | + } |
|
2135 | + |
|
2136 | + return true; |
|
2137 | + } |
|
2138 | 2138 | } |
@@ -303,6 +303,7 @@ |
||
303 | 303 | * get default share folder |
304 | 304 | * |
305 | 305 | * @param \OC\Files\View |
306 | + * @param View $view |
|
306 | 307 | * @return string |
307 | 308 | */ |
308 | 309 | public static function getShareFolder($view = null) { |
@@ -36,242 +36,242 @@ |
||
36 | 36 | |
37 | 37 | class Helper { |
38 | 38 | |
39 | - public static function registerHooks() { |
|
40 | - \OCP\Util::connectHook('OC_Filesystem', 'post_rename', '\OCA\Files_Sharing\Updater', 'renameHook'); |
|
41 | - \OCP\Util::connectHook('OC_Filesystem', 'post_delete', '\OCA\Files_Sharing\Hooks', 'unshareChildren'); |
|
42 | - |
|
43 | - \OCP\Util::connectHook('OC_User', 'post_deleteUser', '\OCA\Files_Sharing\Hooks', 'deleteUser'); |
|
44 | - } |
|
45 | - |
|
46 | - /** |
|
47 | - * Sets up the filesystem and user for public sharing |
|
48 | - * @param string $token string share token |
|
49 | - * @param string $relativePath optional path relative to the share |
|
50 | - * @param string $password optional password |
|
51 | - * @return array |
|
52 | - */ |
|
53 | - public static function setupFromToken($token, $relativePath = null, $password = null) { |
|
54 | - \OC_User::setIncognitoMode(true); |
|
55 | - |
|
56 | - $shareManager = \OC::$server->getShareManager(); |
|
57 | - |
|
58 | - try { |
|
59 | - $share = $shareManager->getShareByToken($token); |
|
60 | - } catch (ShareNotFound $e) { |
|
61 | - \OC_Response::setStatus(404); |
|
62 | - \OCP\Util::writeLog('core-preview', 'Passed token parameter is not valid', \OCP\Util::DEBUG); |
|
63 | - exit; |
|
64 | - } |
|
65 | - |
|
66 | - \OCP\JSON::checkUserExists($share->getShareOwner()); |
|
67 | - \OC_Util::tearDownFS(); |
|
68 | - \OC_Util::setupFS($share->getShareOwner()); |
|
69 | - |
|
70 | - |
|
71 | - try { |
|
72 | - $path = Filesystem::getPath($share->getNodeId()); |
|
73 | - } catch (NotFoundException $e) { |
|
74 | - \OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); |
|
75 | - \OC_Response::setStatus(404); |
|
76 | - \OCP\JSON::error(array('success' => false)); |
|
77 | - exit(); |
|
78 | - } |
|
79 | - |
|
80 | - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK && $share->getPassword() !== null) { |
|
81 | - if (!self::authenticate($share, $password)) { |
|
82 | - \OC_Response::setStatus(403); |
|
83 | - \OCP\JSON::error(array('success' => false)); |
|
84 | - exit(); |
|
85 | - } |
|
86 | - } |
|
87 | - |
|
88 | - $basePath = $path; |
|
89 | - |
|
90 | - if ($relativePath !== null && Filesystem::isReadable($basePath . $relativePath)) { |
|
91 | - $path .= Filesystem::normalizePath($relativePath); |
|
92 | - } |
|
93 | - |
|
94 | - return array( |
|
95 | - 'share' => $share, |
|
96 | - 'basePath' => $basePath, |
|
97 | - 'realPath' => $path |
|
98 | - ); |
|
99 | - } |
|
100 | - |
|
101 | - /** |
|
102 | - * Authenticate link item with the given password |
|
103 | - * or with the session if no password was given. |
|
104 | - * @param \OCP\Share\IShare $share |
|
105 | - * @param string $password optional password |
|
106 | - * |
|
107 | - * @return boolean true if authorized, false otherwise |
|
108 | - */ |
|
109 | - public static function authenticate($share, $password = null) { |
|
110 | - $shareManager = \OC::$server->getShareManager(); |
|
111 | - |
|
112 | - if ($password !== null) { |
|
113 | - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { |
|
114 | - if ($shareManager->checkPassword($share, $password)) { |
|
115 | - \OC::$server->getSession()->set('public_link_authenticated', (string)$share->getId()); |
|
116 | - return true; |
|
117 | - } |
|
118 | - } |
|
119 | - } else { |
|
120 | - // not authenticated ? |
|
121 | - if (\OC::$server->getSession()->exists('public_link_authenticated') |
|
122 | - && \OC::$server->getSession()->get('public_link_authenticated') !== (string)$share->getId()) { |
|
123 | - return true; |
|
124 | - } |
|
125 | - } |
|
126 | - return false; |
|
127 | - } |
|
128 | - |
|
129 | - public static function getSharesFromItem($target) { |
|
130 | - $result = array(); |
|
131 | - $owner = Filesystem::getOwner($target); |
|
132 | - Filesystem::initMountPoints($owner); |
|
133 | - $info = Filesystem::getFileInfo($target); |
|
134 | - $ownerView = new View('/'.$owner.'/files'); |
|
135 | - if ( $owner != User::getUser() ) { |
|
136 | - $path = $ownerView->getPath($info['fileid']); |
|
137 | - } else { |
|
138 | - $path = $target; |
|
139 | - } |
|
140 | - |
|
141 | - |
|
142 | - $ids = array(); |
|
143 | - while ($path !== dirname($path)) { |
|
144 | - $info = $ownerView->getFileInfo($path); |
|
145 | - if ($info instanceof \OC\Files\FileInfo) { |
|
146 | - $ids[] = $info['fileid']; |
|
147 | - } else { |
|
148 | - \OCP\Util::writeLog('sharing', 'No fileinfo available for: ' . $path, \OCP\Util::WARN); |
|
149 | - } |
|
150 | - $path = dirname($path); |
|
151 | - } |
|
152 | - |
|
153 | - if (!empty($ids)) { |
|
154 | - |
|
155 | - $idList = array_chunk($ids, 99, true); |
|
156 | - |
|
157 | - foreach ($idList as $subList) { |
|
158 | - $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (" . implode(',', $subList) . ") AND `share_type` IN (0, 1, 2)"; |
|
159 | - $query = \OCP\DB::prepare($statement); |
|
160 | - $r = $query->execute(); |
|
161 | - $result = array_merge($result, $r->fetchAll()); |
|
162 | - } |
|
163 | - } |
|
164 | - |
|
165 | - return $result; |
|
166 | - } |
|
167 | - |
|
168 | - /** |
|
169 | - * get the UID of the owner of the file and the path to the file relative to |
|
170 | - * owners files folder |
|
171 | - * |
|
172 | - * @param $filename |
|
173 | - * @return array |
|
174 | - * @throws \OC\User\NoUserException |
|
175 | - */ |
|
176 | - public static function getUidAndFilename($filename) { |
|
177 | - $uid = Filesystem::getOwner($filename); |
|
178 | - $userManager = \OC::$server->getUserManager(); |
|
179 | - // if the user with the UID doesn't exists, e.g. because the UID points |
|
180 | - // to a remote user with a federated cloud ID we use the current logged-in |
|
181 | - // user. We need a valid local user to create the share |
|
182 | - if (!$userManager->userExists($uid)) { |
|
183 | - $uid = User::getUser(); |
|
184 | - } |
|
185 | - Filesystem::initMountPoints($uid); |
|
186 | - if ( $uid != User::getUser() ) { |
|
187 | - $info = Filesystem::getFileInfo($filename); |
|
188 | - $ownerView = new View('/'.$uid.'/files'); |
|
189 | - try { |
|
190 | - $filename = $ownerView->getPath($info['fileid']); |
|
191 | - } catch (NotFoundException $e) { |
|
192 | - $filename = null; |
|
193 | - } |
|
194 | - } |
|
195 | - return [$uid, $filename]; |
|
196 | - } |
|
197 | - |
|
198 | - /** |
|
199 | - * Format a path to be relative to the /user/files/ directory |
|
200 | - * @param string $path the absolute path |
|
201 | - * @return string e.g. turns '/admin/files/test.txt' into 'test.txt' |
|
202 | - */ |
|
203 | - public static function stripUserFilesPath($path) { |
|
204 | - $trimmed = ltrim($path, '/'); |
|
205 | - $split = explode('/', $trimmed); |
|
206 | - |
|
207 | - // it is not a file relative to data/user/files |
|
208 | - if (count($split) < 3 || $split[1] !== 'files') { |
|
209 | - return false; |
|
210 | - } |
|
211 | - |
|
212 | - $sliced = array_slice($split, 2); |
|
213 | - $relPath = implode('/', $sliced); |
|
214 | - |
|
215 | - return $relPath; |
|
216 | - } |
|
217 | - |
|
218 | - /** |
|
219 | - * check if file name already exists and generate unique target |
|
220 | - * |
|
221 | - * @param string $path |
|
222 | - * @param array $excludeList |
|
223 | - * @param View $view |
|
224 | - * @return string $path |
|
225 | - */ |
|
226 | - public static function generateUniqueTarget($path, $excludeList, $view) { |
|
227 | - $pathinfo = pathinfo($path); |
|
228 | - $ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : ''; |
|
229 | - $name = $pathinfo['filename']; |
|
230 | - $dir = $pathinfo['dirname']; |
|
231 | - $i = 2; |
|
232 | - while ($view->file_exists($path) || in_array($path, $excludeList)) { |
|
233 | - $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); |
|
234 | - $i++; |
|
235 | - } |
|
236 | - |
|
237 | - return $path; |
|
238 | - } |
|
239 | - |
|
240 | - /** |
|
241 | - * get default share folder |
|
242 | - * |
|
243 | - * @param \OC\Files\View |
|
244 | - * @return string |
|
245 | - */ |
|
246 | - public static function getShareFolder($view = null) { |
|
247 | - if ($view === null) { |
|
248 | - $view = Filesystem::getView(); |
|
249 | - } |
|
250 | - $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/'); |
|
251 | - $shareFolder = Filesystem::normalizePath($shareFolder); |
|
252 | - |
|
253 | - if (!$view->file_exists($shareFolder)) { |
|
254 | - $dir = ''; |
|
255 | - $subdirs = explode('/', $shareFolder); |
|
256 | - foreach ($subdirs as $subdir) { |
|
257 | - $dir = $dir . '/' . $subdir; |
|
258 | - if (!$view->is_dir($dir)) { |
|
259 | - $view->mkdir($dir); |
|
260 | - } |
|
261 | - } |
|
262 | - } |
|
263 | - |
|
264 | - return $shareFolder; |
|
265 | - |
|
266 | - } |
|
267 | - |
|
268 | - /** |
|
269 | - * set default share folder |
|
270 | - * |
|
271 | - * @param string $shareFolder |
|
272 | - */ |
|
273 | - public static function setShareFolder($shareFolder) { |
|
274 | - \OC::$server->getConfig()->setSystemValue('share_folder', $shareFolder); |
|
275 | - } |
|
39 | + public static function registerHooks() { |
|
40 | + \OCP\Util::connectHook('OC_Filesystem', 'post_rename', '\OCA\Files_Sharing\Updater', 'renameHook'); |
|
41 | + \OCP\Util::connectHook('OC_Filesystem', 'post_delete', '\OCA\Files_Sharing\Hooks', 'unshareChildren'); |
|
42 | + |
|
43 | + \OCP\Util::connectHook('OC_User', 'post_deleteUser', '\OCA\Files_Sharing\Hooks', 'deleteUser'); |
|
44 | + } |
|
45 | + |
|
46 | + /** |
|
47 | + * Sets up the filesystem and user for public sharing |
|
48 | + * @param string $token string share token |
|
49 | + * @param string $relativePath optional path relative to the share |
|
50 | + * @param string $password optional password |
|
51 | + * @return array |
|
52 | + */ |
|
53 | + public static function setupFromToken($token, $relativePath = null, $password = null) { |
|
54 | + \OC_User::setIncognitoMode(true); |
|
55 | + |
|
56 | + $shareManager = \OC::$server->getShareManager(); |
|
57 | + |
|
58 | + try { |
|
59 | + $share = $shareManager->getShareByToken($token); |
|
60 | + } catch (ShareNotFound $e) { |
|
61 | + \OC_Response::setStatus(404); |
|
62 | + \OCP\Util::writeLog('core-preview', 'Passed token parameter is not valid', \OCP\Util::DEBUG); |
|
63 | + exit; |
|
64 | + } |
|
65 | + |
|
66 | + \OCP\JSON::checkUserExists($share->getShareOwner()); |
|
67 | + \OC_Util::tearDownFS(); |
|
68 | + \OC_Util::setupFS($share->getShareOwner()); |
|
69 | + |
|
70 | + |
|
71 | + try { |
|
72 | + $path = Filesystem::getPath($share->getNodeId()); |
|
73 | + } catch (NotFoundException $e) { |
|
74 | + \OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); |
|
75 | + \OC_Response::setStatus(404); |
|
76 | + \OCP\JSON::error(array('success' => false)); |
|
77 | + exit(); |
|
78 | + } |
|
79 | + |
|
80 | + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK && $share->getPassword() !== null) { |
|
81 | + if (!self::authenticate($share, $password)) { |
|
82 | + \OC_Response::setStatus(403); |
|
83 | + \OCP\JSON::error(array('success' => false)); |
|
84 | + exit(); |
|
85 | + } |
|
86 | + } |
|
87 | + |
|
88 | + $basePath = $path; |
|
89 | + |
|
90 | + if ($relativePath !== null && Filesystem::isReadable($basePath . $relativePath)) { |
|
91 | + $path .= Filesystem::normalizePath($relativePath); |
|
92 | + } |
|
93 | + |
|
94 | + return array( |
|
95 | + 'share' => $share, |
|
96 | + 'basePath' => $basePath, |
|
97 | + 'realPath' => $path |
|
98 | + ); |
|
99 | + } |
|
100 | + |
|
101 | + /** |
|
102 | + * Authenticate link item with the given password |
|
103 | + * or with the session if no password was given. |
|
104 | + * @param \OCP\Share\IShare $share |
|
105 | + * @param string $password optional password |
|
106 | + * |
|
107 | + * @return boolean true if authorized, false otherwise |
|
108 | + */ |
|
109 | + public static function authenticate($share, $password = null) { |
|
110 | + $shareManager = \OC::$server->getShareManager(); |
|
111 | + |
|
112 | + if ($password !== null) { |
|
113 | + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { |
|
114 | + if ($shareManager->checkPassword($share, $password)) { |
|
115 | + \OC::$server->getSession()->set('public_link_authenticated', (string)$share->getId()); |
|
116 | + return true; |
|
117 | + } |
|
118 | + } |
|
119 | + } else { |
|
120 | + // not authenticated ? |
|
121 | + if (\OC::$server->getSession()->exists('public_link_authenticated') |
|
122 | + && \OC::$server->getSession()->get('public_link_authenticated') !== (string)$share->getId()) { |
|
123 | + return true; |
|
124 | + } |
|
125 | + } |
|
126 | + return false; |
|
127 | + } |
|
128 | + |
|
129 | + public static function getSharesFromItem($target) { |
|
130 | + $result = array(); |
|
131 | + $owner = Filesystem::getOwner($target); |
|
132 | + Filesystem::initMountPoints($owner); |
|
133 | + $info = Filesystem::getFileInfo($target); |
|
134 | + $ownerView = new View('/'.$owner.'/files'); |
|
135 | + if ( $owner != User::getUser() ) { |
|
136 | + $path = $ownerView->getPath($info['fileid']); |
|
137 | + } else { |
|
138 | + $path = $target; |
|
139 | + } |
|
140 | + |
|
141 | + |
|
142 | + $ids = array(); |
|
143 | + while ($path !== dirname($path)) { |
|
144 | + $info = $ownerView->getFileInfo($path); |
|
145 | + if ($info instanceof \OC\Files\FileInfo) { |
|
146 | + $ids[] = $info['fileid']; |
|
147 | + } else { |
|
148 | + \OCP\Util::writeLog('sharing', 'No fileinfo available for: ' . $path, \OCP\Util::WARN); |
|
149 | + } |
|
150 | + $path = dirname($path); |
|
151 | + } |
|
152 | + |
|
153 | + if (!empty($ids)) { |
|
154 | + |
|
155 | + $idList = array_chunk($ids, 99, true); |
|
156 | + |
|
157 | + foreach ($idList as $subList) { |
|
158 | + $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (" . implode(',', $subList) . ") AND `share_type` IN (0, 1, 2)"; |
|
159 | + $query = \OCP\DB::prepare($statement); |
|
160 | + $r = $query->execute(); |
|
161 | + $result = array_merge($result, $r->fetchAll()); |
|
162 | + } |
|
163 | + } |
|
164 | + |
|
165 | + return $result; |
|
166 | + } |
|
167 | + |
|
168 | + /** |
|
169 | + * get the UID of the owner of the file and the path to the file relative to |
|
170 | + * owners files folder |
|
171 | + * |
|
172 | + * @param $filename |
|
173 | + * @return array |
|
174 | + * @throws \OC\User\NoUserException |
|
175 | + */ |
|
176 | + public static function getUidAndFilename($filename) { |
|
177 | + $uid = Filesystem::getOwner($filename); |
|
178 | + $userManager = \OC::$server->getUserManager(); |
|
179 | + // if the user with the UID doesn't exists, e.g. because the UID points |
|
180 | + // to a remote user with a federated cloud ID we use the current logged-in |
|
181 | + // user. We need a valid local user to create the share |
|
182 | + if (!$userManager->userExists($uid)) { |
|
183 | + $uid = User::getUser(); |
|
184 | + } |
|
185 | + Filesystem::initMountPoints($uid); |
|
186 | + if ( $uid != User::getUser() ) { |
|
187 | + $info = Filesystem::getFileInfo($filename); |
|
188 | + $ownerView = new View('/'.$uid.'/files'); |
|
189 | + try { |
|
190 | + $filename = $ownerView->getPath($info['fileid']); |
|
191 | + } catch (NotFoundException $e) { |
|
192 | + $filename = null; |
|
193 | + } |
|
194 | + } |
|
195 | + return [$uid, $filename]; |
|
196 | + } |
|
197 | + |
|
198 | + /** |
|
199 | + * Format a path to be relative to the /user/files/ directory |
|
200 | + * @param string $path the absolute path |
|
201 | + * @return string e.g. turns '/admin/files/test.txt' into 'test.txt' |
|
202 | + */ |
|
203 | + public static function stripUserFilesPath($path) { |
|
204 | + $trimmed = ltrim($path, '/'); |
|
205 | + $split = explode('/', $trimmed); |
|
206 | + |
|
207 | + // it is not a file relative to data/user/files |
|
208 | + if (count($split) < 3 || $split[1] !== 'files') { |
|
209 | + return false; |
|
210 | + } |
|
211 | + |
|
212 | + $sliced = array_slice($split, 2); |
|
213 | + $relPath = implode('/', $sliced); |
|
214 | + |
|
215 | + return $relPath; |
|
216 | + } |
|
217 | + |
|
218 | + /** |
|
219 | + * check if file name already exists and generate unique target |
|
220 | + * |
|
221 | + * @param string $path |
|
222 | + * @param array $excludeList |
|
223 | + * @param View $view |
|
224 | + * @return string $path |
|
225 | + */ |
|
226 | + public static function generateUniqueTarget($path, $excludeList, $view) { |
|
227 | + $pathinfo = pathinfo($path); |
|
228 | + $ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : ''; |
|
229 | + $name = $pathinfo['filename']; |
|
230 | + $dir = $pathinfo['dirname']; |
|
231 | + $i = 2; |
|
232 | + while ($view->file_exists($path) || in_array($path, $excludeList)) { |
|
233 | + $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); |
|
234 | + $i++; |
|
235 | + } |
|
236 | + |
|
237 | + return $path; |
|
238 | + } |
|
239 | + |
|
240 | + /** |
|
241 | + * get default share folder |
|
242 | + * |
|
243 | + * @param \OC\Files\View |
|
244 | + * @return string |
|
245 | + */ |
|
246 | + public static function getShareFolder($view = null) { |
|
247 | + if ($view === null) { |
|
248 | + $view = Filesystem::getView(); |
|
249 | + } |
|
250 | + $shareFolder = \OC::$server->getConfig()->getSystemValue('share_folder', '/'); |
|
251 | + $shareFolder = Filesystem::normalizePath($shareFolder); |
|
252 | + |
|
253 | + if (!$view->file_exists($shareFolder)) { |
|
254 | + $dir = ''; |
|
255 | + $subdirs = explode('/', $shareFolder); |
|
256 | + foreach ($subdirs as $subdir) { |
|
257 | + $dir = $dir . '/' . $subdir; |
|
258 | + if (!$view->is_dir($dir)) { |
|
259 | + $view->mkdir($dir); |
|
260 | + } |
|
261 | + } |
|
262 | + } |
|
263 | + |
|
264 | + return $shareFolder; |
|
265 | + |
|
266 | + } |
|
267 | + |
|
268 | + /** |
|
269 | + * set default share folder |
|
270 | + * |
|
271 | + * @param string $shareFolder |
|
272 | + */ |
|
273 | + public static function setShareFolder($shareFolder) { |
|
274 | + \OC::$server->getConfig()->setSystemValue('share_folder', $shareFolder); |
|
275 | + } |
|
276 | 276 | |
277 | 277 | } |
@@ -87,7 +87,7 @@ discard block |
||
87 | 87 | |
88 | 88 | $basePath = $path; |
89 | 89 | |
90 | - if ($relativePath !== null && Filesystem::isReadable($basePath . $relativePath)) { |
|
90 | + if ($relativePath !== null && Filesystem::isReadable($basePath.$relativePath)) { |
|
91 | 91 | $path .= Filesystem::normalizePath($relativePath); |
92 | 92 | } |
93 | 93 | |
@@ -112,14 +112,14 @@ discard block |
||
112 | 112 | if ($password !== null) { |
113 | 113 | if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { |
114 | 114 | if ($shareManager->checkPassword($share, $password)) { |
115 | - \OC::$server->getSession()->set('public_link_authenticated', (string)$share->getId()); |
|
115 | + \OC::$server->getSession()->set('public_link_authenticated', (string) $share->getId()); |
|
116 | 116 | return true; |
117 | 117 | } |
118 | 118 | } |
119 | 119 | } else { |
120 | 120 | // not authenticated ? |
121 | 121 | if (\OC::$server->getSession()->exists('public_link_authenticated') |
122 | - && \OC::$server->getSession()->get('public_link_authenticated') !== (string)$share->getId()) { |
|
122 | + && \OC::$server->getSession()->get('public_link_authenticated') !== (string) $share->getId()) { |
|
123 | 123 | return true; |
124 | 124 | } |
125 | 125 | } |
@@ -132,7 +132,7 @@ discard block |
||
132 | 132 | Filesystem::initMountPoints($owner); |
133 | 133 | $info = Filesystem::getFileInfo($target); |
134 | 134 | $ownerView = new View('/'.$owner.'/files'); |
135 | - if ( $owner != User::getUser() ) { |
|
135 | + if ($owner != User::getUser()) { |
|
136 | 136 | $path = $ownerView->getPath($info['fileid']); |
137 | 137 | } else { |
138 | 138 | $path = $target; |
@@ -145,7 +145,7 @@ discard block |
||
145 | 145 | if ($info instanceof \OC\Files\FileInfo) { |
146 | 146 | $ids[] = $info['fileid']; |
147 | 147 | } else { |
148 | - \OCP\Util::writeLog('sharing', 'No fileinfo available for: ' . $path, \OCP\Util::WARN); |
|
148 | + \OCP\Util::writeLog('sharing', 'No fileinfo available for: '.$path, \OCP\Util::WARN); |
|
149 | 149 | } |
150 | 150 | $path = dirname($path); |
151 | 151 | } |
@@ -155,7 +155,7 @@ discard block |
||
155 | 155 | $idList = array_chunk($ids, 99, true); |
156 | 156 | |
157 | 157 | foreach ($idList as $subList) { |
158 | - $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (" . implode(',', $subList) . ") AND `share_type` IN (0, 1, 2)"; |
|
158 | + $statement = "SELECT `share_with`, `share_type`, `file_target` FROM `*PREFIX*share` WHERE `file_source` IN (".implode(',', $subList).") AND `share_type` IN (0, 1, 2)"; |
|
159 | 159 | $query = \OCP\DB::prepare($statement); |
160 | 160 | $r = $query->execute(); |
161 | 161 | $result = array_merge($result, $r->fetchAll()); |
@@ -183,7 +183,7 @@ discard block |
||
183 | 183 | $uid = User::getUser(); |
184 | 184 | } |
185 | 185 | Filesystem::initMountPoints($uid); |
186 | - if ( $uid != User::getUser() ) { |
|
186 | + if ($uid != User::getUser()) { |
|
187 | 187 | $info = Filesystem::getFileInfo($filename); |
188 | 188 | $ownerView = new View('/'.$uid.'/files'); |
189 | 189 | try { |
@@ -230,7 +230,7 @@ discard block |
||
230 | 230 | $dir = $pathinfo['dirname']; |
231 | 231 | $i = 2; |
232 | 232 | while ($view->file_exists($path) || in_array($path, $excludeList)) { |
233 | - $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); |
|
233 | + $path = Filesystem::normalizePath($dir.'/'.$name.' ('.$i.')'.$ext); |
|
234 | 234 | $i++; |
235 | 235 | } |
236 | 236 | |
@@ -254,7 +254,7 @@ discard block |
||
254 | 254 | $dir = ''; |
255 | 255 | $subdirs = explode('/', $shareFolder); |
256 | 256 | foreach ($subdirs as $subdir) { |
257 | - $dir = $dir . '/' . $subdir; |
|
257 | + $dir = $dir.'/'.$subdir; |
|
258 | 258 | if (!$view->is_dir($dir)) { |
259 | 259 | $view->mkdir($dir); |
260 | 260 | } |
@@ -89,6 +89,9 @@ |
||
89 | 89 | $this->user = $user; |
90 | 90 | } |
91 | 91 | |
92 | + /** |
|
93 | + * @param string $tagId |
|
94 | + */ |
|
92 | 95 | function createFile($tagId, $data = null) { |
93 | 96 | try { |
94 | 97 | $tags = $this->tagManager->getTagsByIds([$tagId]); |
@@ -39,169 +39,169 @@ |
||
39 | 39 | */ |
40 | 40 | class SystemTagsObjectMappingCollection implements ICollection { |
41 | 41 | |
42 | - /** |
|
43 | - * @var string |
|
44 | - */ |
|
45 | - private $objectId; |
|
46 | - |
|
47 | - /** |
|
48 | - * @var string |
|
49 | - */ |
|
50 | - private $objectType; |
|
51 | - |
|
52 | - /** |
|
53 | - * @var ISystemTagManager |
|
54 | - */ |
|
55 | - private $tagManager; |
|
56 | - |
|
57 | - /** |
|
58 | - * @var ISystemTagObjectMapper |
|
59 | - */ |
|
60 | - private $tagMapper; |
|
61 | - |
|
62 | - /** |
|
63 | - * User |
|
64 | - * |
|
65 | - * @var IUser |
|
66 | - */ |
|
67 | - private $user; |
|
68 | - |
|
69 | - |
|
70 | - /** |
|
71 | - * Constructor |
|
72 | - * |
|
73 | - * @param string $objectId object id |
|
74 | - * @param string $objectType object type |
|
75 | - * @param IUser $user user |
|
76 | - * @param ISystemTagManager $tagManager tag manager |
|
77 | - * @param ISystemTagObjectMapper $tagMapper tag mapper |
|
78 | - */ |
|
79 | - public function __construct( |
|
80 | - $objectId, |
|
81 | - $objectType, |
|
82 | - IUser $user, |
|
83 | - ISystemTagManager $tagManager, |
|
84 | - ISystemTagObjectMapper $tagMapper |
|
85 | - ) { |
|
86 | - $this->tagManager = $tagManager; |
|
87 | - $this->tagMapper = $tagMapper; |
|
88 | - $this->objectId = $objectId; |
|
89 | - $this->objectType = $objectType; |
|
90 | - $this->user = $user; |
|
91 | - } |
|
92 | - |
|
93 | - function createFile($tagId, $data = null) { |
|
94 | - try { |
|
95 | - $tags = $this->tagManager->getTagsByIds([$tagId]); |
|
96 | - $tag = current($tags); |
|
97 | - if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { |
|
98 | - throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); |
|
99 | - } |
|
100 | - if (!$this->tagManager->canUserAssignTag($tag, $this->user)) { |
|
101 | - throw new Forbidden('No permission to assign tag ' . $tagId); |
|
102 | - } |
|
103 | - |
|
104 | - $this->tagMapper->assignTags($this->objectId, $this->objectType, $tagId); |
|
105 | - } catch (TagNotFoundException $e) { |
|
106 | - throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); |
|
107 | - } |
|
108 | - } |
|
109 | - |
|
110 | - function createDirectory($name) { |
|
111 | - throw new Forbidden('Permission denied to create collections'); |
|
112 | - } |
|
113 | - |
|
114 | - function getChild($tagId) { |
|
115 | - try { |
|
116 | - if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)) { |
|
117 | - $tag = $this->tagManager->getTagsByIds([$tagId]); |
|
118 | - $tag = current($tag); |
|
119 | - if ($this->tagManager->canUserSeeTag($tag, $this->user)) { |
|
120 | - return $this->makeNode($tag); |
|
121 | - } |
|
122 | - } |
|
123 | - throw new NotFound('Tag with id ' . $tagId . ' not present for object ' . $this->objectId); |
|
124 | - } catch (\InvalidArgumentException $e) { |
|
125 | - throw new BadRequest('Invalid tag id', 0, $e); |
|
126 | - } catch (TagNotFoundException $e) { |
|
127 | - throw new NotFound('Tag with id ' . $tagId . ' not found', 0, $e); |
|
128 | - } |
|
129 | - } |
|
130 | - |
|
131 | - function getChildren() { |
|
132 | - $tagIds = current($this->tagMapper->getTagIdsForObjects([$this->objectId], $this->objectType)); |
|
133 | - if (empty($tagIds)) { |
|
134 | - return []; |
|
135 | - } |
|
136 | - $tags = $this->tagManager->getTagsByIds($tagIds); |
|
137 | - |
|
138 | - // filter out non-visible tags |
|
139 | - $tags = array_filter($tags, function($tag) { |
|
140 | - return $this->tagManager->canUserSeeTag($tag, $this->user); |
|
141 | - }); |
|
142 | - |
|
143 | - return array_values(array_map(function($tag) { |
|
144 | - return $this->makeNode($tag); |
|
145 | - }, $tags)); |
|
146 | - } |
|
147 | - |
|
148 | - function childExists($tagId) { |
|
149 | - try { |
|
150 | - $result = ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)); |
|
151 | - |
|
152 | - if ($result) { |
|
153 | - $tags = $this->tagManager->getTagsByIds([$tagId]); |
|
154 | - $tag = current($tags); |
|
155 | - if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { |
|
156 | - return false; |
|
157 | - } |
|
158 | - } |
|
159 | - |
|
160 | - return $result; |
|
161 | - } catch (\InvalidArgumentException $e) { |
|
162 | - throw new BadRequest('Invalid tag id', 0, $e); |
|
163 | - } catch (TagNotFoundException $e) { |
|
164 | - return false; |
|
165 | - } |
|
166 | - } |
|
167 | - |
|
168 | - function delete() { |
|
169 | - throw new Forbidden('Permission denied to delete this collection'); |
|
170 | - } |
|
171 | - |
|
172 | - function getName() { |
|
173 | - return $this->objectId; |
|
174 | - } |
|
175 | - |
|
176 | - function setName($name) { |
|
177 | - throw new Forbidden('Permission denied to rename this collection'); |
|
178 | - } |
|
179 | - |
|
180 | - /** |
|
181 | - * Returns the last modification time, as a unix timestamp |
|
182 | - * |
|
183 | - * @return int |
|
184 | - */ |
|
185 | - function getLastModified() { |
|
186 | - return null; |
|
187 | - } |
|
188 | - |
|
189 | - /** |
|
190 | - * Create a sabre node for the mapping of the |
|
191 | - * given system tag to the collection's object |
|
192 | - * |
|
193 | - * @param ISystemTag $tag |
|
194 | - * |
|
195 | - * @return SystemTagMappingNode |
|
196 | - */ |
|
197 | - private function makeNode(ISystemTag $tag) { |
|
198 | - return new SystemTagMappingNode( |
|
199 | - $tag, |
|
200 | - $this->objectId, |
|
201 | - $this->objectType, |
|
202 | - $this->user, |
|
203 | - $this->tagManager, |
|
204 | - $this->tagMapper |
|
205 | - ); |
|
206 | - } |
|
42 | + /** |
|
43 | + * @var string |
|
44 | + */ |
|
45 | + private $objectId; |
|
46 | + |
|
47 | + /** |
|
48 | + * @var string |
|
49 | + */ |
|
50 | + private $objectType; |
|
51 | + |
|
52 | + /** |
|
53 | + * @var ISystemTagManager |
|
54 | + */ |
|
55 | + private $tagManager; |
|
56 | + |
|
57 | + /** |
|
58 | + * @var ISystemTagObjectMapper |
|
59 | + */ |
|
60 | + private $tagMapper; |
|
61 | + |
|
62 | + /** |
|
63 | + * User |
|
64 | + * |
|
65 | + * @var IUser |
|
66 | + */ |
|
67 | + private $user; |
|
68 | + |
|
69 | + |
|
70 | + /** |
|
71 | + * Constructor |
|
72 | + * |
|
73 | + * @param string $objectId object id |
|
74 | + * @param string $objectType object type |
|
75 | + * @param IUser $user user |
|
76 | + * @param ISystemTagManager $tagManager tag manager |
|
77 | + * @param ISystemTagObjectMapper $tagMapper tag mapper |
|
78 | + */ |
|
79 | + public function __construct( |
|
80 | + $objectId, |
|
81 | + $objectType, |
|
82 | + IUser $user, |
|
83 | + ISystemTagManager $tagManager, |
|
84 | + ISystemTagObjectMapper $tagMapper |
|
85 | + ) { |
|
86 | + $this->tagManager = $tagManager; |
|
87 | + $this->tagMapper = $tagMapper; |
|
88 | + $this->objectId = $objectId; |
|
89 | + $this->objectType = $objectType; |
|
90 | + $this->user = $user; |
|
91 | + } |
|
92 | + |
|
93 | + function createFile($tagId, $data = null) { |
|
94 | + try { |
|
95 | + $tags = $this->tagManager->getTagsByIds([$tagId]); |
|
96 | + $tag = current($tags); |
|
97 | + if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { |
|
98 | + throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); |
|
99 | + } |
|
100 | + if (!$this->tagManager->canUserAssignTag($tag, $this->user)) { |
|
101 | + throw new Forbidden('No permission to assign tag ' . $tagId); |
|
102 | + } |
|
103 | + |
|
104 | + $this->tagMapper->assignTags($this->objectId, $this->objectType, $tagId); |
|
105 | + } catch (TagNotFoundException $e) { |
|
106 | + throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); |
|
107 | + } |
|
108 | + } |
|
109 | + |
|
110 | + function createDirectory($name) { |
|
111 | + throw new Forbidden('Permission denied to create collections'); |
|
112 | + } |
|
113 | + |
|
114 | + function getChild($tagId) { |
|
115 | + try { |
|
116 | + if ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)) { |
|
117 | + $tag = $this->tagManager->getTagsByIds([$tagId]); |
|
118 | + $tag = current($tag); |
|
119 | + if ($this->tagManager->canUserSeeTag($tag, $this->user)) { |
|
120 | + return $this->makeNode($tag); |
|
121 | + } |
|
122 | + } |
|
123 | + throw new NotFound('Tag with id ' . $tagId . ' not present for object ' . $this->objectId); |
|
124 | + } catch (\InvalidArgumentException $e) { |
|
125 | + throw new BadRequest('Invalid tag id', 0, $e); |
|
126 | + } catch (TagNotFoundException $e) { |
|
127 | + throw new NotFound('Tag with id ' . $tagId . ' not found', 0, $e); |
|
128 | + } |
|
129 | + } |
|
130 | + |
|
131 | + function getChildren() { |
|
132 | + $tagIds = current($this->tagMapper->getTagIdsForObjects([$this->objectId], $this->objectType)); |
|
133 | + if (empty($tagIds)) { |
|
134 | + return []; |
|
135 | + } |
|
136 | + $tags = $this->tagManager->getTagsByIds($tagIds); |
|
137 | + |
|
138 | + // filter out non-visible tags |
|
139 | + $tags = array_filter($tags, function($tag) { |
|
140 | + return $this->tagManager->canUserSeeTag($tag, $this->user); |
|
141 | + }); |
|
142 | + |
|
143 | + return array_values(array_map(function($tag) { |
|
144 | + return $this->makeNode($tag); |
|
145 | + }, $tags)); |
|
146 | + } |
|
147 | + |
|
148 | + function childExists($tagId) { |
|
149 | + try { |
|
150 | + $result = ($this->tagMapper->haveTag([$this->objectId], $this->objectType, $tagId, true)); |
|
151 | + |
|
152 | + if ($result) { |
|
153 | + $tags = $this->tagManager->getTagsByIds([$tagId]); |
|
154 | + $tag = current($tags); |
|
155 | + if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { |
|
156 | + return false; |
|
157 | + } |
|
158 | + } |
|
159 | + |
|
160 | + return $result; |
|
161 | + } catch (\InvalidArgumentException $e) { |
|
162 | + throw new BadRequest('Invalid tag id', 0, $e); |
|
163 | + } catch (TagNotFoundException $e) { |
|
164 | + return false; |
|
165 | + } |
|
166 | + } |
|
167 | + |
|
168 | + function delete() { |
|
169 | + throw new Forbidden('Permission denied to delete this collection'); |
|
170 | + } |
|
171 | + |
|
172 | + function getName() { |
|
173 | + return $this->objectId; |
|
174 | + } |
|
175 | + |
|
176 | + function setName($name) { |
|
177 | + throw new Forbidden('Permission denied to rename this collection'); |
|
178 | + } |
|
179 | + |
|
180 | + /** |
|
181 | + * Returns the last modification time, as a unix timestamp |
|
182 | + * |
|
183 | + * @return int |
|
184 | + */ |
|
185 | + function getLastModified() { |
|
186 | + return null; |
|
187 | + } |
|
188 | + |
|
189 | + /** |
|
190 | + * Create a sabre node for the mapping of the |
|
191 | + * given system tag to the collection's object |
|
192 | + * |
|
193 | + * @param ISystemTag $tag |
|
194 | + * |
|
195 | + * @return SystemTagMappingNode |
|
196 | + */ |
|
197 | + private function makeNode(ISystemTag $tag) { |
|
198 | + return new SystemTagMappingNode( |
|
199 | + $tag, |
|
200 | + $this->objectId, |
|
201 | + $this->objectType, |
|
202 | + $this->user, |
|
203 | + $this->tagManager, |
|
204 | + $this->tagMapper |
|
205 | + ); |
|
206 | + } |
|
207 | 207 | } |
@@ -95,15 +95,15 @@ discard block |
||
95 | 95 | $tags = $this->tagManager->getTagsByIds([$tagId]); |
96 | 96 | $tag = current($tags); |
97 | 97 | if (!$this->tagManager->canUserSeeTag($tag, $this->user)) { |
98 | - throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); |
|
98 | + throw new PreconditionFailed('Tag with id '.$tagId.' does not exist, cannot assign'); |
|
99 | 99 | } |
100 | 100 | if (!$this->tagManager->canUserAssignTag($tag, $this->user)) { |
101 | - throw new Forbidden('No permission to assign tag ' . $tagId); |
|
101 | + throw new Forbidden('No permission to assign tag '.$tagId); |
|
102 | 102 | } |
103 | 103 | |
104 | 104 | $this->tagMapper->assignTags($this->objectId, $this->objectType, $tagId); |
105 | 105 | } catch (TagNotFoundException $e) { |
106 | - throw new PreconditionFailed('Tag with id ' . $tagId . ' does not exist, cannot assign'); |
|
106 | + throw new PreconditionFailed('Tag with id '.$tagId.' does not exist, cannot assign'); |
|
107 | 107 | } |
108 | 108 | } |
109 | 109 | |
@@ -120,11 +120,11 @@ discard block |
||
120 | 120 | return $this->makeNode($tag); |
121 | 121 | } |
122 | 122 | } |
123 | - throw new NotFound('Tag with id ' . $tagId . ' not present for object ' . $this->objectId); |
|
123 | + throw new NotFound('Tag with id '.$tagId.' not present for object '.$this->objectId); |
|
124 | 124 | } catch (\InvalidArgumentException $e) { |
125 | 125 | throw new BadRequest('Invalid tag id', 0, $e); |
126 | 126 | } catch (TagNotFoundException $e) { |
127 | - throw new NotFound('Tag with id ' . $tagId . ' not found', 0, $e); |
|
127 | + throw new NotFound('Tag with id '.$tagId.' not found', 0, $e); |
|
128 | 128 | } |
129 | 129 | } |
130 | 130 |