From fa607ff5b5158ba38b871966d022adcd9aba13c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Sejkora?= Date: Wed, 22 Jul 2020 13:36:53 +0200 Subject: [PATCH 1/2] [LDAPADMIN-688] Implement File client --- composer.json | 3 +- .../WebDAV/AbstractClient.php | 32 ++++ src/NextcloudApiWrapper/WebDAV/Connection.php | 106 +++++++++++ src/NextcloudApiWrapper/WebDAV/FileClient.php | 169 ++++++++++++++++++ .../WebDAV/XMLTypesEnum.php | 35 ++++ 5 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 src/NextcloudApiWrapper/WebDAV/AbstractClient.php create mode 100644 src/NextcloudApiWrapper/WebDAV/Connection.php create mode 100644 src/NextcloudApiWrapper/WebDAV/FileClient.php create mode 100644 src/NextcloudApiWrapper/WebDAV/XMLTypesEnum.php diff --git a/composer.json b/composer.json index 4af4790..323a83a 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ ], "require": { "guzzlehttp/guzzle": "^6.3", - "symfony/options-resolver": "^3.4" + "symfony/options-resolver": "^3.4", + "ext-simplexml": "*" }, "autoload": { "psr-4": {"NextcloudApiWrapper\\": "src/NextcloudApiWrapper"} diff --git a/src/NextcloudApiWrapper/WebDAV/AbstractClient.php b/src/NextcloudApiWrapper/WebDAV/AbstractClient.php new file mode 100644 index 0000000..e898a68 --- /dev/null +++ b/src/NextcloudApiWrapper/WebDAV/AbstractClient.php @@ -0,0 +1,32 @@ +preserveWhiteSpace = false; + $xmlDocument->formatOutput = true; + $xmlDocument->loadXML($simpleXMLElement->asXML()); + return $xmlDocument->saveXML(); + } +} \ No newline at end of file diff --git a/src/NextcloudApiWrapper/WebDAV/Connection.php b/src/NextcloudApiWrapper/WebDAV/Connection.php new file mode 100644 index 0000000..eb6d528 --- /dev/null +++ b/src/NextcloudApiWrapper/WebDAV/Connection.php @@ -0,0 +1,106 @@ +request($method, $uri, null, $xml, $headers); + } + + /** + * @param $method + * @param $uri + * @param null $params + * @param null $data + * @param array $headers + * @return bool + * @throws NCException + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function noBodyRequest($method, $uri, $params = null, $data = null, $headers = []) { + + $response = $this->rawRequest($method, $uri, $params, $data, $headers); + switch ($response->getStatusCode()) { + default: + throw new NCException($response); + case 201: + case 202: + case 204: + return true; + } + } + + /** + * @param $method + * @param $uri + * @param null $params + * @param null $data + * @param array $headers + * @return NextcloudResponse + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \NextcloudApiWrapper\NCException + */ + public function request($method, $uri, $params = null, $data = null, $headers = []) { + + $response = $this->rawRequest($method, $uri, $params, $data, $headers); + + return new NextcloudResponse($response); + } + + /** + * @param $method + * @param $uri + * @param null $params + * @param null $data + * @param array $headers + * @return ResponseInterface + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function rawRequest($method, $uri, $params = null, $data = null, $headers = []) { + + $params = $params === null ? $this->getBaseRequestParams() : $params; + $request = new Request($method, $uri, $headers, $data); + return $this->guzzle->send($request, $params); + } +} \ No newline at end of file diff --git a/src/NextcloudApiWrapper/WebDAV/FileClient.php b/src/NextcloudApiWrapper/WebDAV/FileClient.php new file mode 100644 index 0000000..9c7bcaf --- /dev/null +++ b/src/NextcloudApiWrapper/WebDAV/FileClient.php @@ -0,0 +1,169 @@ +connection->request(Connection::PROFIND, self::FILE_PART . '/' . $pathToFolder); + } + $xml = new SimpleXMLElement(' + + '); + + $xmlProp = $xml->addChild("d:prop"); + foreach ($params as $param) { + if (key_exists($param, XMLTypesEnum::FOLDER_PARAMS_TO_XML_TYPE)) { + $xmlProp->addChild(XMLTypesEnum::FOLDER_PARAMS_TO_XML_TYPE[$param]); + } + } + + $header = $resursive === false ? ["Depth" => 0] : []; + + return $this->connection->xmlRequest(Connection::PROFIND, self::FILE_PART . '/' . $pathToFolder, $xml->asXML(), $header); + } + + /** + * @param $pathToFile + * @return \Psr\Http\Message\ResponseInterface + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function downloadFile($pathToFile) { + return $this->connection->rawRequest(Connection::GET, $pathToFile); + } + + /** + * @param $pathToFile + * @param $fileContent + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \NextcloudApiWrapper\NCException + */ + public function uploadFile($pathToFile, $fileContent) { + $this->connection->noBodyRequest(Connection::PUT, $pathToFile, null, $fileContent); + } + + /** + * @param $pathToFolder + * @return bool + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \NextcloudApiWrapper\NCException + */ + public function createFolder($pathToFolder) { + + $this->connection->noBodyRequest(Connection::MKCOL, self::FILE_PART . '/' . $pathToFolder); + } + + /** + * @param $pathToFolder + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \NextcloudApiWrapper\NCException + */ + public function deleteFolder($pathToFolder) { + + $this->connection->noBodyRequest(Connection::DELETE, self::FILE_PART . '/' . $pathToFolder); + } + + /** + * @param $sourcePath + * @param $destinationPath + * @param null $name - use when you do not want to rename file or folder + * - when not null it append after sourcePath and also destinationPath + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \NextcloudApiWrapper\NCException + */ + public function move($sourcePath, $destinationPath, $name = null) { + + if ($name !== null) { + $sourcePath .= "/" . $name; + $destinationPath .= "/" . $name; + } + $this->connection->noBodyRequest(Connection::MOVE, self::FILE_PART . '/' . $sourcePath, null, null, ["Destination" => $destinationPath]); + } + + /** + * @param $sourcePath + * @param $destinationPath + * @param null $name - use when you do not want to rename file or folder + * - when not null it append after sourcePath and also destinationPath + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \NextcloudApiWrapper\NCException + */ + public function copy($sourcePath, $destinationPath, $name = null) { + + if ($name !== null) { + $sourcePath .= "/" . $name; + $destinationPath .= "/" . $name; + } + $this->connection->noBodyRequest(Connection::COPY, self::FILE_PART . '/' . $sourcePath, null, null, ["Destination" => $destinationPath]); + } + + /** + * @param $path + * @param array $params + * @return NextcloudResponse + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \NextcloudApiWrapper\NCException + */ + public function favourite($path, $params = []) { + $xml = new SimpleXMLElement(' + + '); + + $xmlProp = $xml->addChild("d:set")->addChild("d:prop"); + foreach ($params as $key=>$value) { + if (key_exists($key, XMLTypesEnum::FAVOURITE_PARAMS_TO_XML_TYPE)) { + if (is_bool($value)) { + $value = $value ? 1 : 0; + } + $xmlProp->addChild(XMLTypesEnum::FAVOURITE_PARAMS_TO_XML_TYPE[$key], $value); + } + } + + return $this->connection->xmlRequest(Connection::PROFIND, self::FILE_PART . '/' . $path, $xml->asXML()); + } + + /** + * @param $path + * @param array $params + * @return NextcloudResponse + * @throws \GuzzleHttp\Exception\GuzzleException + * @throws \NextcloudApiWrapper\NCException + */ + public function filter($path, $params = []) { + $xml = new SimpleXMLElement(' + + '); + + $xmlFilterRules = $xml->addChild("oc:filter-rules"); + foreach ($params as $key=>$value) { + if (key_exists($key, XMLTypesEnum::FAVOURITE_PARAMS_TO_XML_TYPE)) { + if (is_bool($value)) { + $value = $value ? 1 : 0; + } + $xmlFilterRules->addChild(XMLTypesEnum::FAVOURITE_PARAMS_TO_XML_TYPE[$key], $value); + } else if (key_exists($key, XMLTypesEnum::FOLDER_PARAMS_TO_XML_TYPE)) { + if (is_bool($value)) { + $value = $value ? 1 : 0; + } + $xmlFilterRules->addChild(XMLTypesEnum::FOLDER_PARAMS_TO_XML_TYPE[$key], $value); + } + } + + return $this->connection->xmlRequest(Connection::PROFIND, self::FILE_PART . '/' . $path, $xml->asXML()); + } + +} \ No newline at end of file diff --git a/src/NextcloudApiWrapper/WebDAV/XMLTypesEnum.php b/src/NextcloudApiWrapper/WebDAV/XMLTypesEnum.php new file mode 100644 index 0000000..87bf8e1 --- /dev/null +++ b/src/NextcloudApiWrapper/WebDAV/XMLTypesEnum.php @@ -0,0 +1,35 @@ + "d:getlastmodified", + "getetag" => "d:getetag", + "getcontenttype" => "d:getcontenttype", + "resourcetype" => "d:resourcetype", + "getcontentlength" => "d:getcontentlength", + "id" => "oc:id", // The fileid namespaced by the instance id, globally unique + "fileid" => "oc:fileid", // fileid The unique id for the file within the instance + "favorite" => "oc:favorite", + "comments-href" => "oc:comments-href", + "comments-count" => "oc:comments-count", + "comments-unread" => "oc:comments-unread", + "owner-id" => "oc:owner-id", // The user id of the owner of a shared file + "owner-display-name" => "oc:owner-display-name", // The display name of the owner of a shared file + "share-types" => "oc:share-types", + "checksums" => "oc:checksums", + "has-preview" => "ns:has-preview", + "size" => "oc:size", // Unlike getcontentlength, this property also works for folders reporting the size of everything in the folder. + ]; + + const FAVOURITE_PARAMS_TO_XML_TYPE = [ + "favorite" => "oc:favourite", + ]; +} \ No newline at end of file From afe06b17c0c2ea92b307a6f2b38ec187d4aa93ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Sejkora?= Date: Thu, 23 Jul 2020 12:03:45 +0200 Subject: [PATCH 2/2] [LDAPADMIN-688] Update guzzle requirement --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 323a83a..113261a 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ } ], "require": { - "guzzlehttp/guzzle": "^6.3", + "guzzlehttp/guzzle": "^7.0", "symfony/options-resolver": "^3.4", "ext-simplexml": "*" },