diff --git a/README.md b/README.md index 29133bf..704e012 100644 --- a/README.md +++ b/README.md @@ -339,7 +339,7 @@ $client = new Client( | Resource | Support grade | | ---------------------- | ------------- | | Account | :large_blue_circle::large_blue_circle::large_blue_circle::white_circle: | -| Starred Files | :white_circle::white_circle::white_circle::white_circle: | +| Starred Files | :large_blue_circle::large_blue_circle::large_blue_circle::large_blue_circle: | | Group | :large_blue_circle::white_circle::white_circle::white_circle: | | File Share Link | :large_blue_circle::large_blue_circle::white_circle::white_circle: | | Library/Library | :large_blue_circle::large_blue_circle::white_circle::white_circle: | @@ -347,8 +347,8 @@ $client = new Client( | Library/Directory | :large_blue_circle::large_blue_circle::white_circle::white_circle: | | Library/Multiple Files | :large_blue_circle::large_blue_circle::large_blue_circle::large_blue_circle: | | Avatar | :large_blue_circle::large_blue_circle::large_blue_circle::large_blue_circle: | -| Events | :white_circle::white_circle::white_circle::white_circle: | -| Organization | :white_circle::white_circle::white_circle::white_circle: | +| Events | not planned | +| Organization | not planned | ## Seafile server compatibility diff --git a/bin/examples/starred_file.php b/bin/examples/starred_file.php new file mode 100755 index 0000000..738c0e8 --- /dev/null +++ b/bin/examples/starred_file.php @@ -0,0 +1,103 @@ +push( + Middleware::log( + $logger, + new MessageFormatter("{hostname} {req_header_Authorization} - {req_header_User-Agent} - [{date_common_log}] \"{method} {host}{target} HTTP/{version}\" {code} {res_header_Content-Length} req_body: {req_body} response_body: {res_body}") + ) +); + +/** + * Example: + * {"token": "your_token"} + */ +$tokenFile = getenv("HOME") . "/.seafile-php-sdk/api-token.json"; + +/** + * Example: + * { + * "baseUri": "https://your.seafile-server.example.com", + * "testLibId": "ID of an encrypted library", + * "testLibPassword": "Password of that encrypted library" + * } + */ +$cfgFile = getenv("HOME") . "/.seafile-php-sdk/cfg.json"; + +if (!is_readable($tokenFile)) { + throw new Exception($tokenFile . ' is not readable or does not exist.'); +} + +if (!is_readable($cfgFile)) { + throw new Exception($cfgFile . ' is not readable or does not exist.'); +} + +$token = json_decode(file_get_contents($tokenFile)); +$cfg = json_decode(file_get_contents($cfgFile)); + +$client = new Client( + [ + 'base_uri' => $cfg->baseUri, + 'debug' => true, + 'handler' => $stack, + 'headers' => [ + 'Content-Type' => 'application/json', + 'Authorization' => 'Token ' . $token->token + ] + ] +); + +$libraryResource = new Library($client); +$directoryResource = new Directory($client); +$fileResource = new File($client); +$starredFileResource = new StarredFile($client); + +// get all starred files +$logger->log(Logger::INFO, "#################### Getting all starred files"); +$dirItems = $starredFileResource->getAll(); + +if (!empty($dirItems)) { + foreach ($dirItems as $dirItem) { + var_dump($dirItem); + } + + $logger->log(Logger::INFO, "#################### Unstarring files..."); + + foreach ($dirItems as $dirItem) { + $lib = $libraryResource->getById($dirItem->repo); + $starredFileResource->unstar($lib, $dirItem); + } + + $logger->log(Logger::INFO, "#################### Sleeping 10s before starring them again..."); + sleep(10); + + foreach ($dirItems as $dirItem) { + $lib = $libraryResource->getById($dirItem->repo); + $starredFileResource->star($lib, $dirItem); + } +} else { + $logger->log(Logger::DEBUG, "#################### No starred files found."); +} + +print(PHP_EOL . 'Done' . PHP_EOL); diff --git a/lib/Resource/StarredFile.php b/lib/Resource/StarredFile.php new file mode 100644 index 0000000..592f3a2 --- /dev/null +++ b/lib/Resource/StarredFile.php @@ -0,0 +1,124 @@ + + * @copyright 2015 Rene Schmidt DevOps UG (haftungsbeschränkt) & Co. KG + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/rene-s/seafile-php-sdk + */ +class StarredFile extends AbstractResource +{ + /** + * @var string + */ + protected $resourceUri = ''; + + /** + * Constructor + * + * @param Client $client Client instance + */ + public function __construct(Client $client) + { + parent::__construct($client); + + $this->resourceUri = $this->clipUri($client->getConfig('base_uri')) . '/starredfiles/'; + } + + /** + * Get all starred files + * + * @return DirectoryItem[] + */ + public function getAll() + { + $response = $this->client->request('GET', $this->resourceUri); + + $json = json_decode((string)$response->getBody()); + + $dirItemCollection = []; + + foreach ($json as $starredFile) { + $dirItemCollection[] = (new DirectoryItem)->fromJson($starredFile); + } + + return $dirItemCollection; + } + + /** + * Create directory within $parentDir + * + * @param LibraryType $library Library instance + * @param DirectoryItem $dirItem DirectoryItem instance to star + * + * @return string URL of starred file list + * @throws \Exception + */ + public function star(LibraryType $library, DirectoryItem $dirItem) + { + if ($dirItem->type !== 'file') { + throw new \Exception('Cannot star other items than files.'); + } + + $response = $this->client->request( + 'POST', + $this->resourceUri, + [ + 'headers' => ['Accept' => 'application/json'], + 'multipart' => [ + [ + 'name' => 'repo_id', + 'contents' => $library->id + ], + [ + 'name' => 'p', + 'contents' => $dirItem->path + ] + ], + ] + ); + + if ($response->getStatusCode() !== 201 || $response->hasHeader('Location') === false) { + throw new \Exception('Could not star file'); + } + + return $response->getHeader('Location')[0]; + } + + /** + * Unstar a file + * + * @param LibraryType $library Library instance + * @param DirectoryItem $dirItem DirectoryItem instance + * + * @return bool + */ + public function unstar(LibraryType $library, DirectoryItem $dirItem) + { + $uri = sprintf( + '%s/?repo_id=%s&p=%s', + $this->resourceUri, + $library->id, + $dirItem->path + ); + + $response = $this->client->request('DELETE', $uri); + + return $response->getStatusCode() === 200; + } +} diff --git a/lib/Type/DirectoryItem.php b/lib/Type/DirectoryItem.php index 36ce76b..cc825f2 100644 --- a/lib/Type/DirectoryItem.php +++ b/lib/Type/DirectoryItem.php @@ -5,7 +5,7 @@ use DateTime; /** - * Directory type class + * Directory Item class. * * PHP version 5 * @@ -24,22 +24,63 @@ class DirectoryItem extends AbstractType public $id = ""; /** - * @var string + * @var bool */ - public $size = ""; + public $dir = null; + + /** + * @var DateTime + */ + public $mtime; /** * @var string */ public $name = ""; + /** + * @var int + */ + public $org = null; + + /** + * @var string + */ + public $path = null; + + /** + * @var string + */ + public $repo = null; + + /** + * @var string + */ + public $size = ""; + /** * @var string */ public $type = ""; /** - * @var DateTime + * Populate from array + * + * @param array $fromArray Create from array + * + * @return static */ - public $mtime; + public function fromArray(array $fromArray) + { + $typeExists = array_key_exists('type', $fromArray); + $dirExists = array_key_exists('dir', $fromArray); + + if ($typeExists === false && $dirExists === true && is_bool($fromArray['dir'])) { + $fromArray['type'] = $fromArray['dir'] === true ? 'dir' : 'file'; + } + + $array = parent::fromArray($fromArray); + + return $array; + } } diff --git a/test/assets/StarredFileTest_getAll.json b/test/assets/StarredFileTest_getAll.json new file mode 100644 index 0000000..e42240c --- /dev/null +++ b/test/assets/StarredFileTest_getAll.json @@ -0,0 +1,16 @@ +[ + { + "file_name": "seafile-tutorial.doc", + "icon_path": "word.png", + "oid": "eeeab96740ef53249b9d21fb3fa28050842266aa", + "mtime_relative": "", + "repo": "eeece753-3a16-4c46-91f7-ee1b013ad17e", + "org": -1, + "path": "/seafile-tutorial.doc", + "size": 300544, + "repo_id": "eeece753-3a16-4c46-91f7-ee1b013ad17e", + "mtime": 1451074804, + "dir": false, + "repo_name": "My Library" + } +] \ No newline at end of file diff --git a/test/unit/Resource/StarredFileTest.php b/test/unit/Resource/StarredFileTest.php new file mode 100644 index 0000000..9b9a6f3 --- /dev/null +++ b/test/unit/Resource/StarredFileTest.php @@ -0,0 +1,139 @@ + + * @copyright 2015 Rene Schmidt DevOps UG (haftungsbeschränkt) & Co. KG + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/rene-s/seafile-php-sdk + */ +class StarredFileTest extends TestCase +{ + + /** + * Test getAll() + * + * @return void + */ + public function testGetAll() + { + $starredFileResource = new StarredFile($this->getMockedClient( + new Response( + 200, + ['Content-Type' => 'application/json'], + file_get_contents(__DIR__ . '/../../assets/StarredFileTest_getAll.json') + ) + )); + + $this->assertAttributeNotEmpty('resourceUri', $starredFileResource); + + $starredDirItems = $starredFileResource->getAll(); + + $this->assertInternalType('array', $starredDirItems); + + foreach ($starredDirItems as $starredDirItem) { + $this->assertInstanceOf('Seafile\Client\Type\DirectoryItem', $starredDirItem); + } + } + + /** + * Test star() with wrong DirItem type + * + * @return void + * @throws \Exception + */ + public function testStarWrongType() + { + $starredFileResource = new StarredFile($this->getMockedClient(new Response())); + + $this->setExpectedException('Exception', 'Cannot star other items than files.'); + + $starredFileResource->star(new LibraryType(), new DirectoryItem()); + } + + /** + * Test star() + * + * @return void + * @throws \Exception + */ + public function testStar() + { + $lib = new LibraryType(); + $lib->id = 123; + + $dirItem = new DirectoryItem(); + $dirItem->type = 'file'; + $dirItem->path = '/some/path'; + + $responseUrl = 'https://example.com/test/'; + + $starResponse = new Response( + 201, + [ + 'Accept' => 'application/json', + 'Location' => $responseUrl + ] + ); + + $mockedClient = $this->getMockBuilder('\Seafile\Client\Http\Client')->getMock(); + + $mockedClient->expects($this->any()) + ->method('getConfig') + ->with('base_uri') + ->willReturn($responseUrl); + + $mockedClient->expects($this->any()) + ->method('request') + ->with( + $this->equalTo('POST') + ) + // Return what was passed to offsetGet as a new instance + ->will($this->returnCallback( + function ($method, $uri, $params) use ($starResponse, $lib, $dirItem) { + + $hasParams = array_key_exists('headers', $params) + && array_key_exists('multipart', $params) + && array_key_exists('name', $params['multipart'][0]) + && array_key_exists('contents', $params['multipart'][0]) + && array_key_exists('name', $params['multipart'][1]) + && array_key_exists('contents', $params['multipart'][1]); + + $hasContents = $params['multipart'][0]['contents'] === $lib->id + && $params['multipart'][1]['contents'] === $dirItem->path; + + if ($hasParams + && $hasContents + && $method === 'POST' + && $uri === 'https://example.com/test/starredfiles/' + ) { + return $starResponse; + } + + return new Response(500); + } + )); + + + /** @var Client $mockedClient */ + $starredFileResource = new StarredFile($mockedClient); + + $result = $starredFileResource->star($lib, $dirItem); + + $this->assertSame($responseUrl, $result); + } +} diff --git a/test/unit/Type/AbstractTypeTest.php b/test/unit/Type/AbstractTypeTest.php index 822e521..965309e 100644 --- a/test/unit/Type/AbstractTypeTest.php +++ b/test/unit/Type/AbstractTypeTest.php @@ -62,7 +62,11 @@ public function testFromArrayPropertyMissing() 'size' => 2, 'name' => 'my name', 'type' => 'my type', - 'mtime' => null + 'mtime' => null, + 'dir' => null, + 'org' => null, + 'path' => null, + 'repo' => null ], (array)$dirItem ); diff --git a/test/unit/Type/DirectoryItemTest.php b/test/unit/Type/DirectoryItemTest.php new file mode 100644 index 0000000..4d3766a --- /dev/null +++ b/test/unit/Type/DirectoryItemTest.php @@ -0,0 +1,59 @@ + + * @copyright 2015 Rene Schmidt DevOps UG (haftungsbeschränkt) & Co. KG + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/rene-s/seafile-php-sdk + */ +class DirectoryItemTest extends \PHPUnit_Framework_TestCase +{ + + /** + * DataProvider for testFromArray() + * + * @return array + */ + public function dataFromArray() + { + return [ + // [[expect response code, expected result, password]] + [[ + 'dir' => true, + 'type' => 'dir' + ]], + [[ + 'dir' => false, + 'type' => 'file' + ]], + ]; + } + + /** + * Test fromArray() + * + * @param array $data Dataprovider array + * + * @return void + * @dataProvider dataFromArray + */ + public function testFromArray(array $data) + { + $dirItem = new DirectoryItem([ + 'dir' => $data['dir'] + ]); + + $this->assertSame($data['dir'], $dirItem->dir); + $this->assertSame($data['type'], $dirItem->type); + } +}