diff --git a/lib/classes/API/V1/adapter.class.php b/lib/classes/API/V1/adapter.class.php index cc5a27cb07..bfbcc930d6 100644 --- a/lib/classes/API/V1/adapter.class.php +++ b/lib/classes/API/V1/adapter.class.php @@ -264,7 +264,7 @@ class API_V1_adapter extends API_V1_Abstract if ($opCodeCache instanceof \Alchemy\Phrasea\Cache\Cache) { $ret['cache']['op_code'] = array( - 'type' => $mainCache->getName(), + 'type' => $opCodeCache->getName(), 'stats' => $opCodeCache->getStats() ); } else { @@ -695,12 +695,11 @@ class API_V1_adapter extends API_V1_Abstract if ($output instanceof \record_adapter) { $ret['entity'] = '0'; - $ret['record'] = $this->list_record($output); + $ret['url'] = '/records/' . $output->get_sbas_id() . '/' . $output->get_record_id() . '/'; } if ($output instanceof \Entities\LazaretFile) { $ret['entity'] = '1'; - $ret['reasons'] = $behavior === BorderManager::FORCE_LAZARET ? array() : $reasons; - $ret['lazaretFile'] = $this->list_lazaret_file($output); + $ret['url'] = '/quarantine/item/' . $output->getId() . '/'; } $result = new API_V1_result($request, $this); @@ -710,6 +709,65 @@ class API_V1_adapter extends API_V1_Abstract return $result; } + public function list_quarantine(Application $app, Request $request) + { + $offset_start = max($request->get('offset_start', 0), 0); + $per_page = min(max($request->get('per_page', 10), 1), 20); + + $em = $app['Core']->getEntityManager(); + $user = $app['Core']->getAuthenticatedUser(); + /* @var $user \User_Adapter */ + $baseIds = array_keys($user->ACL()->get_granted_base(array('canaddrecord'))); + + $lazaretFiles = array(); + + if (count($baseIds) > 0) { + $lazaretRepository = $em->getRepository('Entities\LazaretFile'); + + $lazaretFiles = $lazaretRepository->findPerPage( + $baseIds, $offset_start, $per_page + ); + } + + $ret = array(); + + foreach ($lazaretFiles as $lazaretFile) { + $ret[] = $this->list_lazaret_file($lazaretFile); + } + + $result = new API_V1_result($request, $this); + + $result->set_datas(array( + 'offset_start' => $offset_start, + 'per_page' => $per_page, + 'items' => $ret, + )); + + return $result; + } + + public function list_quarantine_item($lazaret_id, Application $app, Request $request) + { + $lazaretFile = $app['Core']['EM']->find('Entities\LazaretFile', $lazaret_id); + + /* @var $lazaretFile \Entities\LazaretFile */ + if (null === $lazaretFile) { + throw new \API_V1_exception_notfound(sprintf('Lazaret file id %d not found', $lazaret_id)); + } + + if ( ! $app['Core']->getAuthenticatedUser()->ACL()->has_right_on_base($lazaretFile->getBaseId(), 'canaddrecord')) { + throw new \API_V1_exception_forbidden('You do not have access to this quarantine item'); + } + + $ret = array('item' => $this->list_lazaret_file($lazaretFile)); + + $result = new API_V1_result($request, $this); + + $result->set_datas($ret); + + return $result; + } + protected function list_lazaret_file(\Entities\LazaretFile $file) { $checks = array(); @@ -1278,7 +1336,7 @@ class API_V1_adapter extends API_V1_Abstract $choices[$user->get_id()] = array( 'usr_id' => $user->get_id(), 'usr_name' => $user->get_display_name(), - 'is_mine' => $user->get_id() == $this->core->getAuthenticatedUser()->get_id(), + 'readonly' => $user->get_id() != $this->core->getAuthenticatedUser()->get_id(), 'agreement' => $validation_datas->getAgreement(), 'updated_on' => $validation_datas->getUpdated()->format(DATE_ATOM), 'note' => $validation_datas->getNote(), @@ -1447,10 +1505,10 @@ class API_V1_adapter extends API_V1_Abstract $per_page = (($per_page >= 1) && ($per_page <= 20)) ? $per_page : 5; $datas = array( - 'feed' => $this->list_aggregate_publications($feed, $user), - 'offset_start' => $offset_start, - 'per_page' => $per_page, - 'entries' => $this->list_publications_entries($feed, $offset_start, $per_page), + 'total_entries' => $feed->get_count_total_entries(), + 'offset_start' => $offset_start, + 'per_page' => $per_page, + 'entries' => $this->list_publications_entries($feed, $offset_start, $per_page), ); $result->set_datas($datas); @@ -1495,19 +1553,13 @@ class API_V1_adapter extends API_V1_Abstract 'total_entries' => $feed->get_count_total_entries(), 'icon' => $feed->get_icon_url(), 'public' => $feed->is_public(), - 'is_mine' => $feed->is_owner($user), + 'readonly' => ! $feed->is_publisher($user), + 'deletable' => $feed->is_owner($user), 'created_on' => $feed->get_created_on()->format(DATE_ATOM), 'updated_on' => $feed->get_updated_on()->format(DATE_ATOM), ); } - protected function list_aggregate_publications(Feed_Aggregate $feed, $user) - { - return array( - 'total_entries' => $feed->get_count_total_entries(), - ); - } - /** * Retrieve all entries of one feed * diff --git a/tests/Alchemy/Phrasea/Application/ApiAbstract.inc b/tests/Alchemy/Phrasea/Application/ApiAbstract.inc index ccceb4b01b..cfdd3b9f95 100644 --- a/tests/Alchemy/Phrasea/Application/ApiAbstract.inc +++ b/tests/Alchemy/Phrasea/Application/ApiAbstract.inc @@ -608,7 +608,7 @@ abstract class ApiAbstract extends \PhraseanetWebTestCaseAbstract $ref_structure->get_element('idbarbouze'); $this->fail('An expected exception has not been raised.'); } catch (\Exception_Databox_FieldNotFound $e) { - + } $route = '/databoxes/' . $databox_id . '/metadatas/'; @@ -1567,7 +1567,7 @@ abstract class ApiAbstract extends \PhraseanetWebTestCaseAbstract $this->evaluateMeta200($content); - $this->assertArrayHasKey('feed', $content['response']); + $this->assertArrayHasKey('total_entries', $content['response']); $this->assertArrayHasKey('offset_start', $content['response']); $this->assertArrayHasKey('per_page', $content['response']); $this->assertArrayHasKey('entries', $content['response']); @@ -1727,6 +1727,99 @@ abstract class ApiAbstract extends \PhraseanetWebTestCaseAbstract } } + /** + * @covers list_lazaret_file + * @covers list_quarantine + * @covers list_quarantine_item + */ + public function testQuarantineList() + { + $this->setToken(self::$token); + $route = '/quarantine/list/'; + + $quarantineItemId = $this->getQuarantineItem()->getId(); + + $this->evaluateMethodNotAllowedRoute($route, array('POST', 'PUT', 'DELETE')); + + $this->client->request('GET', $route, array(), array(), array('HTTP_Accept' => $this->getAcceptMimeType())); + $content = $this->unserialize($this->client->getResponse()->getContent()); + + $this->assertArrayHasKey('offset_start', $content['response']); + $this->assertArrayHasKey('per_page', $content['response']); + $this->assertArrayHasKey('items', $content['response']); + + $found = false; + foreach ($content['response']['items'] as $item) { + $this->evaluateGoodQuarantineItem($item); + if ($item['id'] == $quarantineItemId) { + $found = true; + } + } + + if ( ! $found) { + $this->fail('should find the quarantine item'); + } + } + + /** + * @covers list_lazaret_file + * @covers list_quarantine_item + */ + public function testQuarantineContent() + { + $this->setToken(self::$token); + + $quarantineItemId = $this->getQuarantineItem()->getId(); + $route = '/quarantine/item/' . $quarantineItemId . '/'; + + $this->evaluateMethodNotAllowedRoute($route, array('POST', 'PUT', 'DELETE')); + + $this->client->request('GET', $route, array(), array(), array('HTTP_Accept' => $this->getAcceptMimeType())); + $content = $this->unserialize($this->client->getResponse()->getContent()); + + $this->assertArrayHasKey('item', $content['response']); + + $this->evaluateGoodQuarantineItem($content['response']['item']); + $this->assertEquals($quarantineItemId, $content['response']['item']['id']); + } + + protected function getQuarantineItem() + { + $lazaretSession = new \Entities\LazaretSession(); + self::$core['EM']->persist($lazaretSession); + + $quarantineItem; + $callback = function ($element, $visa, $code) use (&$quarantineItem) { + $quarantineItem = $element; + }; + + $tmpname = tempnam(sys_get_temp_dir(), 'test_quarantine'); + copy(__DIR__ . '/../../../testfiles/iphone_pic.jpg', $tmpname); + + $file = \Alchemy\Phrasea\Border\File::buildFromPathfile($tmpname, self::$collection); + self::$core['border-manager']->process($lazaretSession, $file, $callback, \Alchemy\Phrasea\Border\Manager::FORCE_LAZARET); + + return $quarantineItem; + } + + protected function evaluateGoodQuarantineItem($item) + { + $this->assertArrayHasKey('id', $item); + $this->assertArrayHasKey('session', $item); + $this->assertArrayHasKey('base_id', $item); + $this->assertArrayHasKey('original_name', $item); + $this->assertArrayHasKey('sha256', $item); + $this->assertArrayHasKey('uuid', $item); + $this->assertArrayHasKey('forced', $item); + $this->assertArrayHasKey('checks', $item); + $this->assertArrayHasKey('created_on', $item); + $this->assertArrayHasKey('updated_on', $item); + + $this->assertInternalType('boolean', $item['forced']); + $this->assertDateAtom($item['updated_on']); + $this->assertDateAtom($item['created_on']); + } + protected function evaluateGoodFeed($feed) { $this->assertArrayHasKey('id', $feed);