pixelead0 / tmdb_v3-PHP-API-

Wrapper in PHP for The Movie Data Base version 3
119 stars 84 forks source link

Undefined index: movie_credits #57

Closed omar-elhamedy closed 5 years ago

omar-elhamedy commented 5 years ago

Hi, is it possible to get cast and crew of movie Persons in the same function like getCredits(); ? I need to create a page with both cast and crew and the role of each person only ? also when I use this code to get all the cast member with their role on the movie it show me the first 40 correct with their role but then i get Undefined index: movie_credits & Invalid argument supplied for foreach() error. I'm still learning PHP so maybe I have approached the solution in a wrong way.

  $tmdb = new TMDB(); 
  $movieId = 383498;
  $tmdb->setAPIKey('APIKEY');
  $movie = $tmdb->getMovie($movieId);
  $cast = $movie->getCast();

   foreach ($cast as $person) {
                                echo '<li>'. $person->getName() .' </li>';
                                echo '<img src="'. $tmdb->getImageURL('w185') . $person->getProfile() .'"/></li>';
                                $person = $tmdb->getPerson($person->getID());
                        $movieRoles = $person->getMovieRoles();
                        foreach($movieRoles as $movieRole){
                            if ($movieRole->getMovieID() == $movieId){
                            echo $movieRole->getCharacter() ;

                                   ;}}}

### The Error

Undefined index: movie_credits in /var/www/html/app/tmdb/controller/classes/data/Person.php on line 122

Warning: Invalid argument supplied for foreach() in /var/www/html/app/tmdb/controller/classes/data/Person.php on line 122

bogdanfinn commented 5 years ago

Hey @omar-mohamed23 Is it really a use case to get the cast and the crew in one function call? You can make two calls and you have your required data.

But yeah it is possible. But a little bit harder: Every Object extending the ApiBaseObject has a general get() function. You can make something like this:

$movie->get('credits');

But attention: When you use the get() call you receive the API Response. Not Model Instances. You have to create Person instances manually with the correct data.

For your mentioned error with your code: Make sure your settings are correct. It seems that you are requesting a Ressource from the API and not specified the appended field (like movie_credits). Look in this file in your project: configuration/default.php

Look at my file:

// Data Return Configuration - Manipulate if you want to tune your results
$cnf['appender']['movie'] = array('trailers', 'images', 'credits', 'translations', 'reviews');
$cnf['appender']['tvshow'] = array('trailers', 'images', 'credits', 'translations', 'keywords');
$cnf['appender']['person'] = array('movie_credits', 'tv_credits', 'images');

Please look at the TMDB API Documentation. You are able to specify "extra fields" (like "movie_credits" for Persons). This extra fields are not send in the API Response by default. You have to manually specify them. If you want to call getMovieRoles() on a Person Instance make sure you have added "movie_credits" to the additional fields.

omar-elhamedy commented 5 years ago

First thing Thanks for your fast reply :) can you please give me an example on my code how to specify the appended field ? I checked the settings and they are the default. What confuse me that in this example I used on Deadpool 2 the result is what I need but it only show me the first 40 characters when I checked the original array from TMDB I think it stop showing character for the crew array in the API "Starting from (Sala Baker) in this example" that's what made me think to merge both cast and crew so I can loop through the array and get each character name for every Person.

bogdanfinn commented 5 years ago

Your code works. It loads only the Cast not the Crew. When want both try something like this:

$cast = $movie->getCast(); //your code
$crew = $movie->getCrew(); //Not in your code

//Your code
foreach ($cast as $person) {
    echo '<li>' . $person->getName() . ' </li>';
    echo '<img src="' . $tmdb->getImageURL('w185') . $person->getProfile() . '"/></li>';
    $person = $tmdb->getPerson($person->getID());
    $movieRoles = $person->getMovieRoles();
    foreach ($movieRoles as $movieRole) {
        if ($movieRole->getMovieID() == $movieId) {
            echo $movieRole->getCharacter();;
        }
    }
}

//Not in your code
foreach ($crew as $person) {
    echo '<li>' . $person->getName() . ' </li>';
    echo '<img src="' . $tmdb->getImageURL('w185') . $person->getProfile() . '"/></li>';
}

I tried it with deadpool 2 and it renders every crew member and every actor in my case. As i mentioned in my previous comment you have to specify your "append to response"-fields for the tmdb api. That you can do in the default configuration (if you use it). Let me explain it: If you want to load Data for a specific person the library internal calls the following url: https://api.themoviedb.org/3/person/{person_id}?api_key=<>&language=en-US

But you are able to make something like this: https://api.themoviedb.org/3/person/{person_id}?api_key=<>&language=en-US&append_to_response=movie_credits

This tells the API that you additionally want to get the movie_credits field for the person response. In this library you dont have to manipulate the URL directly. You only define the additional fields in your configuration file: `configuration/default.php`` (Look at my comment above) Further Information here: https://developers.themoviedb.org/3/getting-started/append-to-response

omar-elhamedy commented 5 years ago

@bogdanfinn Really Thank you for your help I get the error on my test VPS when I try the code but on my localhost XAMPP server it works fine. I think it might be an error with my PHP setup on my VPS. Thanks again for your help :)