Last active
July 16, 2019 23:29
-
-
Save roxblnfk/591c944a71e32cc39349a37f64b8d2ed to your computer and use it in GitHub Desktop.
FlySystem/WebDAV wrapper (fix ->readStream() for v1.0.5 https://github.com/thephpleague/flysystem-webdav/tree/1.0.5)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use League\Flysystem\Filesystem; | |
use WebDAVAdapterWrapper; | |
use WebDAVClientWrapper; | |
$client = new WebDAVClientWrapper($settings); | |
$adapter = new WebDAVAdapterWrapper($client); | |
$flysystem = new Filesystem($adapter); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use League\Flysystem\Util; | |
use League\Flysystem\WebDAV\WebDAVAdapter; | |
class WebDAVAdapterWrapper extends WebDAVAdapter | |
{ | |
/** | |
* @var WebDAVClientWrapper | |
*/ | |
protected $client; | |
/** | |
* {@inheritdoc} | |
*/ | |
public function readStream($path) | |
{ | |
$location = $this->applyPathPrefix($this->encodePath($path)); | |
try { | |
$response = $this->client->request('GET', $location); | |
if ($response['statusCode'] !== 200) { | |
return false; | |
} | |
return array_merge([ | |
'stream' => $response['response']->getBodyAsStream(), | |
'timestamp' => strtotime(is_array($response['headers']['last-modified']) | |
? current($response['headers']['last-modified']) | |
: $response['headers']['last-modified']), | |
'path' => $path, | |
], Util::map($response['headers'], static::$resultMap)); | |
} catch (\Exception $e) { | |
return false; | |
} | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function read($path) | |
{ | |
$location = $this->applyPathPrefix($this->encodePath($path)); | |
try { | |
$response = $this->client->request('GET', $location); | |
if ($response['statusCode'] !== 200) { | |
return false; | |
} | |
return array_merge([ | |
'contents' => isset($response['body']) ? $response['body'] : $response['response']->getBodyAsString(), | |
'timestamp' => strtotime(is_array($response['headers']['last-modified']) | |
? current($response['headers']['last-modified']) | |
: $response['headers']['last-modified']), | |
'path' => $path, | |
], Util::map($response['headers'], static::$resultMap)); | |
} catch (\Exception $e) { | |
return false; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Sabre\DAV\Client; | |
use Sabre\HTTP\ClientException; | |
use Sabre\HTTP\ClientHttpException; | |
use Sabre\HTTP\Request; | |
use Sabre\HTTP\RequestInterface; | |
use Sabre\HTTP\Response; | |
use Sabre\HTTP\ResponseInterface; | |
class WebDAVClientWrapper extends Client | |
{ | |
/** | |
* Cached curl handle. | |
* @var resource | |
*/ | |
protected $curlHandle; | |
/** | |
* Performs an actual HTTP request, and returns the result. | |
* | |
* If the specified url is relative, it will be expanded based on the base | |
* url. | |
* | |
* The returned array contains 3 keys: | |
* * response - the response instance | |
* * httpCode - a HTTP code (200, 404, etc) | |
* * headers - a list of response http headers. The header names have | |
* been lowercased. | |
* | |
* For large uploads, it's highly recommended to specify body as a stream | |
* resource. You can easily do this by simply passing the result of | |
* fopen(..., 'r'). | |
* | |
* This method will throw an exception if an HTTP error was received. Any | |
* HTTP status code above 399 is considered an error. | |
* | |
* Note that it is no longer recommended to use this method, use the send() | |
* method instead. | |
* | |
* @param string $method | |
* @param string $url | |
* @param string|resource|null $body | |
* @param array $headers | |
* @return ResponseInterface[]|array | |
* @throws ClientHttpException | |
* @throws ClientException, in case a curl error occurred. | |
*/ | |
function request($method, $url = '', $body = null, array $headers = []) | |
{ | |
$url = $this->getAbsoluteUrl($url); | |
$response = $this->send(new Request($method, $url, $headers, $body)); | |
return [ | |
'response' => $response, | |
// 'body' => $response->getBodyAsString(), | |
'statusCode' => (int)$response->getStatus(), | |
'headers' => array_change_key_case($response->getHeaders()), | |
]; | |
} | |
/** | |
* This method is responsible for performing a single request. | |
* | |
* @param RequestInterface $request | |
* @return ResponseInterface | |
* @throws ClientException | |
*/ | |
protected function doRequest(RequestInterface $request) | |
{ | |
$settings = $this->createCurlSettingsArray($request); | |
$settings[CURLOPT_RETURNTRANSFER] = false; | |
$settings[CURLOPT_HEADER] = false; | |
$headers = ''; | |
$settings[CURLOPT_HEADERFUNCTION] = function ($curl, $str) use (&$headers) { | |
$headers .= $str; | |
return strlen($str); | |
}; | |
$body = ''; | |
if (!key_exists(CURLOPT_NOBODY, $settings) || !$settings[CURLOPT_NOBODY]) { | |
$settings[CURLOPT_FILE] = $body = tmpfile(); | |
} | |
if (!$this->curlHandle) { | |
$this->curlHandle = curl_init(); | |
} | |
curl_setopt_array($this->curlHandle, $settings); | |
$this->curlExec($this->curlHandle); | |
if ($body) | |
rewind($body); | |
$response = $this->parseCurlSeparatedResult($headers, $body, $this->curlHandle); | |
if ($response['status'] === self::STATUS_CURLERROR) { | |
throw new ClientException($response['curl_errmsg'], $response['curl_errno']); | |
} | |
return $response['response']; | |
} | |
/** | |
* @param string $headers | |
* @param resource|string $body | |
* @param resource $curlHandle | |
* @return array | |
*/ | |
protected function parseCurlSeparatedResult($headers, $body, $curlHandle) | |
{ | |
list($curlInfo, $curlErrNo, $curlErrMsg) = $this->curlStuff($curlHandle); | |
if ($curlErrNo) { | |
return [ | |
'status' => self::STATUS_CURLERROR, | |
'curl_errno' => $curlErrNo, | |
'curl_errmsg' => $curlErrMsg, | |
]; | |
} | |
$response = new Response($curlInfo['http_code'], null, $body); | |
$headerBlob = explode("\r\n\r\n", trim($headers, "\r\n")); | |
# We only care about the last set of headers | |
$headerBlob = end($headerBlob); | |
# Splitting headers | |
$headerBlob = explode("\r\n", $headerBlob); | |
foreach ($headerBlob as $header) { | |
$parts = explode(':', $header, 2); | |
if (count($parts) == 2) { | |
$response->addHeader(trim($parts[0]), trim($parts[1])); | |
} | |
} | |
$httpCode = intval($response->getStatus()); | |
return [ | |
'status' => $httpCode >= 400 ? self::STATUS_HTTPERROR : self::STATUS_SUCCESS, | |
'response' => $response, | |
'http_code' => $httpCode, | |
]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Solution for https://github.com/thephpleague/flysystem-webdav/issues/52