Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
This commit is contained in:
Arthur Schiwon 2019-10-14 15:40:04 +02:00
Родитель f42df85faf
Коммит 7c7a76e287
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7424F1874854DF23
4 изменённых файлов: 126 добавлений и 14 удалений

Просмотреть файл

@ -162,6 +162,10 @@ class Client {
public function fetchFolder($relativeServerPath, array $properties = null) {
$this->ensureConnection();
$folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
if(true || $this->isSP2013) {
$allFields = $folder->getListItemAllFields();
$this->context->load($allFields);
}
$this->loadAndExecute($folder, $properties);
if($this->isSP2013 === null
@ -172,6 +176,8 @@ class Client {
\OC::$server->getLogger()->debug('SP 2013 detected against {path}',
['app' => 'sharepoint', 'path' => $relativeServerPath]);
}
$allFields = $folder->getListItemAllFields();
$this->loadAndExecute($allFields);
}
return $folder;
@ -360,7 +366,7 @@ class Client {
$fileCollection = $folder->getFiles();
$this->context->load($folderCollection, self::DEFAULT_PROPERTIES);
$this->context->load($fileCollection, self::DEFAULT_PROPERTIES);
$this->context->load($fileCollection, array_merge(self::DEFAULT_PROPERTIES, [Storage::SP_PROPERTY_URL]));
$this->context->executeQuery();
$collections = ['folders' => $folderCollection, 'files' => $fileCollection];
@ -384,7 +390,7 @@ class Client {
// it's expensive, we only check folders
return false;
}
if($this->isSP2013) {
if(true || $this->isSP2013) {
return in_array(
(string)$file->getProperty(Storage::SP_PROPERTY_NAME),
$this->knownSP2013SystemFolders
@ -443,6 +449,28 @@ class Client {
return $lists->getData();
}
public function getDocumentLibrary(string $documentLibrary):SPList {
static $list = null;
if($list instanceof SPList) {
return $list;
}
$this->ensureConnection();
$title = substr($documentLibrary, strrpos($documentLibrary, '/'));
$lists = $this->context->getWeb()->getLists()->getByTitle(rawurlencode($title));
$this->loadAndExecute($lists);
if($lists instanceof SPList) {
$list = $lists;
$rFolder = $list->getRootFolder();
$this->loadAndExecute($rFolder);
return $list;
}
if($lists->getCount() === 0) {
throw new NotFoundException('No list found');
}
throw new NotFoundException('Too many lists found');
}
/**
* shortcut for querying a provided object from SP
*
@ -470,8 +498,12 @@ class Client {
if(!is_string($this->credentials['password']) || empty($this->credentials['password'])) {
throw new \InvalidArgumentException('No password given');
}
$this->authContext = $this->contextsFactory->getAuthContext($this->credentials['user'], $this->credentials['password']);
$this->authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow…
/*$this->authContext = $this->contextsFactory->getAuthContext($this->credentials['user'], $this->credentials['password']);
$this->authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow…*/
$this->authContext = new AuthenticationContext($this->sharePointUrl);
$this->authContext->acquireTokenForUser($this->credentials['user'], $this->credentials['password']);
$this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext);
# Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand)
}

Просмотреть файл

@ -197,6 +197,9 @@ class Storage extends Common {
public function stat($path) {
$serverUrl = $this->formatPath($path);
try {
if($path === '' || $path === '/') {
return $this->statForDocumentLibrary();
}
$file = $this->getFileOrFolder($serverUrl);
} catch (\Exception $e) {
return false;
@ -204,6 +207,10 @@ class Storage extends Common {
$size = $file->getProperty(self::SP_PROPERTY_SIZE) ?: FileInfo::SPACE_UNKNOWN;
$mtimeValue = (string)$file->getProperty(self::SP_PROPERTY_MTIME);
if($mtimeValue === '') {
// if sp2013 ListItemAllFields are fetched automatically
$mtimeValue = $file->getListItemAllFields()->getProperty('Modified');
}
$name = (string)$file->getProperty(self::SP_PROPERTY_NAME);
if($mtimeValue === '') {
@ -232,6 +239,33 @@ class Storage extends Common {
return false;
}
protected function statForDocumentLibrary() {
try {
$dLib = $this->spClient->getDocumentLibrary($this->documentLibrary);
$mtimeValue = (string)$dLib->getProperty('LastItemModifiedDate');
} catch (NotFoundException $e) {
\OC::$server->getLogger()->logException($e);
return false;
}
if($mtimeValue === '') {
// SP2013 does not provide an mtime.
$timestamp = time();
} else {
$mtime = new \DateTime($mtimeValue);
$timestamp = $mtime->getTimestamp();
error_log('Document Library mtime found ');
}
return [
// int64, size in bytes, excluding the size of any Web Parts that are used in the file.
'size' => FileInfo::SPACE_UNKNOWN,
'mtime' => $timestamp,
// no property in SP 2013 & 2016, other storages do the same
'atime' => time(),
];
}
/**
* see http://php.net/manual/en/function.filetype.php
*
@ -559,7 +593,7 @@ class Storage extends Common {
/** @var File|Folder $item */
$url = $item->getProperty(self::SP_PROPERTY_URL);
if(is_null($url)) {
// at least on SP13 $url is null, although it should not
// at least on SP13 requesting self::SP_PROPERTY_URL against folders causes an exception
continue;
}
$itemEntry = $this->fileCache->get($url);
@ -582,6 +616,9 @@ class Storage extends Common {
* @throws NotFoundException
*/
private function getUserPermissions($serverUrl) {
// temporarily, cf. https://github.com/vgrem/phpSPO/issues/93#issuecomment-489024363
throw new NotFoundException('Could not retrieve permissions');
$item = $this->getFileOrFolder($serverUrl);
$entry = $this->fileCache->get($serverUrl);
if(isset($entry['permissions'])) {
@ -639,7 +676,9 @@ class Storage extends Common {
*/
private function formatPath($path) {
$path = trim($path, '/');
$serverUrl = '/' . $this->documentLibrary;
$docLib = $this->spClient->getDocumentLibrary($this->documentLibrary);
$docLib->getRootFolder()->getProperty('ServerRelativeUrl');
$serverUrl = $docLib->getRootFolder()->getProperty('ServerRelativeUrl');
if($path !== '') {
$serverUrl .= '/' . $path;
}

Просмотреть файл

@ -32,6 +32,7 @@ use Office365\PHP\Client\SharePoint\File;
use Office365\PHP\Client\SharePoint\FileCollection;
use Office365\PHP\Client\SharePoint\Folder;
use Office365\PHP\Client\SharePoint\FolderCollection;
use Office365\PHP\Client\SharePoint\ListItem;
use Office365\PHP\Client\SharePoint\Web;
use Test\TestCase;
@ -101,7 +102,12 @@ class SharePointClientTest extends TestCase {
->method('getAuthContext')
->willReturn($this->createMock(AuthenticationContext::class));
$listItemAllFieldsMock = $this->createMock(ListItem::class);
$folderMock = $this->createMock(Folder::class);
$folderMock->expects($this->any())
->method('getListItemAllFields')
->willReturn($listItemAllFieldsMock);
$webMock = $this->createMock(Web::class);
$webMock->expects($this->never())
@ -115,13 +121,12 @@ class SharePointClientTest extends TestCase {
$clientContextMock->expects($this->once())
->method('getWeb')
->willReturn($webMock);
$clientContextMock->expects($this->once())
->method('load')
->withConsecutive([$folderMock, $properties]);
$clientContextMock->expects($this->once())
$clientContextMock->expects($this->atLeastOnce())
->method('load');
$clientContextMock->expects($this->atLeastOnce())
->method('executeQuery');
$this->contextsFactory->expects($this->once())
$this->contextsFactory->expects($this->atLeastOnce())
->method('getClientContext')
->willReturn($clientContextMock);
@ -312,10 +317,15 @@ class SharePointClientTest extends TestCase {
$itemClass = File::class;
}
$listItemAllFieldsMock = $this->createMock(ListItem::class);
$itemMock = $this->createMock($itemClass);
$itemMock->expects($this->once())
->method($spRenameMethod)
->with($spRenameParameter);
$itemMock->expects($this->any())
->method('getListItemAllFields')
->willReturn($listItemAllFieldsMock);
$this->contextsFactory->expects($this->once())
->method('getAuthContext')
@ -336,7 +346,7 @@ class SharePointClientTest extends TestCase {
->method('getClientContext')
->willReturn($clientContextMock);
$clientContextMock->expects($this->exactly(2))
$clientContextMock->expects($this->atLeast(2))
->method('executeQuery');
$this->client->rename($path, $newPath);

Просмотреть файл

@ -113,8 +113,6 @@ class SharePointTest extends TestCase {
public function pathProvider() {
return [
['/', null],
['', null],
['Paperwork', null],
['Paperwork/', null],
['/Paperwork/', null],
@ -163,6 +161,39 @@ class SharePointTest extends TestCase {
$this->assertTrue($mtime->getTimestamp() < $data['atime']);
}
public function testStatDocumentLibrary() {
$path = '';
$returnSize = null;
$mtime = new \DateTime(null, new \DateTimeZone('Z'));
$mtime->sub(new \DateInterval('P2D'));
// a SP time string looks like: 2017-03-22T16:17:23Z
$returnMTime = $mtime->format('o-m-d\TH:i:se');
$size = FileInfo::SPACE_UNKNOWN;
$dLibMock = $this->createMock(SPList::class);
$dLibMock->expects($this->once())
->method('getProperty')
->with('LastItemModifiedDate')
->willReturn($returnMTime);
$serverPath = '/' . $this->documentLibraryTitle;
if(trim($path, '/') !== '') {
$serverPath .= '/' . trim($path, '/');
}
$this->client->expects($this->once())
->method('getDocumentLibrary')
->with($this->documentLibraryTitle)
->willReturn($dLibMock);
$data = $this->storage->stat($path);
$this->assertSame($mtime->getTimestamp(), $data['mtime']);
$this->assertSame($size, $data['size']);
$this->assertTrue($mtime->getTimestamp() < $data['atime']);
}
public function testStatNotExisting() {
$path = '/foobar/bar.foo';
$serverPath = '/' . $this->documentLibraryTitle . '/' . trim($path, '/');