diff --git a/composer.json b/composer.json
index 4af4790..113261a 100644
--- a/composer.json
+++ b/composer.json
@@ -11,8 +11,9 @@
}
],
"require": {
- "guzzlehttp/guzzle": "^6.3",
- "symfony/options-resolver": "^3.4"
+ "guzzlehttp/guzzle": "^7.0",
+ "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