Skip to content

Commit e330e8f

Browse files
authored
Merge pull request #241 from neildaniels/watch-providers
Add support for watch providers
2 parents e800d43 + 322a2a0 commit e330e8f

26 files changed

+3491
-8
lines changed

lib/Tmdb/Api/Movies.php

+13
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,19 @@ public function getVideos($movie_id, array $parameters = [], array $headers = []
296296
return $this->get('movie/' . $movie_id . '/videos', $parameters, $headers);
297297
}
298298

299+
/**
300+
* Get the watch providers (by region) for a specific movie id.
301+
*
302+
* @param $movie_id
303+
* @param array $parameters
304+
* @param array $headers
305+
* @return mixed
306+
*/
307+
public function getWatchProviders($movie_id, array $parameters = [], array $headers = [])
308+
{
309+
return $this->get('movie/' . $movie_id . '/watch/providers', $parameters, $headers);
310+
}
311+
299312
/**
300313
* Get the external ids that we have stored for a movie.
301314
*

lib/Tmdb/Api/Tv.php

+13
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,19 @@ public function getVideos($tvshow_id, array $parameters = [], array $headers = [
169169
return $this->get('tv/' . $tvshow_id . '/videos', $parameters, $headers);
170170
}
171171

172+
/**
173+
* Get the watch providers (by region) for a specific movie id.
174+
*
175+
* @param $movie_id
176+
* @param array $parameters
177+
* @param array $headers
178+
* @return mixed
179+
*/
180+
public function getWatchProviders($tvshow_id, array $parameters = [], array $headers = [])
181+
{
182+
return $this->get('tv/' . $tvshow_id . '/watch/providers', $parameters, $headers);
183+
}
184+
172185
/**
173186
* Get the changes for a specific TV show id.
174187
*

lib/Tmdb/Factory/MovieFactory.php

+28
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Tmdb\Model\Common\Translation;
2929
use Tmdb\Model\Company;
3030
use Tmdb\Model\Movie;
31+
use Tmdb\Model\Watch;
3132

3233
/**
3334
* Class MovieFactory
@@ -206,6 +207,33 @@ public function create(array $data = []): ?AbstractModel
206207
$movie->setReleaseDates($release_dates);
207208
}
208209

210+
if (array_key_exists('watch/providers', $data) && array_key_exists('results', $data['watch/providers'])) {
211+
$watchProviders = new GenericCollection();
212+
foreach ($data['watch/providers']['results'] as $iso31661 => $countryWatchData) {
213+
$countryWatchData['iso_3166_1'] = $iso31661;
214+
215+
foreach (['flatrate', 'rent', 'buy'] as $providerType) {
216+
$typeProviders = new GenericCollection();
217+
foreach ($countryWatchData[$providerType] ?? [] as $providerData) {
218+
if (isset($providerData['provider_id'])) {
219+
$providerData['id'] = $providerData['provider_id'];
220+
}
221+
if (isset($providerData['provider_name'])) {
222+
$providerData['name'] = $providerData['provider_name'];
223+
}
224+
225+
$providerData['iso_3166_1'] = $iso31661;
226+
$providerData['type'] = $providerType;
227+
$typeProviders->add(null, $this->hydrate(new Watch\Provider(), $providerData));
228+
}
229+
$countryWatchData[$providerType] = $typeProviders;
230+
}
231+
232+
$watchProviders->add($iso31661, $this->hydrate(new Watch\Providers(), $countryWatchData));
233+
}
234+
$movie->setWatchProviders($watchProviders);
235+
}
236+
209237
if (array_key_exists('videos', $data)) {
210238
$movie->setVideos($this->getVideoFactory()->createCollection($data['videos']));
211239
}

lib/Tmdb/Factory/TvFactory.php

+28
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Tmdb\Model\Person\CastMember;
3030
use Tmdb\Model\Person\CrewMember;
3131
use Tmdb\Model\Tv;
32+
use Tmdb\Model\Watch;
3233

3334
/**
3435
* Class TvFactory
@@ -244,6 +245,33 @@ public function create(array $data = []): ?AbstractModel
244245
$tvShow->setNetworks($this->getNetworkFactory()->createCollection($data['networks']));
245246
}
246247

248+
if (array_key_exists('watch/providers', $data) && array_key_exists('results', $data['watch/providers'])) {
249+
$watchProviders = new GenericCollection();
250+
foreach ($data['watch/providers']['results'] as $iso31661 => $countryWatchData) {
251+
$countryWatchData['iso_3166_1'] = $iso31661;
252+
253+
foreach (['flatrate', 'rent', 'buy'] as $providerType) {
254+
$typeProviders = new GenericCollection();
255+
foreach ($countryWatchData[$providerType] ?? [] as $providerData) {
256+
if (isset($providerData['provider_id'])) {
257+
$providerData['id'] = $providerData['provider_id'];
258+
}
259+
if (isset($providerData['provider_name'])) {
260+
$providerData['name'] = $providerData['provider_name'];
261+
}
262+
263+
$providerData['iso_3166_1'] = $iso31661;
264+
$providerData['type'] = $providerType;
265+
$typeProviders->add(null, $this->hydrate(new Watch\Provider(), $providerData));
266+
}
267+
$countryWatchData[$providerType] = $typeProviders;
268+
}
269+
270+
$watchProviders->add($iso31661, $this->hydrate(new Watch\Providers(), $countryWatchData));
271+
}
272+
$tvShow->setWatchProviders($watchProviders);
273+
}
274+
247275
if (array_key_exists('videos', $data) && $data['videos'] !== null) {
248276
$tvShow->setVideos($this->getVideoFactory()->createCollection($data['videos']));
249277
}

lib/Tmdb/Model/Movie.php

+24
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@ class Movie extends AbstractModel
230230
* @var int
231231
*/
232232
private $voteCount;
233+
/**
234+
* @var GenericCollection
235+
*/
236+
private $watchProviders;
233237

234238
/**
235239
* Constructor
@@ -255,6 +259,7 @@ public function __construct()
255259
$this->recommendations = new GenericCollection();
256260
$this->translations = new GenericCollection();
257261
$this->videos = new Videos();
262+
$this->watchProviders = new GenericCollection();
258263
}
259264

260265
/**
@@ -1032,4 +1037,23 @@ public function setVideos($videos)
10321037

10331038
return $this;
10341039
}
1040+
1041+
/**
1042+
* @return GenericCollection
1043+
*/
1044+
public function getWatchProviders(): GenericCollection
1045+
{
1046+
return $this->watchProviders;
1047+
}
1048+
1049+
/**
1050+
* @param GenericCollection $watchProviders
1051+
* @return $this
1052+
*/
1053+
public function setWatchProviders($watchProviders)
1054+
{
1055+
$this->watchProviders = $watchProviders;
1056+
1057+
return $this;
1058+
}
10351059
}

lib/Tmdb/Model/Movie/QueryParameter/AppendToResponse.php

+1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ final class AppendToResponse extends BaseAppendToResponse
4040
public const LISTS = 'lists';
4141
public const CHANGES = 'changes';
4242
public const VIDEOS = 'videos';
43+
public const WATCH_PROVIDERS = 'watch/providers';
4344
}

lib/Tmdb/Model/Query/Discover/DiscoverMoviesQuery.php

+43
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,49 @@ public function language($language)
120120
return $this;
121121
}
122122

123+
/**
124+
* An ISO 3166-1 code. Combine this filter with with_watch_providers in order to filter your results by a specific watch provider in a specific region.
125+
*
126+
* @param string $watchRegion
127+
* @return $this
128+
*/
129+
public function watchRegion($watchRegion)
130+
{
131+
$this->set('watch_region', $watchRegion);
132+
133+
return $this;
134+
}
135+
136+
/**
137+
* Only include movies with the specified watch providers. Combine with watch_region.
138+
*
139+
* @param array|string $watchProviders
140+
* @param int $mode
141+
* @return $this
142+
*/
143+
public function withWatchProviders($watchProviders, $mode = self::MODE_OR)
144+
{
145+
$this->set('with_watch_providers', $this->with($watchProviders, $mode));
146+
147+
return $this;
148+
}
149+
150+
/**
151+
* Only include movies with the specified monetization types. Combine with watch_region.
152+
*
153+
* Allowed Values: flatrate, free, ads, rent, buy
154+
*
155+
* @param array|string $watchProviders
156+
* @param int $mode
157+
* @return $this
158+
*/
159+
public function withWatchMonetizationTypes($watchProviders, $mode = self::MODE_OR)
160+
{
161+
$this->set('with_watch_monetization_types', $this->with($watchProviders, $mode));
162+
163+
return $this;
164+
}
165+
123166
/**
124167
* Minimum value is 1, expected value is an integer.
125168
*

lib/Tmdb/Model/Query/Discover/DiscoverTvQuery.php

+103
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
namespace Tmdb\Model\Query\Discover;
1616

1717
use DateTime;
18+
use Tmdb\Model\AbstractModel;
1819
use Tmdb\Model\Collection\QueryParametersCollection;
1920

2021
/**
@@ -23,6 +24,12 @@
2324
*/
2425
class DiscoverTvQuery extends QueryParametersCollection
2526
{
27+
/** Transform args to an AND query */
28+
public const MODE_AND = 0;
29+
30+
/** Transform args to an OR query */
31+
public const MODE_OR = 1;
32+
2633
/**
2734
* Minimum value is 1, expected value is an integer.
2835
*
@@ -49,6 +56,49 @@ public function language($language)
4956
return $this;
5057
}
5158

59+
/**
60+
* An ISO 3166-1 code. Combine this filter with with_watch_providers in order to filter your results by a specific watch provider in a specific region.
61+
*
62+
* @param string $watchRegion
63+
* @return $this
64+
*/
65+
public function watchRegion($watchRegion)
66+
{
67+
$this->set('watch_region', $watchRegion);
68+
69+
return $this;
70+
}
71+
72+
/**
73+
* Only include movies with the specified watch providers. Combine with watch_region.
74+
*
75+
* @param array|string $watchProviders
76+
* @param int $mode
77+
* @return $this
78+
*/
79+
public function withWatchProviders($watchProviders, $mode = self::MODE_OR)
80+
{
81+
$this->set('with_watch_providers', $this->with($watchProviders, $mode));
82+
83+
return $this;
84+
}
85+
86+
/**
87+
* Only include movies with the specified monetization types. Combine with watch_region.
88+
*
89+
* Allowed Values: flatrate, free, ads, rent, buy
90+
*
91+
* @param array|string $watchProviders
92+
* @param int $mode
93+
* @return $this
94+
*/
95+
public function withWatchMonetizationTypes($watchProviders, $mode = self::MODE_OR)
96+
{
97+
$this->set('with_watch_monetization_types', $this->with($watchProviders, $mode));
98+
99+
return $this;
100+
}
101+
52102
/**
53103
* Available options are vote_average.desc, vote_average.asc, first_air_date.desc,
54104
* first_air_date.asc, popularity.desc, popularity.asc
@@ -109,6 +159,44 @@ public function voteAverageGte($average)
109159
return $this;
110160
}
111161

162+
/**
163+
* Format the with compatible parameters.
164+
*
165+
* @param array|string $with
166+
* @param int $mode
167+
*
168+
* @return null|string
169+
*/
170+
protected function with($with = null, $mode = self::MODE_OR): ?string
171+
{
172+
if ($with instanceof GenericCollection) {
173+
$with = $with->toArray();
174+
}
175+
176+
if (is_array($with)) {
177+
return $this->andWith((array)$with, $mode);
178+
}
179+
180+
return $with;
181+
}
182+
183+
/**
184+
* Creates an and query to combine an AND or an OR expression.
185+
*
186+
* @param array $with
187+
* @param int $mode
188+
* @return string
189+
*/
190+
protected function andWith(array $with, $mode)
191+
{
192+
return (
193+
implode(
194+
$mode === self::MODE_OR ? '|' : ',',
195+
array_map([$this, 'normalize'], $with)
196+
)
197+
);
198+
}
199+
112200
/**
113201
* Creates an OR query for genres
114202
*
@@ -227,4 +315,19 @@ public function withNetworksAnd(array $networks = [])
227315
implode(',', $networks)
228316
);
229317
}
318+
319+
/**
320+
* Extract object id's if an collection was passed on.
321+
*
322+
* @param $mixed
323+
* @return mixed
324+
*/
325+
protected function normalize($mixed)
326+
{
327+
if (is_object($mixed) && $mixed instanceof AbstractModel) {
328+
return $mixed->getId();
329+
}
330+
331+
return $mixed;
332+
}
230333
}

0 commit comments

Comments
 (0)