Giter VIP home page Giter VIP logo

api's Introduction

A PHP Wrapper for use with the TMDB API.

License License Build Status Build Status codecov PHP Total Downloads

Tests run with minimal, normal and development dependencies.

Buy me a coffee, or a beer :-)

My stomach will appreciate your donation!

Main features

  • Array implementation of the movie database (RAW)
  • Model implementation of the movie database (By making use of the repositories)
  • An ImageHelper class to help build image urls or html elements.

Attention newcomers to php

If you are new to php and starting a project to learn, I'd recommend you skip down to the installation, and then follow the quickstart that's just for you!

I do advise you to take a broader look later on what all these PSR standards mean and do for the php community :-).

PSR Compliance

We try to leave as many options open to the end users of this library, as such with 4.0 changes have been made to introduce PSR compliance where we can. You bring the dependencies you prefer that are compliant with PSR standards, register the listeners, and we handle the rest.

Framework implementations

Installation

Install composer.

Before we can install the api library, you need to install a set of dependencies that provide the following implementations.

Dependencies you have to fulfill yourself

  • For PSR-7: HTTP Message Interface, for example nyholm/psr7.
  • For PSR-14: Event Dispatcher, for example symfony/event-dispatcher.
  • For PSR-17: HTTP Factories, for example nyholm/psr7.
  • For PSR-18: HTTP Client, for example guzzlehttp/guzzle.

I urge you to implement the optional caching implementation

When making use of caching, make sure to also include php-http/cache-plugin in composer, this plugin handles the logic for us, so we don't have to re-invent the wheel. You are however also free to choose to implement your own cache listener, or add the caching logic inside the http client of your choice.

composer require php-http/cache-plugin:^1.7

Even though themoviedb.org disabled rate limiting since the end of 2019, I'd still recommend enabling the cache to make your application run a bit smoother. As such the 427 retry subscriber in previous versions is not present anymore.

  • For PSR-6: Caching Interface, for example symfony/cache.
  • For PSR-16: Simple Cache, with an PSR-6 adapter for example symfony/cache, then use the PSR-16 to PSR-6 adapter.

Not only will this make your application more responsive, by loading from cache when we can, it also decreases the amount of requests we need to send.

Optional dependencies

  • For PSR-3: Logger Interface, for example monolog/monolog.

Install php-tmdb/api

If the required dependencies above are met, you are ready to install the library.

composer require php-tmdb/api:^4

Include Composer's autoloader:

require_once dirname(__DIR__).'/vendor/autoload.php';

To use the examples provided, copy the examples/apikey.php.dist to examples/apikey.php and change the settings.

New to PSR standards or composer?

If you came here looking to start a fun project to start learning, the above might seem a little daunting.

Don't worry! The documentation here was setup with beginners in mind as well.

We also provide a bunch of examples in the examples/ folder.

To get started;

composer require php-tmdb/api:^4 symfony/event-dispatcher guzzlehttp/guzzle symfony/cache monolog/monolog nyholm/psr7

Now that we have everything we need installed, let's get started setting up to be able to use the library.

Quick setup

Review the setup files below and go over the examples folder, for example examples/movies/api/get.php or examples/movies/api/get.php files.

Constructing the Client

If you have chosen different implementations than the examples suggested beforehand, obviously all the upcoming documentation won't match. Adjust accordingly to your dependencies, we will go along with the examples given earlier.

General API Usage

If you're looking for a simple array entry point the API namespace is the place to be, however we recommend you use the repositories and model's functionality up ahead.

use Tmdb\Client;

$client = new Client();
$movie = $client->getMoviesApi()->getMovie(550);

If you want to provide any other query arguments.

use Tmdb\Client;

$client = new Client();
$movie = $client->getMoviesApi()->getMovie(550, ['language' => 'en']);

For all further calls just review the unit tests or examples provided, or the API classes themselves.

Model Usage

The library can also be used in an object oriented manner, which I reckon is the preferred way of doing things.

Instead of calling upon the client, you pass the client onto one of the many repositories and do then some work on it.

use Tmdb\Repository\MovieRepository;
use Tmdb\Client;

$client = new Client();
$repository = new MovieRepository($client);
$movie = $repository->load(87421);

echo $movie->getTitle();

The repositories also contain the other API methods that are available through the API namespace.

use Tmdb\Repository\MovieRepository;
use Tmdb\Client;

$client = new Client();
$repository = new MovieRepository($client);
$topRated = $repository->getTopRated(['page' => 3]);
// or
$popular = $repository->getPopular();

For all further calls just review the unit tests or examples provided, or the model's themselves.

Event Dispatching

We (can) dispatch the following events inside the library, which by using event listeners you could modify some behavior.

HTTP Client exceptions

  • Tmdb\Event\HttpClientExceptionEvent
    • Allows to still set a successful response if the error can be corrected, by calling $event->isPropagated() in your listener, this does require you to provide a PSR-7 response object and set it with $event->setResponse($response).

TMDB API exceptions

  • Tmdb\Event\TmdbExceptionEvent
    • Allows to still set a successful response if the error can be corrected, by calling $event->isPropagated() in your listener, this does require you to provide a PSR-7 response object and set it with $event->setResponse($response).

Hydration

  • Tmdb\Event\BeforeHydrationEvent, allows modification of the response data before being hydrated.
    • This event will still be thrown regardless if the event_listener_handles_hydration option is set to false, this allows for example the logger to still produce records.
  • Tmdb\Event\AfterHydrationEvent, allows modification of the eventual subject returned.

The current implementation within the event dispatcher causes significant overhead, you might actually not want at all.

In the future we will look into this further for improvement, for now we have bigger fish to catch.

From 4.0 moving forward by default the hydration events have been disabled.

To re-enable this functionality, we recommend only using it for models you need to modify data for;

use Tmdb\Client;

$client = new Client([
    'hydration' => [
        'event_listener_handles_hydration' => true,
        'only_for_specified_models' => [
            Tmdb\Model\Movie::class
        ]
    ]
]);

If that configuration has been applied, also make sure the event dispatcher you use is aware of our HydrationListener;

use Symfony\Component\EventDispatcher\EventDispatcher;
use Tmdb\Event\HydrationEvent;
use Tmdb\Event\Listener\HydrationListener;

$eventDispatcher = new EventDispatcher();
$hydrationListener = new HydrationListener($eventDispatcher);
$eventDispatcher->addListener(HydrationEvent::class, $hydrationListener);

If you re-enable this functionality without specifying any models, all hydration will be done through the event listeners.

Requests & Responses

  • Tmdb\Event\BeforeRequestEvent
    • Allows modification of the PSR-7 request data before being sent.
    • Allows early response behavior ( think of caching ), by calling $event->isPropagated() in your listener, this does require you to provide a PSR-7 response object and set it with $event->setResponse($response)
  • Tmdb\Event\ResponseEvent
    • Contains the Request object.
    • Allows modification of the PSR-7 response before being hydrated, this does require you to provide a PSR-7 response object and set it with $event->setResponse($response)
    • Allows end-user to implement their own cache, or any other actions you'd like to perform on the given response.

Event listeners

We have a couple of optional event listeners that you could add to provide additional functionality.

Caching

Instead of constructing the default RequestListener, construct the client with the Psr6CachedRequestListener.

use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Tmdb\Event\Listener\Psr6CachedRequestListener;
use Tmdb\Repository\MovieRepository;
use Tmdb\Client;

$client = new Client();

$cache = new FilesystemAdapter('php-tmdb', 86400, __DIR__ . '/cache');
$requestListener = new Psr6CachedRequestListener(
    $client->getHttpClient(),
    $client->getEventDispatcher(),
    $cache,
    $client->getHttpClient()->getPsr17StreamFactory(),
    []
);

$repository = new MovieRepository($client);
$popular = $repository->getPopular();

The current implementation will change again in the future, it will either involve a small change in listener registration, or will just happen without you being aware. We currently base this on php-http/cache-plugin, which pulls in extra dependencies we don't really use. Since caching is quite a subject itself, for now we have chosen the "quick 'n dirty way".

Logging

The logging is divided in a couple of listeners, so you can decide what you want to log, or not. All of these listeners have support for writing custom formatted messages. See the relevant interfaces and classes located in the Tmdb\Formatter namespace.

Instead of monolog you can pass any PSR-3 compatible logger.

Tmdb\Event\Listener\Logger\LogApiErrorListener

use Monolog\Logger;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Tmdb\Event\Listener\Logger\LogApiErrorListener;
use Tmdb\Event\TmdbExceptionEvent;
use Tmdb\Formatter\TmdbApiException\SimpleTmdbApiExceptionFormatter;

$eventDispatcher = new EventDispatcher();
$apiErrorListener = new LogApiErrorListener(
    new Logger(),
    new SimpleTmdbApiExceptionFormatter()
);

$eventDispatcher->addListener(TmdbExceptionEvent::class, $apiErrorListener);

This will log exceptions thrown when a response has successfully been received, but the response indicated the request was not successful.

[2021-01-01 13:24:14] php-tmdb.CRITICAL: Critical API exception: 7 Invalid API key: You must be granted a valid key. [] []

Tmdb\Event\Listener\Logger\LogHttpMessageListener

use Symfony\Component\EventDispatcher\EventDispatcher;
use Tmdb\Event\BeforeRequestEvent;
use Tmdb\Event\HttpClientExceptionEvent;
use Tmdb\Event\Listener\Logger\LogHttpMessageListener;
use Tmdb\Event\ResponseEvent;
use Tmdb\Formatter\HttpMessage\SimpleHttpMessageFormatter;

$eventDispatcher = new EventDispatcher();
$requestLoggerListener = new LogHttpMessageListener(
    new Monolog\Logger(),
    new SimpleHttpMessageFormatter()
);

$eventDispatcher->addListener(BeforeRequestEvent::class, $requestLoggerListener);
$eventDispatcher->addListener(ResponseEvent::class, $requestLoggerListener);
$eventDispatcher->addListener(HttpClientExceptionEvent::class, $requestLoggerListener);

This will log outgoing requests and responses.

[2021-01-01 13:11:18] php-tmdb.INFO: Sending request: GET https://api.themoviedb.org/3/company/1?include_adult=true&language=en-US&region=us 1.1 {"length":0,"has_session_token":false} []
[2021-01-01 13:11:18] php-tmdb.INFO: Received response: 200 OK 1.1 {"status_code":200,"length":223} []

In case of any other PSR-18 client exceptions ( connection errors for example ), these will also be written to the log.

[2021-01-01 13:36:39] php-tmdb.INFO: Sending request: GET https://api.themoviedb.org/3/company/1?include_adult=true&language=en-US&region=us 1.1 {"length":0,"has_session_token":false} []
[2021-01-01 13:36:39] php-tmdb.CRITICAL: Critical http client error: 0 cURL error 7: Failed to connect to api.themoviedb.org port 443: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) {"request":"https://api.themoviedb.org/3/company/1?include_adult=true&language=en-US&region=us"} []

Tmdb\Event\Listener\Logger\LogHydrationListener

use Symfony\Component\EventDispatcher\EventDispatcher;
use Tmdb\Event\BeforeHydrationEvent;
use Tmdb\Event\Listener\Logger\LogHydrationListener;
use Tmdb\Formatter\Hydration\SimpleHydrationFormatter;

$eventDispatcher = new EventDispatcher();
$hydrationLoggerListener = new LogHydrationListener(
    new Monolog\Logger(),
    new SimpleHydrationFormatter(),
    false // set to true if you wish to add the json data passed for each hydration, do not use this in production!
);

$eventDispatcher->addListener(BeforeHydrationEvent::class, $hydrationLoggerListener);

This will log hydration of models with (optionally) their data, useful for debugging.

[2021-01-01 13:11:18] php-tmdb.DEBUG: Hydrating model "Tmdb\Model\Image\LogoImage". {"data":{"file_path":"/o86DbpburjxrqAzEDhXZcyE8pDb.png"},"data_size":49} []
[2021-01-01 13:11:18] php-tmdb.DEBUG: Hydrating model "Tmdb\Model\Company". {"data":{"description":"","headquarters":"San Francisco, California","homepage":"https://www.lucasfilm.com/","id":1,"logo_path":"/o86DbpburjxrqAzEDhXZcyE8pDb.png","name":"Lucasfilm Ltd.","origin_country":"US","parent_company":null},"data_size":227} []

For calls with a lot of appended data, this quickly becomes a large dump in the log file, and I would advise to only use this when necessary.

Do not enable the hydration data dumping on production, it will generate massive logs.

Adult filter

To enable inclusion of results considered "adult", add the following listener.

use Symfony\Component\EventDispatcher\EventDispatcher;
use Tmdb\Event\BeforeRequestEvent;
use Tmdb\Event\Listener\Request\AdultFilterRequestListener;

$eventDispatcher = new EventDispatcher();
$adultFilterListener = new AdultFilterRequestListener(true);

$eventDispatcher->addListener(BeforeRequestEvent::class, $adultFilterListener);

Language filter

To enable filtering contents on language, add the following listener.

use Symfony\Component\EventDispatcher\EventDispatcher;
use Tmdb\Event\BeforeRequestEvent;
use Tmdb\Event\Listener\Request\LanguageFilterRequestListener;

$eventDispatcher = new EventDispatcher();
$languageFilterListener = new LanguageFilterRequestListener('nl-NL');

$eventDispatcher->addListener(BeforeRequestEvent::class, $languageFilterListener);

Region filter

To enable filtering contents on region, add the following listener.

use Symfony\Component\EventDispatcher\EventDispatcher;
use Tmdb\Event\BeforeRequestEvent;
use Tmdb\Event\Listener\Request\RegionFilterRequestListener;

$eventDispatcher = new EventDispatcher();
$regionFilterListener = new RegionFilterRequestListener('nl');

$eventDispatcher->addListener(BeforeRequestEvent::class, $regionFilterListener);

Guest session

If you want to make use of guest sessions, you need to specify this explicitly on the client.

use Tmdb\Client;
use Tmdb\Token\Session\GuestSessionToken;

$client = new Client();
$client->setGuestSessionToken(new GuestSessionToken('my_token'));

// Now you can make calls in the guest sessions namespace. 

Image Helper

An ImageHelper class is present to take care of the images, which does require the configuration to be loaded:

use Tmdb\Client;
use Tmdb\Helper\ImageHelper;
use Tmdb\Model\Image;
use Tmdb\Repository\ConfigurationRepository;

$client = new Client();
$image = new Image();
$configRepository = new ConfigurationRepository($client);
$config = $configRepository->load();

$imageHelper = new ImageHelper($config);

echo $imageHelper->getHtml($image, 'w154', 154, 80);

Collection Filtering

We also provide some easy methods to filter any collection, you should note however you can always implement your own filter easily by using Closures:

use Tmdb\Model\Movie;
use Tmdb\Model\Image\PosterImage;

$movie = new Movie();

foreach($movie->getImages()->filter(
        function($key, $value){
            return $value instanceof PosterImage;
        }
    ) as $image) {
        // do something with all poster images
}

These basic filters however are already covered in the Images collection object:

use Tmdb\Model\Movie;

/** @var $movie Movie **/
$backdrop = $movie
    ->getImages()
    ->filterBackdrops()
;

And there are more Collections which provide filters, but you will find those out along the way.

The GenericCollection and the ResultCollection

  • The GenericCollection holds any collection of objects (e.g. an collection of movies).
  • The ResultCollection is an extension of the GenericCollection, and inherits the response parameters (page, total_pages, total_results) from an result set, this can be used to create pagination.

api's People

Contributors

actioussan avatar dariusiii avatar daverdalas avatar esbjorn avatar jackw6809 avatar johannesx75 avatar kduma avatar machou avatar markredeman avatar michael-pay avatar migburillo avatar mihaeu avatar mrmstn avatar nbraquart avatar nchief avatar neildaniels avatar nmullen avatar okaufmann avatar ptheofan avatar rjkip avatar sirikkoster avatar sostheng avatar strebl avatar thinkingmedia avatar tuxboy avatar wagnered avatar wells avatar wtfzdotnet avatar yukoff avatar z38 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

api's Issues

[API Feature] TV and Person related changes

Hey guys, we deployed a few things this morning:

1. Fixed creating lists via the API (this works again)
2. Added a 'origin_country' to TV search results
3. Added a `production_companies` field to the TV info method
4. Added `first_air_date` to person crew credit methods
5. Exposed the TV certification list method

Everything has been updated and added to the docs, so be sure to take a look.
  • Implementation at factory levels and objects I

Guzzle4

  • Implement an http adapter for Guzzle v4

TV Languages

Make sure the TV languages hydration includes proper objects for the languages returned ( currently just an array ).

Image related objects

  • Make sure image related objects provide relevant methods, and refactor them to be more explicit ( Image\Poster becomes Image\PosterImage ).
  • Extract duplicate code and provide a generic entry for hydration.

Get "production_compagnies" and "production_companies" for a Movie

Hi,

Very good job ! So, I have a little request, when I load a movie with :

$repository = new \Tmdb\Repository\MovieRepository($client);
$movie = $repository->load([move_id]);

The movie object doesn't have information concerning "production_compagnies" and "production_countries". Whereas the The Movie Database API send this informations.

Thanks a lot

Laravel Bundle

Hi Micheal

I did see you have a Symfony2 bundle.
Do you have Laravel experience? If yes, do you plan to make a bundle for Laravel?

Regards

[API Feature] The TV series content rating method is finally live

New Feature: The TV series content rating method is finally live. Check the docs for the details: http://docs.themoviedb.apiary.io/reference/tv/tvidcontentratings

Bug Fix: The popular person method wasn't paginating properly. This has been corrected.
  • Expand the factory(ies?) and associated model(s)

[API Feature] TV shows and episodes now support account states

New Feature: TV shows and episodes now support account states

The following two methods are now hooked up and live.

https://api.themoviedb.org/3/tv/{ID}/account_states?api_key=###&session_id=###

https://api.themoviedb.org/3/tv/{ID}/season/{SEASON_NUMBER}/episode/{EPISODE_NUMBER}/account_states?api_key=###&session_id=###

This rounds off making the `account_states` available for the 3 main rateable objects in our db. Both of these are documented in the docs.
  • Should be implemented at all levels

Refactor the registration of custom caching and logging

Currently the state of logging & caching was merely a quick fix, while focusing on other things. There's a couple of issues that need to be addressed:

  • The Client currently knows too much about these things and some methods should be removed.
  • A custom implementation of the logger should be able to be passed through, with an own LogSubscriber we could depend on the Psr\LogInterface and make this compatible with whatever anybody's flavor is.
  • I think the further caching methods should dissappear, in favor of explicitly registering these as EventSubscriber objects.

As caching is always enabled by default ( just following http protocols ), somehow an custom implementation should then also be forced to be on?

New feature /person/{id}/tagged_images

Hi,
i love your library, really love it!
I want know if you will add the new feature of the TheMovieDB API to get the tagged people in images: /person/{id}/tagged_images.

Thanks!

TV OriginCountry

OriginCountry should be a GenericCollection of Country objects.

TV CreatedBy

Should contain a GenericCollection with CastMember's.

Implement event dispatcher

  • Reduce overhead in the factories, and make them cleaner.
  • Allow modifying collections before they are returned.
  • Allow modifying requests and responses.

Found issue with Movie Changes Request

Hi :)
i don't know if it's a problem, or if i haven't understand how this API call works, but if i do this request:

$token  = new \Tmdb\ApiToken(TMDB_API_KEY);
$client = new \Tmdb\Client($token);

$movieChanges = $client->getChangesApi()->getMovieChanges(array(
    'page' => 1,
    'from' => '18-06-2014',
    'to'   => '19-06-2014'
));

var_dump($movieChanges);

or this:

$token  = new \Tmdb\ApiToken(TMDB_API_KEY);
$client = new \Tmdb\Client($token);

$movieChanges = $client->getChangesApi()->getMovieChanges(array(
    'page' => 1,
    'from' => '10-10-2012',
    'to'   => '14-10-2012'
));

var_dump($movieChanges);

return always 741 total result with always the same movie ids, i have also tried with this date format: YYYY-MM-DD, that is write in the TMDB API documentation, because you use this: MM-DD-YYYY and i can't understand what is the right format to send, and the result is always the same, with the same ids, i make some mistake?

thanks

[API Feature] Movie discover just got a nice upgrade!

New feature: Movie discover just got a nice upgrade!

We just added some really nice new sorting options (up to 14 now!) that we think are pretty awesome. Some of the queries you can build now are pretty darn powerful.

On top of the new sort options, we also added 7 new filters. You can now filter by primary_release_date.gte, primary_release_date.lte, vote_count.gte, vote_count.lte, with_cast, with_crew, with_people and with_keywords.

I started writing some example queries but you know what, there's just too many! Take a look at this page some examples:

https://www.themoviedb.org/documentation/api/discover
  • Might be fun to provide some filters by default to use, especially for the less experienced folks, other than that there are no changes necessary.

[API Feature] Person search responses now have a 'known_for' array.

New Feature: Person search responses now have a 'known_for' array.

We've been working on ways to help find data better and more accurately and one of the requests we've got around people is that a 'known_for' array would be really helpful.

Starting yesterday, the popular person, person search and multi search methods now return more information for the person record. This is especially useful on the search methods. You can see example responses in the docs, or here, just try it yourself.

http://docs.themoviedb.apiary.io/reference/search/searchmulti/get
http://docs.themoviedb.apiary.io/reference/search/searchperson/get

I'm sure you can imagine where else we might extend this, like perhaps some extra info in the movie search results too. All in due time ;)
  • Factories should be expanded I suppose, and the associated objects.

Select language for videos request

Hi! It's me again :)
I want know if it's possible add a Language parameter for the Video request for a movie, for example this call:

$videos = $client->getMoviesApi()->getVideos(87421);

thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.