diff --git a/.travis.yml b/.travis.yml index e12efbf..8bcd2c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ jobs: - stage: "Tests" name: "Unit Tests" script: vendor/bin/phpunit -c . --coverage-clover build/logs/clover.xml - - script: vendor/bin/phpstan analyse src/ --level 6 --no-progress + - script: vendor/bin/phpstan analyse src/ --level 5 --no-progress name: "Static Analyser" before_script: diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..27153d5 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,3 @@ +parameters: + ignoreErrors: + - '#Unsafe usage of new static().#' diff --git a/src/Client/BasicAuthClient.php b/src/Client/BasicAuthClient.php index f778486..9e8eb36 100644 --- a/src/Client/BasicAuthClient.php +++ b/src/Client/BasicAuthClient.php @@ -40,6 +40,7 @@ class BasicAuthClient implements ClientInterface * @param Headers $headers * @param CacheInterface|null $cache * @param string|null $apiUri + * @param LoggerInterface|null $logger * @throws UsageException */ public function __construct( @@ -48,8 +49,8 @@ public function __construct( Headers $headers, CacheInterface $cache = null, $apiUri = null, - LoggerInterface $logger = null) - { + LoggerInterface $logger = null + ) { if (empty($apiId) || empty($apiSecret)) { throw new UsageException("Key and secret are required"); } diff --git a/src/Client/BookboonResponse.php b/src/Client/BookboonResponse.php index eeb779b..8e52364 100644 --- a/src/Client/BookboonResponse.php +++ b/src/Client/BookboonResponse.php @@ -113,7 +113,7 @@ public function serialize() */ public function unserialize($serialized) { - $data = unserialize($serialized, ['']); + $data = unserialize($serialized, ['allowed_classes' => [BookboonResponse::class]]); $this->body = $data['body']; $this->status = $data['status']; $this->headers = $data['headers']; diff --git a/src/Client/ClientInterface.php b/src/Client/ClientInterface.php index 2c77c0d..c9ba951 100644 --- a/src/Client/ClientInterface.php +++ b/src/Client/ClientInterface.php @@ -23,7 +23,7 @@ interface ClientInterface const API_HOST = 'bookboon.com'; const API_PATH = '/api'; - const VERSION = 'Bookboon-PHP/3.2'; + const VERSION = 'Bookboon-PHP/3.3'; /** * Prepares the call to the api and if enabled tries cache provider first for GET calls. diff --git a/src/Client/ResponseTrait.php b/src/Client/ResponseTrait.php index 88ba93c..8dc1dff 100644 --- a/src/Client/ResponseTrait.php +++ b/src/Client/ResponseTrait.php @@ -28,7 +28,7 @@ protected function handleErrorResponse(string $body, array $headers, int $status case 400: case 405: $returnArray = json_decode($body, true); - throw new ApiSyntaxException($returnArray['message']); + throw new ApiSyntaxException($returnArray['message'] ?? ''); case 401: case 403: $returnArray = json_decode($body, true); @@ -42,7 +42,6 @@ protected function handleErrorResponse(string $body, array $headers, int $status case 410: case 404: throw new ApiNotFoundException($url); - break; default: $returnArray = json_decode($body, true); throw new ApiGeneralException($this->generalExceptionMessage($returnArray ?? [], $headers)); @@ -86,4 +85,4 @@ protected function getResponseHeader(array $headers, string $name) : string { return $headers[$name] ?? ''; } -} \ No newline at end of file +} diff --git a/src/Entity/Author.php b/src/Entity/Author.php index 1d35e08..d12cc14 100644 --- a/src/Entity/Author.php +++ b/src/Entity/Author.php @@ -22,12 +22,12 @@ public static function get(Bookboon $bookboon, string $authorId) : BookboonRespo throw new BadUUIDException(); } - $bResponse = $bookboon->rawRequest("/authors/$authorId"); + $bResponse = $bookboon->rawRequest("/v1/authors/$authorId"); $bResponse->setEntityStore( new EntityStore( [ - new static($bResponse->getReturnArray()) + new self($bResponse->getReturnArray()) ] ) ); @@ -43,7 +43,7 @@ public static function get(Bookboon $bookboon, string $authorId) : BookboonRespo */ public static function getAll(Bookboon $bookboon) { - $bResponse = $bookboon->rawRequest("/authors"); + $bResponse = $bookboon->rawRequest('/v1/authors'); $bResponse->setEntityStore( new EntityStore(static::getEntitiesFromArray($bResponse->getReturnArray())) @@ -63,7 +63,7 @@ public static function getAll(Bookboon $bookboon) */ public static function getByBookId(Bookboon $bookboon, string $bookId) : BookboonResponse { - $bResponse = $bookboon->rawRequest("/books/$bookId/authors"); + $bResponse = $bookboon->rawRequest("/v1/books/$bookId/authors"); $bResponse->setEntityStore( new EntityStore(static::getEntitiesFromArray($bResponse->getReturnArray())) diff --git a/src/Entity/Book.php b/src/Entity/Book.php index f74817d..5540697 100644 --- a/src/Entity/Book.php +++ b/src/Entity/Book.php @@ -32,7 +32,7 @@ abstract class Book extends Entity */ public static function get(Bookboon $bookboon, string $bookId, bool $extendedMetadata = false) : BookboonResponse { - $bResponse = $bookboon->rawRequest("/books/$bookId", ['extendedMetadata' => $extendedMetadata ? 'true' : 'false']); + $bResponse = $bookboon->rawRequest("/v1/books/$bookId", ['extendedMetadata' => $extendedMetadata ? 'true' : 'false']); $bResponse->setEntityStore( new EntityStore( @@ -69,7 +69,7 @@ public static function getMultiple( 'extendedMetadata' => $extendedMetadata ? 'true' : 'false' ]; - $bResponse = $bookboon->rawRequest("/books", $variables); + $bResponse = $bookboon->rawRequest('/v1/books', $variables); $bResponse->setEntityStore( new EntityStore(static::getEntitiesFromArray($bResponse->getReturnArray())) @@ -99,7 +99,7 @@ public static function getAll( 'extendedMetadata' => $extendedMetadata ? 'true' : 'false' ]; - $bResponse = $bookboon->rawRequest("/books", $variables); + $bResponse = $bookboon->rawRequest('/v1/books', $variables); $bResponse->setEntityStore( new EntityStore(static::getEntitiesFromArray($bResponse->getReturnArray())) @@ -157,7 +157,7 @@ public static function getDownloadUrl( ) : string { $variables['format'] = $format; - $bResponse = $bookboon->rawRequest("/books/$bookId/download", $variables, ClientInterface::HTTP_POST); + $bResponse = $bookboon->rawRequest("/v1/books/$bookId/download", $variables, ClientInterface::HTTP_POST); return $bResponse->getReturnArray()['url']; } @@ -181,7 +181,7 @@ public static function search( int $offset = 0, array $bookTypes = ['pdf'] ) : BookboonResponse { - $bResponse = $bookboon->rawRequest('/search', ['q' => $query, 'limit' => $limit, 'offset' => $offset, 'bookType' => join(',', $bookTypes)]); + $bResponse = $bookboon->rawRequest('/v1/search', ['q' => $query, 'limit' => $limit, 'offset' => $offset, 'bookType' => join(',', $bookTypes)]); $bResponse->setEntityStore( new EntityStore(Book::getEntitiesFromArray($bResponse->getReturnArray())) @@ -206,7 +206,7 @@ public static function recommendations( int $limit = 5, array $bookTypes = ['pdf'] ) : BookboonResponse { - $bResponse = $bookboon->rawRequest('/recommendations', ['limit' => $limit, 'books' => $bookIds, 'bookType' => join(',', $bookTypes)]); + $bResponse = $bookboon->rawRequest('/v1/recommendations', ['limit' => $limit, 'books' => $bookIds, 'bookType' => join(',', $bookTypes)]); $bResponse->setEntityStore( new EntityStore(Book::getEntitiesFromArray($bResponse->getReturnArray())) diff --git a/src/Entity/Category.php b/src/Entity/Category.php index b9229c6..b35b9c8 100644 --- a/src/Entity/Category.php +++ b/src/Entity/Category.php @@ -8,9 +8,6 @@ class Category extends Entity { - const TEXTBOOKS = 'd1fabb36-4eff-4760-a80d-a15700efa9ae'; - const BUSINESS = '82403e77-ccbf-4e10-875c-a15700ef8a56'; - /** * Get Category. * @@ -24,12 +21,12 @@ class Category extends Entity */ public static function get(Bookboon $bookboon, string $categoryId, array $bookTypes = ['pdf']) : BookboonResponse { - $bResponse = $bookboon->rawRequest("/categories/$categoryId", ['bookType' => join(',', $bookTypes)]); + $bResponse = $bookboon->rawRequest("/v1/categories/$categoryId", ['bookType' => join(',', $bookTypes)]); $bResponse->setEntityStore( new EntityStore( [ - new static($bResponse->getReturnArray()) + new self($bResponse->getReturnArray()) ] ) ); @@ -51,7 +48,7 @@ public static function getTree( array $blacklistedCategoryIds = [], int $depth = 2 ) : BookboonResponse { - $bResponse = $bookboon->rawRequest('/categories', ['depth' => $depth]); + $bResponse = $bookboon->rawRequest('/v1/categories'); $categories = $bResponse->getReturnArray(); @@ -60,7 +57,7 @@ public static function getTree( } $bResponse->setEntityStore( - new EntityStore(Category::getEntitiesFromArray($categories)) + new EntityStore(self::getEntitiesFromArray($categories)) ); return $bResponse; @@ -100,7 +97,7 @@ private static function recursiveBlacklist(array &$categories, array $blackliste */ public static function getDownloadUrl(Bookboon $bookboon, string $categoryId, array $variables) : string { - $bResponse = $bookboon->rawRequest("/categories/$categoryId/download", $variables, ClientInterface::HTTP_POST); + $bResponse = $bookboon->rawRequest("/v1/categories/$categoryId/download", $variables, ClientInterface::HTTP_POST); return $bResponse->getReturnArray()['url']; } diff --git a/src/Entity/Exam.php b/src/Entity/Exam.php index fafdbb2..a102c4c 100644 --- a/src/Entity/Exam.php +++ b/src/Entity/Exam.php @@ -25,12 +25,12 @@ public static function get(Bookboon $bookboon, string $examId) : BookboonRespons throw new BadUUIDException(); } - $bResponse = $bookboon->rawRequest("/exams/$examId"); + $bResponse = $bookboon->rawRequest("/v1/exams/$examId"); $bResponse->setEntityStore( new EntityStore( [ - new static($bResponse->getReturnArray()) + new self($bResponse->getReturnArray()) ] ) ); @@ -46,7 +46,7 @@ public static function get(Bookboon $bookboon, string $examId) : BookboonRespons */ public static function getByBookId(Bookboon $bookboon, string $bookId) : BookboonResponse { - $bResponse = $bookboon->rawRequest("/books/$bookId/exams"); + $bResponse = $bookboon->rawRequest("/v1/books/$bookId/exams"); $bResponse->setEntityStore( new EntityStore(Exam::getEntitiesFromArray($bResponse->getReturnArray())) @@ -64,7 +64,7 @@ public static function getByBookId(Bookboon $bookboon, string $bookId) : Bookboo */ public static function getAll(Bookboon $bookboon) : BookboonResponse { - $bResponse = $bookboon->rawRequest("/exams"); + $bResponse = $bookboon->rawRequest("/v1/exams"); $bResponse->setEntityStore( new EntityStore(static::getEntitiesFromArray($bResponse->getReturnArray())) @@ -75,12 +75,12 @@ public static function getAll(Bookboon $bookboon) : BookboonResponse public static function start(Bookboon $bookboon, $examId) { - return $bookboon->rawRequest("/exams/$examId", [], ClientInterface::HTTP_POST)->getReturnArray(); + return $bookboon->rawRequest("/v1/exams/$examId", [], ClientInterface::HTTP_POST)->getReturnArray(); } public static function finish(Bookboon $bookboon, $examId, $postVars) { - return $bookboon->rawRequest("/exams/$examId/submit", $postVars, ClientInterface::HTTP_POST)->getReturnArray(); + return $bookboon->rawRequest("/v1/exams/$examId/submit", $postVars, ClientInterface::HTTP_POST)->getReturnArray(); } /** @@ -141,4 +141,4 @@ public function getQuestions() { return ExamQuestion::getEntitiesFromArray($this->safeGet('questions')); } -} \ No newline at end of file +} diff --git a/src/Entity/Frontpage.php b/src/Entity/Frontpage.php index dd3a496..c0ac7d8 100644 --- a/src/Entity/Frontpage.php +++ b/src/Entity/Frontpage.php @@ -24,10 +24,10 @@ class Frontpage extends Entity */ public static function get(Bookboon $bookboon, array $bookTypes = ['pdf']) : BookboonResponse { - $bResponse = $bookboon->rawRequest('/frontpage', ['bookType' => implode(',', $bookTypes)]); + $bResponse = $bookboon->rawRequest('/v1/frontpage', ['bookType' => implode(',', $bookTypes)]); $bResponse->setEntityStore( - new EntityStore(Frontpage::getEntitiesFromArray($bResponse->getReturnArray())) + new EntityStore(self::getEntitiesFromArray($bResponse->getReturnArray())) ); return $bResponse; @@ -46,14 +46,12 @@ public static function get(Bookboon $bookboon, array $bookTypes = ['pdf']) : Boo */ public static function getBySlug(Bookboon $bookboon, string $slug, array $bookTypes = ['pdf']) : BookboonResponse { - - /** @var Frontpage[] $frontpageArray */ - $bResponse = $bookboon->rawRequest("/frontpage/$slug", ['bookType' => join(',', $bookTypes)]); + $bResponse = $bookboon->rawRequest("/v1/frontpage/$slug", ['bookType' => join(',', $bookTypes)]); $bResponse->setEntityStore( new EntityStore( [ - new static($bResponse->getReturnArray()) + new self($bResponse->getReturnArray()) ] ) ); diff --git a/src/Entity/Journey.php b/src/Entity/Journey.php index c8678d5..df7d434 100644 --- a/src/Entity/Journey.php +++ b/src/Entity/Journey.php @@ -18,9 +18,9 @@ class Journey extends Entity */ public static function get(Bookboon $bookboon, string $journeyId) : BookboonResponse { - $bResponse = $bookboon->rawRequest("/journeys/$journeyId"); + $bResponse = $bookboon->rawRequest("/v1/journeys/$journeyId"); - $journeyEntity = new static($bResponse->getReturnArray()); + $journeyEntity = new self($bResponse->getReturnArray()); if (count($journeyEntity->getBookIds()) > 0) { $books = Book::getMultiple($bookboon, $journeyEntity->getBookIds(), false); @@ -49,7 +49,7 @@ public static function get(Bookboon $bookboon, string $journeyId) : BookboonResp */ public static function getAll(Bookboon $bookboon, array $bookTypes = ['pdf']) : BookboonResponse { - $bResponse = $bookboon->rawRequest('/journeys'); + $bResponse = $bookboon->rawRequest('/v1/journeys'); $bResponse->setEntityStore( new EntityStore(Journey::getEntitiesFromArray($bResponse->getReturnArray())) diff --git a/src/Entity/Language.php b/src/Entity/Language.php index 1c0dbdf..cf5d2e1 100644 --- a/src/Entity/Language.php +++ b/src/Entity/Language.php @@ -19,7 +19,7 @@ class Language extends Entity */ public static function get(Bookboon $bookboon, array $bookTypes = ['pdf']) : BookboonResponse { - $bResponse = $bookboon->rawRequest('/languages'); + $bResponse = $bookboon->rawRequest('/v1/languages'); $bResponse->setEntityStore( new EntityStore(Language::getEntitiesFromArray($bResponse->getReturnArray())) diff --git a/src/Entity/Question.php b/src/Entity/Question.php index a3b0885..fbfd16d 100644 --- a/src/Entity/Question.php +++ b/src/Entity/Question.php @@ -22,7 +22,7 @@ public static function get( array $answerIds = [], string $rootSegmentId = '' ) : BookboonResponse { - $url = $rootSegmentId == '' ? '/questions' : '/questions/' . $rootSegmentId; + $url = $rootSegmentId == '' ? '/v1/questions' : '/v1/questions/' . $rootSegmentId; $bResponse = $bookboon->rawRequest($url, ['answer' => $answerIds]); $bResponse->setEntityStore( @@ -46,7 +46,7 @@ public static function send( array $variables = [], string $rootSegmentId = '' ) : BookboonResponse { - $url = $rootSegmentId == '' ? '/questions' : '/questions/' . $rootSegmentId; + $url = $rootSegmentId == '' ? '/v1/questions' : '/v1/questions/' . $rootSegmentId; $bResponse = $bookboon->rawRequest($url, $variables, ClientInterface::HTTP_POST); return $bResponse; } diff --git a/src/Entity/Review.php b/src/Entity/Review.php index cf3531c..ce9bf60 100644 --- a/src/Entity/Review.php +++ b/src/Entity/Review.php @@ -25,10 +25,10 @@ public static function getByBookId(Bookboon $bookboon, string $bookId) : Bookboo throw new BadUUIDException(); } - $bResponse = $bookboon->rawRequest("/books/$bookId/review"); + $bResponse = $bookboon->rawRequest("/v1/books/$bookId/reviews"); $bResponse->setEntityStore( - new EntityStore(Review::getEntitiesFromArray($bResponse->getReturnArray())) + new EntityStore(self::getEntitiesFromArray($bResponse->getReturnArray())) ); return $bResponse; @@ -36,12 +36,12 @@ public static function getByBookId(Bookboon $bookboon, string $bookId) : Bookboo /** * @param array $review - * @return static + * @return Review * @throws \Bookboon\Api\Exception\EntityDataException */ public static function create(array $review = []) : Review { - return new static($review); + return new self($review); } @@ -57,7 +57,7 @@ public static function create(array $review = []) : Review public function submit(Bookboon $bookboon, string $bookId) : void { if (Entity::isValidUUID($bookId)) { - $bookboon->rawRequest("/books/$bookId/review", $this->getData(), ClientInterface::HTTP_POST); + $bookboon->rawRequest("/v1/books/$bookId/reviews", $this->getData(), ClientInterface::HTTP_POST); } } diff --git a/src/Entity/Subscription.php b/src/Entity/Subscription.php index e1d4231..6471f85 100644 --- a/src/Entity/Subscription.php +++ b/src/Entity/Subscription.php @@ -41,7 +41,7 @@ public static function add(Bookboon $bookboon, string $email, bool $hasConsented try { $bookboon->rawRequest( - '/subscriptions', + '/v1/subscriptions', $options, ClientInterface::HTTP_POST, false @@ -73,7 +73,7 @@ public static function remove(Bookboon $bookboon, string $email, ?string $alias) try { $bookboon->rawRequest( - '/subscriptions', + '/v1/subscriptions', $options, ClientInterface::HTTP_DELETE, false diff --git a/tests/BookboonTest.php b/tests/BookboonTest.php index 5a8bd8e..d066a51 100644 --- a/tests/BookboonTest.php +++ b/tests/BookboonTest.php @@ -33,7 +33,7 @@ public function testBadUrl() */ public function testBadRequest() { - self::$bookboon->rawRequest('/search', ['get' => ['q' => '']]); + self::$bookboon->rawRequest('/v1/search', ['get' => ['q' => '']]); } /** @@ -41,7 +41,7 @@ public function testBadRequest() */ public function testNotFound() { - self::$bookboon->rawRequest('/bah'); + self::$bookboon->rawRequest('/v1/bah'); } /** @@ -50,7 +50,7 @@ public function testNotFound() public function testBadAuthentication() { $bookboon = Bookboon::create("bad", "auth", ['basic']); - $bookboon->rawRequest('/categories/062adfac-844b-4e8c-9242-a1620108325e'); + $bookboon->rawRequest('/v1/categories/062adfac-844b-4e8c-9242-a1620108325e'); } /** @@ -59,7 +59,7 @@ public function testBadAuthentication() public function testEmpty() { $bookboon = Bookboon::create("", "", ['basic']); - $bookboon->rawRequest('/categories/062adfac-844b-4e8c-9242-a1620108325e'); + $bookboon->rawRequest('/v1/categories/062adfac-844b-4e8c-9242-a1620108325e'); } public function testGetClient() diff --git a/tests/Client/BasicAuthClientTest.php b/tests/Client/BasicAuthClientTest.php index bf57551..8789cdf 100644 --- a/tests/Client/BasicAuthClientTest.php +++ b/tests/Client/BasicAuthClientTest.php @@ -36,7 +36,7 @@ public function testBadAuthentication() $client = new BasicAuthClient("bad", "auth", new Headers(), null); $bookboon = new Bookboon($client); - $bookboon->rawRequest('/categories'); + $bookboon->rawRequest('/v1/categories'); } public function testNonExistingHeader() diff --git a/tests/Entity/AuthorTest.php b/tests/Entity/AuthorTest.php index 1432bc3..9a72474 100644 --- a/tests/Entity/AuthorTest.php +++ b/tests/Entity/AuthorTest.php @@ -4,6 +4,7 @@ use Bookboon\Api\Bookboon; use PHPUnit\Framework\TestCase; +use Bookboon\Api\Entity\Book; /** * Class AuthorTest @@ -19,7 +20,7 @@ public static function setUpBeforeClass() { include_once(__DIR__ . '/../Helpers.php'); $bookboon = \Helpers::getBookboon(); - self::$data = Author::get($bookboon, '0908031c-ce02-9b86-11e6-6dd9aa4699d1') + self::$data = Author::get($bookboon, '0908031c-ce02-9b86-11e6-6dd9268599d1') ->getEntityStore() ->getSingle(); } @@ -44,7 +45,7 @@ public function testNotFalse($method) public function testHasBooks() { $books = self::$data->getBooks(); - $this->assertInstanceOf('\Bookboon\Api\Entity\Book', $books[0]); + $this->assertInstanceOf(Book::class, $books[0]); } /** diff --git a/tests/Entity/CategoryTest.php b/tests/Entity/CategoryTest.php index 7d9df95..3772405 100644 --- a/tests/Entity/CategoryTest.php +++ b/tests/Entity/CategoryTest.php @@ -59,14 +59,22 @@ public function testInvalidCategory() public function testGetCategoryTree() { $categories = Category::getTree(self::$bookboon)->getEntityStore()->get(); - $this->assertEquals(2, count($categories)); + $this->assertGreaterThan(10, count($categories)); } public function testGetCategoryTreeBlacklist() { - $categories = Category::getTree(self::$bookboon, ['82403e77-ccbf-4e10-875c-a15700ef8a56', '07651831-1c44-4815-87a2-a2b500f5934a']); + $hiddenId = 'a382f37c-dc28-400a-9838-a17700ad5472'; + $categories = Category::getTree(self::$bookboon, [$hiddenId]); - $this->assertEquals(1, count($categories->getEntityStore()->get())); + $categoryIds = array_map( + static function (Category $item) { + return $item->getId(); + }, + $categories->getEntityStore()->get() + ); + + $this->assertNotContains($hiddenId, $categoryIds); } public function testCategoryDownload() diff --git a/tests/Helpers.php b/tests/Helpers.php index 5f505aa..1d3bbc7 100644 --- a/tests/Helpers.php +++ b/tests/Helpers.php @@ -18,7 +18,7 @@ public static function getApiSecret() public static function getBookboon() { - $bookboon = Bookboon::create(self::getApiId(), self::getApiSecret(), ['basic', 'download_book.pdf', 'download_category']); + $bookboon = Bookboon::create(self::getApiId(), self::getApiSecret(), ['basic', 'api.book.academic', 'api.book.professional', 'api.download_category', 'api.journeys']); $bookboon->getClient()->requestAccessToken([], OauthGrants::CLIENT_CREDENTIALS); return $bookboon; @@ -41,4 +41,4 @@ public static function invokeMethod(&$object, $methodName, array $parameters = [ return $method->invokeArgs($object, $parameters); } -} \ No newline at end of file +}