poc 365 changes
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
This commit is contained in:
Родитель
f42df85faf
Коммит
7c7a76e287
|
@ -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, '/');
|
||||
|
|
Загрузка…
Ссылка в новой задаче