* @author Fabian Beiner <fb@fabianbeiner.de>
* @license https://opensource.org/licenses/MIT The MIT License
* @link https://github.com/FabianBeiner/PHP-IMDB-Grabber/ GitHub Repository
- * @version 6.2.0
+ * @version 6.2.6
*/
class IMDB
{
* These are the regular expressions used to extract the data.
* If you don’t know what you’re doing, you shouldn’t touch them.
*/
- const IMDB_AKA = '~<td[^>]*>\s*Also\s*Known\s*As\s*</td>\s*<td>(.+)</td>~Uis';
- const IMDB_ASPECT_RATIO = '~<td[^>]*>Aspect\s*Ratio</td>\s*<td>(.+)</td>~Uis';
- const IMDB_AWARDS = '~<div\s*class="titlereference-overview-section">\s*Awards:(.+)</div>~Uis';
- const IMDB_BUDGET = '~<td[^>]*>Budget<\/td>\s*<td>\s*(.*)(?:\(estimated\))\s*<\/td>~Ui';
- const IMDB_CAST = '~<td[^>]*itemprop="actor"[^>]*>\s*<a\s*href="/name/([^/]*)/\?[^"]*"[^>]*>\s*<span.+>(.+)</span~Ui';
+ const IMDB_AKA = '~=ttrv_dt_aka.*<span[^>]+>(.*)</span>~Ui';
+ const IMDB_ASPECT_RATIO = '~aspect ratio.*<span.*>(.*)</span>~Uis';
+ const IMDB_AWARDS = '~Awards</a>.*span\sclass.*>(.*)</div>~Uis';
+ const IMDB_BUDGET = '~budget</span>.*<span.*>\s*(.*)(?:\s*\(estimated\))\s*</span>~Ui';
+ const IMDB_CAST = '~<\/div><a class="ipc-lockup-overlay ipc-focusable" href="\/name\/([^\/]*)\/.*href.*>(.*)<\/a>~Ui';
const IMDB_CAST_IMAGE = '~(loadlate="(.*)"[^>]*><\/a>\s+<\/td>\s+)?<td[^>]*itemprop="actor"[^>]*>\s*<a\s*href="\/name\/([^/]*)\/\?[^"]*"[^>]*>\s*<span.+>(.+)<\/span+~Uis';
- const IMDB_CERTIFICATION = '~<td[^>]*>\s*Certification\s*</td>\s*<td>(.+)</td>~Ui';
- const IMDB_CHAR = '~<td class="character">(?:\s+)<div>(.*)(?:\s+)(?: /| \(.*\)|<\/div>)~Ui';
- const IMDB_COLOR = '~<a href="\/search\/title\?colors=(?:.*)">(.*)<\/a>~Ui';
- const IMDB_COMPANIES = '~production_companies&ref_=(?:.*)">Edit</a>\s+</header>\s+<ul class="simpleList">(.*)Distributors</h4>~Uis';
- const IMDB_COMPANY = '~<li>\s+<a href="\/company\/(co[0-9]+)\/">(.*?)</a>~';
- const IMDB_COUNTRY = '~<a href="/country/(\w+)">(.*)</a>~Ui';
- const IMDB_CREATOR = '~<div[^>]*>\s*(?:Creator|Creators)\s*:\s*<ul[^>]*>(.+)</ul>~Uxsi';
- const IMDB_DISTRIBUTOR = '@href="[^"]*update=[t0-9]+:distributors[^"]*">Edit</a>\s*</header>\s*<ul\s*class="simpleList">(.*):special_effects_companies@Uis';
- const IMDB_DISTRIBUTORS = '@\/company\/(co[0-9]+)\/">(.*?)<\/a>\s+(?:\(([0-9]+)\))?\s+(?:\((.*?)\))?\s+(?:\((.*?)\))?\s+(?:\((?:.*?)\))?\s+</li>@';
- const IMDB_DIRECTOR = '~<div[^>]*>\s*(?:Director|Directors)\s*:\s*<ul[^>]*>(.+)</ul>~Uxsi';
- const IMDB_GENRE = '~href="/genre/([a-zA-Z_-]*)/?">([a-zA-Z_ -]*)</a>~Ui';
- const IMDB_GROSS = '~pl-zebra-list__label">Cumulative Worldwide Gross<\/td>\s+<td>\s+(.*)\s+<~Uxsi';
- const IMDB_ID = '~((?:tt\d{6,})|(?:itle\?\d{6,}))~';
+ const IMDB_CERTIFICATION = '~\?certificates=.*ref_=ttrv_stry">(.+)(?:</span></li></ul></div>|<a\sclass[^>]+\/parentalguide\/[^>]+>)~Ui';
+ const IMDB_CHAR = '~\/characters\/nm\d+\/.*>(.*)<\/a>~Ui';
+ const IMDB_COLOR = '~href="/search/title/\?colors(?:.*)">(.*)<\/a>~Ui';
+ const IMDB_COMPANIES = '~id="production">[\w\s]*?(.*)</section>~Ui';
+ const IMDB_COMPANY = '~href="/company/(co\d+)/\?ref_=ttrv_cmpy_\d">([^<svg].*?)</a><div~';
+ const IMDB_COUNTRY = '~country_of_origin=(.*)&ref_=ttrv_dt_cnt">(.*)<\/a~Ui';
+ const IMDB_CREATOR = '~>\s*(?:Creator|Creators|Producer|Producers).*<ul[^>]*>(.+)</ul>~Uxsi';
+ const IMDB_DISTRIBUTOR = '@<span\sid="distribution".*<ul\sclass[^>]+>(.*)</section>@Uis';
+ const IMDB_DISTRIBUTORS = '@<li.*\/company\/(.*)\/[^>]+>(.*)<.*\((.*),\s*([\d-]+?).*\((.*)\).*</li>@Uis';
+ const IMDB_DIRECTOR = '~id="director".*<ul[^>]*>(.+)</section>~Uxsi';
+ const IMDB_GENRE = '~genres=([a-zA-Z_-]*)&.*<span class="ipc-chip__text">([a-zA-Z_ -]*)<\/span><\/a~Ui';
+ const IMDB_GROSS = '~pl-zebra-list__label">Cumulative Worldwide Gross<\/td>\s*<td>\s*(.*?)\s*<\/td>~i';
+ const IMDB_ID = '~((?:tt\d+)|(?:itle\?\d+))~';
const IMDB_LANGUAGE = '~<a href="\/language\/(\w+)">(.*)<\/a>~Ui';
- const IMDB_LOCATION = '~href="\/search\/title\?locations=(.*)">(.*)<\/a>~Ui';
- const IMDB_LOCATIONS = '~href="\/search\/title\?locations=[^>]*>\s?(.*)\s?<\/a>[^"]*<dd>\s?(.*)\s<\/dd>~Ui';
- const IMDB_MPAA = '~<li class="ipl-inline-list__item">(?:\s+)(TV-Y|TV-Y7|TV-G|TV-PG|TV-14|TV-MA|G|PG|PG-13|R|NC-17|NR|UR)(?:\s+)<\/li>~Ui';
- const IMDB_MUSIC = '~Music by\s*<\/h4>.*<table class=.*>(.*)</table>~Us';
+ const IMDB_LOCATION = '~href="/search/title/\?locations=(.*)&.*">(.*)<\/a>~Ui';
+ const IMDB_LOCATIONS = '~href="(?<url>\/search\/title\/\?locations=[^>]*)">\s?(?<location>.*)\s?<\/a><p(.*)>\((?<specification>.*)\)<\/p>~Ui';
+ const IMDB_MPAA = '~<li class="ipl-inline-list__item">(?:\s+)(TV-Y|TV-Y7|TV-Y7-FV|TV-G|TV-PG|TV-14|TV-MA|TV-MA-L|TV-MA-S|TV-MA-V|G|PG|PG-13|R|NC-17|NR|UR|M|X)(?:\s+)<\/li>~Ui';
+ const IMDB_MUSIC = '~id="composer">.*<ul\sclass[^>]+>(.*)</section>~Uxsi';
const IMDB_NAME = '~href="/name/(.+)/?(?:\?[^"]*)?"[^>]*>(.+)</a>~Ui';
const IMDB_MOVIE_DESC = '~<section class="titlereference-section-overview">\s+<div>\s+(.*)\s*?</div>\s+<hr>\s+<div class="titlereference-overview-section">~Ui';
const IMDB_SERIES_DESC = '~<div>\s+(?:.*?</a>\s+</span>\s+</div>\s+<hr>\s+<div>\s+)(.*)\s+</div>\s+<hr>\s+<div class="titlereference-overview-section">~Ui';
const IMDB_SERIESEP_DESC = '~All Episodes(?:.*?)</li>\s+(?:.*?)?</ul>\s+</span>\s+<hr>\s+</div>\s+<div>\s+(.*?)\s+</div>\s+<hr>~';
- const IMDB_NOT_FOUND_ADV = '~<span>No results.</span>~Ui';
+ const IMDB_NOT_FOUND_ADV = '~"results-section-empty-results-msg"~Ui';
const IMDB_NOT_FOUND_DES = 'Know what this is about';
const IMDB_NOT_FOUND_ORG = '~<h1 class="findHeader">No results found for ~Ui';
- const IMDB_PLOT = '~<td[^>]*>\s*Plot\s*Summary\s*</td>\s*<td>\s*<p>\s*(.*)\s*</p>~Ui';
- const IMDB_PLOT_KEYWORDS = '~<td[^>]*>Plot\s*Keywords</td>\s*<td>(.+)(?:<a\s*href="/title/[^>]*>[^<]*</a>\s*</li>\s*</ul>\s*)?</td>~Ui';
- const IMDB_POSTER = '~<link\s*rel=\'image_src\'\s*href="(.*)">~Ui';
- const IMDB_RATING = '~class="ipl-rating-star__rating">(.*)<~Ui';
- const IMDB_RATING_COUNT = '~class="ipl-rating-star__total-votes">\((.*)\)<~Ui';
- const IMDB_RELEASE_DATE = '~href="/title/[t0-9]*/releaseinfo">(.*)<~Ui';
- const IMDB_RUNTIME = '~<td[^>]*>\s*Runtime\s*</td>\s*<td>(.+)</td>~Ui';
- const IMDB_SEARCH_ADV = '~text-primary">1[.]</span>\s*<a.href="\/title\/(tt\d{6,})\/(?:.*?)"(?:\s*)>(?:.*?)<\/a>~Ui';
+ const IMDB_PLOT = '~data-testid="plot-l".*>(.*)<\/span>~Ui';
+ const IMDB_PLOT_KEYWORDS = '~explore=keywords.*<span class="ipc-chip__text">(.*)<\/span>~Ui';
+ const IMDB_POSTER = '~<meta property="og:image" content="(.*)"\/>~Ui';
+ const IMDB_RATING = '~"ratingsSummary":{"aggregateRating":(.*),.*}~Ui';
+ const IMDB_RATING_COUNT = '~"ratingsSummary":{.*"voteCount":(\d+),.*}~Ui';
+ const IMDB_RELEASE_DATE = '~\/title\/tt\d+\/releaseinfo\/\?ref_=ttrv_ov_rdat">(.*)</a>~Ui';
+ const IMDB_RUNTIME = '~id="runtime".*<ul[^>]+>(.*)</ul>~Ui';
+ const IMDB_SEARCH_ADV = '~<a href="/title/(tt\d+).*?ipc-title-link-wrapper~i';
const IMDB_SEARCH_ORG = '~find-title-result">(?:.*?)alt="(.*?)"(?:.*?)href="\/title\/(tt\d{6,})\/(?:.*?)">(.*?)<\/a>~';
- const IMDB_SEASONS = '~episodes\?season=(?:\d+)">(\d+)<~Ui';
- const IMDB_SOUND_MIX = '~<td[^>]*>\s*Sound\s*Mix\s*</td>\s*<td>(.+)</td>~Ui';
- const IMDB_TAGLINE = '~<td[^>]*>\s*Taglines\s*</td>\s*<td>(.+)</td>~Ui';
- const IMDB_TITLE = '~itemprop="name">(.*)(<\/h3>|<span)~Ui';
+ const IMDB_SEASONS = '~episodes/\?season=[^>]+>(\d+)<~Ui';
+ const IMDB_SOUND_MIX = '~/search/title/\?sound_mixes.*ref_=spec_2">(.*)</a>~Ui';
+ const IMDB_TAGLINE = '~"taglines":{"edges":\[{"node":{"text":"(.*)","__typename":"Tagline"}~Ui';
+ const IMDB_TITLE = '~<title>(.*)\s*\(.*\)\s*-\sReference\s*view \s*-\s*IMDb</title>~Ui';
const IMDB_TITLE_EP = '~titlereference-watch-ribbon"(?:.*)itemprop="name">(.*?)\s+<span\sclass="titlereference-title-year">~Ui';
- const IMDB_TITLE_ORIG = '~</h3>(?:\s+)(.*)(?:\s+)<span class=\"titlereference-original-title-label~Ui';
+ const IMDB_TITLE_ORIG = '~hero__pageTitle.*hero__primary-text">(.*)</span>~Ui';
const IMDB_TOP250 = '~href="/chart/top(?:tv)?".class(?:.*?)#([0-9]{1,})</a>~Ui';
const IMDB_TRAILER = '~href="/title/(?:tt\d+)/videoplayer/(vi[0-9]*)"~Ui';
- const IMDB_TYPE = '~href="/genre/(?:[a-zA-Z_-]*)/?">(?:[a-zA-Z_ -]*)</a>\s+</li>\s+(?:.*item">)\s+(?:<a href="(?:.*)</a>\s+</li>\s+(?:.*item">)\s+)?([a-zA-Z_ -]*)\s+</li>~Ui';
+ const IMDB_TYPE = '~"titleType":.*"text":"(.*)",~Ui';
const IMDB_URL = '~https?://(?:.*\.|.*)imdb.com/(?:t|T)itle(?:\?|/)(..\d+)~i';
- const IMDB_USER_REVIEW = '~href="/title/[t0-9]*/reviews"[^>]*>([^<]*)\s*User~Ui';
- const IMDB_VOTES = '~"ipl-rating-star__total-votes">\s*\((.*)\)\s*<~Ui';
- const IMDB_WRITER = '~<div[^>]*>\s*(?:Writer|Writers)\s*:\s*<ul[^>]*>(.+)</ul>~Ui';
- const IMDB_YEAR = '~og:title\' content="(?:.*)\((?:.*)(\d{4})(?:.*)\)~Ui';
+ const IMDB_USER_REVIEW = '~href="/title/tt\d+/reviews/\?ref_=ttrv_ov_ururv">(.*)</a>~Ui';
+ const IMDB_VOTES = '~"ratingsSummary":{.*"voteCount":(\d+),.*}~Ui';
+ const IMDB_WRITER = '~>\s*(?:Writer|Writers).*<ul[^>]*>(.+)</ul>~Uxsi';
+ const IMDB_YEAR = '~<title>.*\s*\((?:[^()]+ )?(\d{4}(?:–\d{4})?)\)\s*-\sReference\s*view \s*-\s*IMDb</title>~iU';
/**
* @var string The string returned, if nothing is found.
}
$aCurlInfo = IMDBHelper::runCurl($this->sUrl);
- $sSource = $aCurlInfo['contents'];
+ $sSource = isset($aCurlInfo['contents']) ? $aCurlInfo['contents'] : false;
if (false === $sSource) {
if (true === self::IMDB_DEBUG) {
return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
} else {
- $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo', $this->iId);
+ $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo/', $this->iId);
$aCurlInfo = IMDBHelper::runCurl($fullAkas);
$sSource = $aCurlInfo['contents'] ?? false;
return false;
}
- $aReturned = IMDBHelper::matchRegex($sSource, "~<td class=\"aka-item__name\">(.*?)<\/td>\s+<td class=\"aka-item__title\">(.*?)<\/td>~");
+ $aReturned = IMDBHelper::matchRegex($sSource, '~<span class="ipc-metadata-list-item__label"[^>]*>([^<]+)</span>.*?<span class="ipc-metadata-list-item__list-content-item"[^>]*>([^<]+)</span>(?:\s*<span class="ipc-metadata-list-item__list-content-item--subText"[^>]*>\(([^)]+)\)</span>)?~s');
if ($aReturned) {
$aReturn = [];
return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
} else {
- $fullCritics = sprintf('https://www.imdb.com/title/tt%s/criticreviews', $this->iId);
+ $fullCritics = sprintf('https://www.imdb.com/title/tt%s/criticreviews/', $this->iId);
$aCurlInfo = IMDBHelper::runCurl($fullCritics);
$sSource = $aCurlInfo['contents'] ?? false;
echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
}
- return false;
+ return IMDB::$sNotFound;
}
$aReturned = IMDBHelper::matchRegex(
$sSource,
- '~metascore_wrap(?:.*)\s+(?:.*)\s+(?:.*)ratingValue\">([0-9]+)<\/span>(?:\s+(?:.*)){4}ratingCount\">([0-9]+)~'
+ '~<div class="sc-8c54a7fa-1 gTQbcw">(\d+)</div>.*?(\d+) reviews~s'
);
if ($aReturned) {
$aReturn = [];
$aReturn[] = [
- 'metascore' => IMDBHelper::cleanString($aReturned[1][0]),
- 'reviews' => IMDBHelper::cleanString($aReturned[2][0]),
+ 'metascore' => isset($aReturned[1][0]) ? IMDBHelper::cleanString($aReturned[1][0]) : '',
+ 'reviews' => isset($aReturned[2][0]) ? IMDBHelper::cleanString($aReturned[2][0]) : '',
];
file_put_contents($sCacheFile, serialize($aReturn));
return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
} else {
- $fullCritics = sprintf('https://www.imdb.com/title/tt%s/criticreviews', $this->iId);
+ $fullCritics = sprintf('https://www.imdb.com/title/tt%s/criticreviews/', $this->iId);
$aCurlInfo = IMDBHelper::runCurl($fullCritics);
$sSource = $aCurlInfo['contents'] ?? false;
echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
}
- return false;
+ return IMDB::$sNotFound;
}
$aReturned = IMDBHelper::matchRegex(
$sSource,
- '~"ratingValue\">([0-9]+)<\/span>\s+<\/div>\s+<\/td>\s+(?:.*)\s+(?:<a\s+href=\"(.*)\"\s+)?(?:.*)\"name\">(.*)<\/span>(?:.*)\"name\">(.*)<\/span><\/span>(?:<\/a>)?\s+(?:.*)\"reviewbody\"> (.*)<\/div>~'
+ '~<div class="sc-d8486f96-2 (?:fgepEK|kPhAAe|crRWFG)">(\d+)</div>.*?<span class="sc-d8486f96-5 jyAgZO">(.*?)</span>(?:<a.*?href="(.*?)".*?>)?(.*?)</(?:span|a)>.*?<div>(.*?)</div>~'
);
if ($aReturned) {
if (0 !== $iLimit && $i >= $iLimit) {
break;
}
- $sChar = str_replace(' / ', ' and ', $aMatchChar[1][$i]);
+ $sCharRaw = $aMatchChar[1][$i] ?? 'Unknown';
+ $sChar = str_replace(' / ', ' and ', $sCharRaw);
$aReturn[] = '<a href="https://www.imdb.com/name/' . IMDBHelper::cleanString(
$aMatch[1][$i]
) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
if (0 !== $iLimit && $i >= $iLimit) {
break;
}
- $sChar = str_replace(' / ', ' and ', $aMatchChar[1][$i]);
+ $sCharRaw = $aMatchChar[1][$i] ?? 'Unknown';
+ $sChar = str_replace(' / ', ' and ', $sCharRaw);
+
$aReturn[] = IMDBHelper::cleanString($sName) . ' as ' . IMDBHelper::cleanString($sChar);
}
/**
* Returns all locations
*
- * @return string location
- * @return string specification
+ * @return string|array locations
*/
public function getLocations()
{
return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
} else {
- $fullLocations = sprintf('https://www.imdb.com/title/tt%s/locations', $this->iId);
+ $fullLocations = sprintf('https://www.imdb.com/title/tt%s/locations/', $this->iId);
$aCurlInfo = IMDBHelper::runCurl($fullLocations);
$sSource = $aCurlInfo['contents'] ?? false;
echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
}
- return false;
+ return IMDB::$sNotFound;
}
$aReturned = IMDBHelper::matchRegex($sSource, self::IMDB_LOCATIONS);
if ($aReturned) {
$aReturn = [];
- foreach ($aReturned[1] as $i => $strName) {
+ foreach ($aReturned['url'] as $i => $strName) {
if (strpos($strName, '(') === false) {
$aReturn[] = [
- 'location' => IMDBHelper::cleanString($strName),
- ];
- }
- if (strpos($aReturned[2][$i], '(') !== false) {
- $aReturn[] = [
- 'specification' => IMDBHelper::cleanString($aReturned[2][$i]),
+ 'url' => IMDBHelper::cleanString($aReturned['url'][$i]),
+ 'location' => IMDBHelper::cleanString($aReturned['location'][$i]),
+ 'specification' => IMDBHelper::cleanString($aReturned['specification'][$i]),
];
}
}
* @param bool $bMore Add … if there are more cast members than printed.
* @param string $sSize small or big images
*
- * @return array Array with title and url.
+ * @return string Array with title and url.
*/
public function getPhotos($iLimit = 0, $bMore = true, $sSize = 'small')
{
while ($isPage) {
$fullPhotos = sprintf('https://www.imdb.com/title/tt%s/mediaindex?page=%d', $this->iId, $page);
$aCurlInfo = IMDBHelper::runCurl($fullPhotos);
- $sSource = $aCurlInfo['contents'];
+ $sSource = isset($aCurlInfo['contents']) ? $aCurlInfo['contents'] : false;
if (false === $sSource) {
if (true === self::IMDB_DEBUG) {
echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
}
- return false;
+ return IMDB::$sNotFound;
}
$aReturned = IMDBHelper::matchRegex($sSource, '~title="(.*?)"\s+><img(?:.*)\s+src="(.*?)"\s+\/>~');
return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
} else {
- $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo', $this->iId);
+ $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo/', $this->iId);
$aCurlInfo = IMDBHelper::runCurl($fullAkas);
$sSource = $aCurlInfo['contents'] ?? false;
echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
}
- return false;
+ return IMDB::$sNotFound;
}
$aReturned = IMDBHelper::matchRegex(
$sSource,
- '~>(.*)\s+<\/a><\/td>\s+<td class=\"release-date-item__date\" align=\"right\">(.*)<\/td>~'
+ '~<a class="ipc-metadata-list-item__label[^>]*>([^<]+)</a>.*?<span class="ipc-metadata-list-item__list-content-item"[^>]*>([^<]+)</span>~s'
);
if ($aReturned) {
$fullEpisodes = sprintf('https://www.imdb.com/title/tt%s/episodes/?season=%d', $this->iId, $page);
$aCurlInfo = IMDBHelper::runCurl($fullEpisodes);
- $sSource = $aCurlInfo['contents'];
+ $sSource = isset($aCurlInfo['contents']) ? $aCurlInfo['contents'] : false;
if (false === $sSource) {
if (true === self::IMDB_DEBUG) {
echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
}
+ return IMDB::$sNotFound;
+ }
- return false;
+ $aSeasonsLinks = IMDBHelper::matchRegex($sSource, '~tab-season-entry" href="/title/tt\d+/episodes/\?season=(\d)~s');
+ $aFoundSeasons = [];
+ if ($aSeasonsLinks) {
+ foreach ($aSeasonsLinks[1] as $i => $aSeasonNumber) {
+ $aFoundSeasons[] = $aSeasonNumber;
+ }
+
+ }
+
+ if (!in_array($page, $aFoundSeasons)) {
+ break;
}
$aSplit = IMDBHelper::matchRegex($sSource, '~<article class=.+?episode-item-wrapper(.+?)ipc-rating-star--rate">Rate</span>~s');
if ($aSplit) {
foreach ($aSplit[1] as $i => $text) {
- $aReturned = IMDBHelper::matchRegex($aSplit[1][$i], '~h4.+/title/(tt\d+)/[?]ref_.+ttep_ep(\d+).+?S\d+\.E\d+ ∙ (.+?)<\/div>.+?<span class=".+?">(.+?)</span>.+?<div class="ipc-html-content-inner-div">(.+?)</div>.+?ratingGroup--imdb-rating.+?</svg>(.+?)<span.+?ipc-rating-star--voteCount">.+?>(.+?)<~s');
- if ($aReturned) {
- foreach ($aReturned[1] as $n => $episode) {
- $aReturn[] = [
- 'season' => $page,
- 'episode' => IMDBHelper::cleanString($aReturned[2][$n]),
- 'title' => IMDBHelper::cleanString($aReturned[3][$n]),
- 'rating' => IMDBHelper::cleanString($aReturned[6][$n]),
- 'votes' => IMDBHelper::cleanString($aReturned[7][$n]),
- 'airdate' => IMDBHelper::cleanString($aReturned[4][$n]),
- 'plot' => IMDBHelper::cleanString($aReturned[5][$n]),
- 'id' => IMDBHelper::cleanString($aReturned[1][$n]),
- ];
- }
+
+ # Set default values
+ $dEpisode = self::$sNotFound;
+ $dTitle = self::$sNotFound;
+ $dRating = self::$sNotFound;
+ $dVotes = self::$sNotFound;
+ $dAirdate = self::$sNotFound;
+ $dPlot = self::$sNotFound;
+ $dId = self::$sNotFound;
+
+ # Find values
+ $fId = IMDBHelper::matchRegex($aSplit[1][$i], '~h4.+/title/(tt\d+)~s');
+ $fEpisode = IMDBHelper::matchRegex($aSplit[1][$i], '~ref_=ttep_ep_(\d+)~s');
+ $fTitle = IMDBHelper::matchRegex($aSplit[1][$i], '~S\d+\.E\d+ ∙ (.+?)<\/div>~s');
+ $fAirdate = IMDBHelper::matchRegex($aSplit[1][$i], '~<span class="sc-ccd6e31b-10 fVspdm">(.+?)<\/span>~s');
+ $fPlot = IMDBHelper::matchRegex($aSplit[1][$i], '~"ipc-html-content-inner-div" role="presentation">(.+?)<\/div>~s');
+ $fRaiting = IMDBHelper::matchRegex($aSplit[1][$i], '~IMDb rating: (\d\.\d)~s');
+ $fVotes = IMDBHelper::matchRegex($aSplit[1][$i], '~voteCount.+?-->(.+?)<~s');
+
+ # Update values if not empty
+ if (!empty($fId[1][0])) {
+ $dId = IMDBHelper::cleanString($fId[1][0]);
+ }
+
+ if (!empty($fEpisode[1][0])) {
+ $dEpisode = IMDBHelper::cleanString($fEpisode[1][0]);
+ }
+
+ if (!empty($fTitle[1][0])) {
+ $dTitle = IMDBHelper::cleanString($fTitle[1][0]);
+ }
+
+ if (!empty($fRaiting[1][0])) {
+ $dRating = IMDBHelper::cleanString($fRaiting[1][0]);
}
+
+ if (!empty($fVotes[1][0])) {
+ $dVotes = IMDBHelper::cleanString($fVotes[1][0]);
+ }
+
+ if (!empty($fAirdate[1][0])) {
+ $dAirdate = IMDBHelper::cleanString($fAirdate[1][0]);
+ }
+
+ if (!empty($fPlot[1][0])) {
+ $dPlot = IMDBHelper::cleanString($fPlot[1][0]);
+ }
+
+
+ $aReturn[] = [
+ 'season' => $page,
+ 'episode' => $dEpisode,
+ 'title' => $dTitle,
+ 'rating' => $dRating,
+ 'votes' => $dVotes,
+ 'airdate' => $dAirdate,
+ 'plot' => $dPlot,
+ 'id' => $dId,
+ ];
+
}
}
file_put_contents($sCacheFile, serialize($aReturn));
- if (preg_match('~href="\?season=-1~s', $sSource) || !preg_match('~id="load_next_episodes"~', $sSource)) {
- break;
- }
$page++;
}
*/
public static function arrayOutput($bArrayOutput, $sSeparator, $sNotFound, $aReturn = null, $bHaveMore = false)
{
- if ($bArrayOutput ?? false) {
- if ($aReturn == null || ! is_array($aReturn)) {
- return [];
- }
-
- if ($bHaveMore) {
- $aReturn[] = '…';
- }
+ if ($aReturn === null) {
+ return $bArrayOutput ? [] : $sNotFound;
+ }
- return $aReturn;
- } else {
- if ($aReturn == null || ! is_array($aReturn)) {
- return $sNotFound;
- }
+ if ($bArrayOutput) {
+ return $bHaveMore ? [...$aReturn, '…'] : $aReturn;
+ }
- foreach ($aReturn as $i => $value) {
- if (is_array($value)) {
- $aReturn[$i] = implode($sSeparator, $value);
- }
- }
+ $processValue = fn(mixed $value): string => match (true) {
+ is_array($value) => empty(array_filter($value, fn($v) => $v !== '' && $v !== null))
+ ? $sNotFound
+ : implode($sSeparator, array_map(fn($v) => $v ?: $sNotFound, $value)),
+ $value === '' || $value === null => $sNotFound,
+ default => (string)$value,
+ };
- return implode($sSeparator, $aReturn) . (($bHaveMore) ? '…' : '');
- }
+ $result = implode($sSeparator, array_map($processValue, $aReturn));
+ return $bHaveMore ? $result . '…' : $result;
}
/**
CURLOPT_BINARYTRANSFER => ($bDownload ? true : false),
CURLOPT_CONNECTTIMEOUT => self::IMDB_TIMEOUT,
CURLOPT_ENCODING => '',
- CURLOPT_FOLLOWLOCATION => 0,
+ CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_FRESH_CONNECT => 0,
CURLOPT_HEADER => ($bDownload ? false : true),
CURLOPT_HTTPHEADER => [
if (200 !== $aCurlInfo['http_code'] && 302 !== $aCurlInfo['http_code']) {
if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL returned wrong HTTP code “' . $aCurlInfo['http_code'] . '”, aborting.</b></pre>';
+ echo '<pre><b>cURL returned wrong HTTP code “' . $aCurlInfo['http_code'] . '” for “' . $aCurlInfo['url'] . '”, aborting.</b></pre>';
}
return false;
* @author Fabian Beiner <fb@fabianbeiner.de>
* @license https://opensource.org/licenses/MIT The MIT License
* @link https://github.com/FabianBeiner/PHP-IMDB-Grabber/ GitHub Repository
- * @version 6.2.0
+ * @version 6.2.6
*
*
* Functionality is the same but modified heavily to remove the does-not-make-sense static helper
/**
* Set this to true if you run into problems.
*/
- private bool $IMDB_DEBUG = false;
+ private bool $IMDB_DEBUG = true;
/**
* @var string Set the preferred language for the User Agent.
* These are the regular expressions used to extract the data.
* If you don’t know what you’re doing, you shouldn’t touch them.
*/
- const IMDB_AKA = '~<td[^>]*>\s*Also\s*Known\s*As\s*</td>\s*<td>(.+)</td>~Uis';
- const IMDB_ASPECT_RATIO = '~<td[^>]*>Aspect\s*Ratio</td>\s*<td>(.+)</td>~Uis';
- const IMDB_AWARDS = '~<div\s*class="titlereference-overview-section">\s*Awards:(.+)</div>~Uis';
- const IMDB_BUDGET = '~<td[^>]*>Budget<\/td>\s*<td>\s*(.*)(?:\(estimated\))\s*<\/td>~Ui';
- const IMDB_CAST = '~<td[^>]*itemprop="actor"[^>]*>\s*<a\s*href="/name/([^/]*)/\?[^"]*"[^>]*>\s*<span.+>(.+)</span~Ui';
+ const IMDB_AKA = '~=ttrv_dt_aka.*<span[^>]+>(.*)</span>~Ui';
+ const IMDB_ASPECT_RATIO = '~aspect ratio.*<span.*>(.*)</span>~Uis';
+ const IMDB_AWARDS = '~Awards</a>.*span\sclass.*>(.*)</div>~Uis';
+ const IMDB_BUDGET = '~budget</span>.*<span.*>\s*(.*)(?:\s*\(estimated\))\s*</span>~Ui';
+ const IMDB_CAST = '~<\/div><a class="ipc-lockup-overlay ipc-focusable" href="\/name\/([^\/]*)\/.*href.*>(.*)<\/a>~Ui';
const IMDB_CAST_IMAGE = '~(loadlate="(.*)"[^>]*><\/a>\s+<\/td>\s+)?<td[^>]*itemprop="actor"[^>]*>\s*<a\s*href="\/name\/([^/]*)\/\?[^"]*"[^>]*>\s*<span.+>(.+)<\/span+~Uis';
- const IMDB_CERTIFICATION = '~<td[^>]*>\s*Certification\s*</td>\s*<td>(.+)</td>~Ui';
- const IMDB_CHAR = '~<td class="character">(?:\s+)<div>(.*)(?:\s+)(?: /| \(.*\)|<\/div>)~Ui';
- const IMDB_COLOR = '~<a href="\/search\/title\?colors=(?:.*)">(.*)<\/a>~Ui';
- const IMDB_COMPANIES = '~production_companies&ref_=(?:.*)">Edit</a>\s+</header>\s+<ul class="simpleList">(.*)Distributors</h4>~Uis';
- const IMDB_COMPANY = '~<li>\s+<a href="\/company\/(co[0-9]+)\/">(.*?)</a>~';
- const IMDB_COUNTRY = '~<a href="/country/(\w+)">(.*)</a>~Ui';
- const IMDB_CREATOR = '~<div[^>]*>\s*(?:Creator|Creators)\s*:\s*<ul[^>]*>(.+)</ul>~Uxsi';
- const IMDB_DISTRIBUTOR = '@href="[^"]*update=[t0-9]+:distributors[^"]*">Edit</a>\s*</header>\s*<ul\s*class="simpleList">(.*):special_effects_companies@Uis';
- const IMDB_DISTRIBUTORS = '@\/company\/(co[0-9]+)\/">(.*?)<\/a>\s+(?:\(([0-9]+)\))?\s+(?:\((.*?)\))?\s+(?:\((.*?)\))?\s+(?:\((?:.*?)\))?\s+</li>@';
- const IMDB_DIRECTOR = '~<div[^>]*>\s*(?:Director|Directors)\s*:\s*<ul[^>]*>(.+)</ul>~Uxsi';
- const IMDB_GENRE = '~href="/genre/([a-zA-Z_-]*)/?">([a-zA-Z_ -]*)</a>~Ui';
- const IMDB_GROSS = '~pl-zebra-list__label">Cumulative Worldwide Gross<\/td>\s+<td>\s+(.*)\s+<~Uxsi';
- const IMDB_ID = '~((?:tt\d{6,})|(?:itle\?\d{6,}))~';
+ const IMDB_CERTIFICATION = '~\?certificates=.*ref_=ttrv_stry">(.+)(?:</span></li></ul></div>|<a\sclass[^>]+\/parentalguide\/[^>]+>)~Ui';
+ const IMDB_CHAR = '~\/characters\/nm\d+\/.*>(.*)<\/a>~Ui';
+ const IMDB_COLOR = '~href="/search/title/\?colors(?:.*)">(.*)<\/a>~Ui';
+ const IMDB_COMPANIES = '~id="production">[\w\s]*?(.*)</section>~Ui';
+ const IMDB_COMPANY = '~href="/company/(co\d+)/\?ref_=ttrv_cmpy_\d">([^<svg].*?)</a><div~';
+ const IMDB_COUNTRY = '~country_of_origin=(.*)&ref_=ttrv_dt_cnt">(.*)<\/a~Ui';
+ const IMDB_CREATOR = '~>\s*(?:Creator|Creators|Producer|Producers).*<ul[^>]*>(.+)</ul>~Uxsi';
+ const IMDB_DISTRIBUTOR = '@<span\sid="distribution".*<ul\sclass[^>]+>(.*)</section>@Uis';
+ const IMDB_DISTRIBUTORS = '@<li.*\/company\/(.*)\/[^>]+>(.*)<.*\((.*),\s*([\d-]+?).*\((.*)\).*</li>@Uis';
+ const IMDB_DIRECTOR = '~id="director".*<ul[^>]*>(.+)</section>~Uxsi';
+ const IMDB_GENRE = '~genres=([a-zA-Z_-]*)&.*<span class="ipc-chip__text">([a-zA-Z_ -]*)<\/span><\/a~Ui';
+ const IMDB_GROSS = '~pl-zebra-list__label">Cumulative Worldwide Gross<\/td>\s*<td>\s*(.*?)\s*<\/td>~i';
+ const IMDB_ID = '~((?:tt\d+)|(?:itle\?\d+))~';
const IMDB_LANGUAGE = '~<a href="\/language\/(\w+)">(.*)<\/a>~Ui';
- const IMDB_LOCATION = '~href="\/search\/title\?locations=(.*)">(.*)<\/a>~Ui';
- const IMDB_LOCATIONS = '~href="\/search\/title\?locations=[^>]*>\s?(.*)\s?<\/a>[^"]*<dd>\s?(.*)\s<\/dd>~Ui';
- const IMDB_MPAA = '~<li class="ipl-inline-list__item">(?:\s+)(TV-Y|TV-Y7|TV-G|TV-PG|TV-14|TV-MA|G|PG|PG-13|R|NC-17|NR|UR)(?:\s+)<\/li>~Ui';
- const IMDB_MUSIC = '~Music by\s*<\/h4>.*<table class=.*>(.*)</table>~Us';
- const IMDB_NAME = '~href="/name/(.+)/?(?:\?[^"]*)?"[^>]*>(.+)</a>~Ui';
+ const IMDB_LOCATION = '~href="/search/title/\?locations=(.*)&.*">(.*)<\/a>~Ui';
+ const IMDB_LOCATIONS = '~href="(?<url>\/search\/title\/\?locations=[^>]*)">\s?(?<location>.*)\s?<\/a><p(.*)>\((?<specification>.*)\)<\/p>~Ui';
+ const IMDB_MPAA = '~<li class="ipl-inline-list__item">(?:\s+)(TV-Y|TV-Y7|TV-Y7-FV|TV-G|TV-PG|TV-14|TV-MA|TV-MA-L|TV-MA-S|TV-MA-V|G|PG|PG-13|R|NC-17|NR|UR|M|X)(?:\s+)<\/li>~Ui';
+ const IMDB_MUSIC = '~id="composer">.*<ul\sclass[^>]+>(.*)</section>~Uxsi';
+ const IMDB_NAME = '~href="/name/(.+)/?(?:\?[^"]*)?"[^>]*>(.+)</a>~Ui';
const IMDB_MOVIE_DESC = '~<section class="titlereference-section-overview">\s+<div>\s+(.*)\s*?</div>\s+<hr>\s+<div class="titlereference-overview-section">~Ui';
const IMDB_SERIES_DESC = '~<div>\s+(?:.*?</a>\s+</span>\s+</div>\s+<hr>\s+<div>\s+)(.*)\s+</div>\s+<hr>\s+<div class="titlereference-overview-section">~Ui';
const IMDB_SERIESEP_DESC = '~All Episodes(?:.*?)</li>\s+(?:.*?)?</ul>\s+</span>\s+<hr>\s+</div>\s+<div>\s+(.*?)\s+</div>\s+<hr>~';
- const IMDB_NOT_FOUND_ADV = '~<span>No results.</span>~Ui';
+ const IMDB_NOT_FOUND_ADV = '~"results-section-empty-results-msg"~Ui';
const IMDB_NOT_FOUND_DES = 'Know what this is about';
const IMDB_NOT_FOUND_ORG = '~<h1 class="findHeader">No results found for ~Ui';
- const IMDB_PLOT = '~<td[^>]*>\s*Plot\s*Summary\s*</td>\s*<td>\s*<p>\s*(.*)\s*</p>~Ui';
- const IMDB_PLOT_KEYWORDS = '~<td[^>]*>Plot\s*Keywords</td>\s*<td>(.+)(?:<a\s*href="/title/[^>]*>[^<]*</a>\s*</li>\s*</ul>\s*)?</td>~Ui';
- const IMDB_POSTER = '~<link\s*rel=\'image_src\'\s*href="(.*)">~Ui';
- const IMDB_RATING = '~class="ipl-rating-star__rating">(.*)<~Ui';
- const IMDB_RATING_COUNT = '~class="ipl-rating-star__total-votes">\((.*)\)<~Ui';
- const IMDB_RELEASE_DATE = '~href="/title/[t0-9]*/releaseinfo">(.*)<~Ui';
- const IMDB_RUNTIME = '~<td[^>]*>\s*Runtime\s*</td>\s*<td>(.+)</td>~Ui';
- const IMDB_SEARCH_ADV = '~text-primary">1[.]</span>\s*<a.href="\/title\/(tt\d{6,})\/(?:.*?)"(?:\s*)>(?:.*?)<\/a>~Ui';
+ const IMDB_PLOT = '~data-testid="plot-l".*>(.*)<\/span>~Ui';
+ const IMDB_PLOT_KEYWORDS = '~explore=keywords.*<span class="ipc-chip__text">(.*)<\/span>~Ui';
+ const IMDB_POSTER = '~<meta property="og:image" content="(.*)"\/>~Ui';
+ const IMDB_RATING = '~"ratingsSummary":{"aggregateRating":(.*),.*}~Ui';
+ const IMDB_RATING_COUNT = '~"ratingsSummary":{.*"voteCount":(\d+),.*}~Ui';
+ const IMDB_RELEASE_DATE = '~\/title\/tt\d+\/releaseinfo\/\?ref_=ttrv_ov_rdat">(.*)</a>~Ui';
+ const IMDB_RUNTIME = '~id="runtime".*<ul[^>]+>(.*)</ul>~Ui';
+ const IMDB_SEARCH_ADV = '~<a href="/title/(tt\d+).*?ipc-title-link-wrapper~i';
const IMDB_SEARCH_ORG = '~find-title-result">(?:.*?)alt="(.*?)"(?:.*?)href="\/title\/(tt\d{6,})\/(?:.*?)">(.*?)<\/a>~';
- const IMDB_SEASONS = '~episodes\?season=(?:\d+)">(\d+)<~Ui';
- const IMDB_SOUND_MIX = '~<td[^>]*>\s*Sound\s*Mix\s*</td>\s*<td>(.+)</td>~Ui';
- const IMDB_TAGLINE = '~<td[^>]*>\s*Taglines\s*</td>\s*<td>(.+)</td>~Ui';
- const IMDB_TITLE = '~itemprop="name">(.*)(<\/h3>|<span)~Ui';
+ const IMDB_SEASONS = '~episodes/\?season=[^>]+>(\d+)<~Ui';
+ const IMDB_SOUND_MIX = '~/search/title/\?sound_mixes.*ref_=spec_2">(.*)</a>~Ui';
+ const IMDB_TAGLINE = '~"taglines":{"edges":\[{"node":{"text":"(.*)","__typename":"Tagline"}~Ui';
+ const IMDB_TITLE = '~<title>(.*)\s*\(.*\)\s*-\sReference\s*view \s*-\s*IMDb</title>~Ui';
const IMDB_TITLE_EP = '~titlereference-watch-ribbon"(?:.*)itemprop="name">(.*?)\s+<span\sclass="titlereference-title-year">~Ui';
- const IMDB_TITLE_ORIG = '~</h3>(?:\s+)(.*)(?:\s+)<span class=\"titlereference-original-title-label~Ui';
+ const IMDB_TITLE_ORIG = '~hero__pageTitle.*hero__primary-text">(.*)</span>~Ui';
const IMDB_TOP250 = '~href="/chart/top(?:tv)?".class(?:.*?)#([0-9]{1,})</a>~Ui';
const IMDB_TRAILER = '~href="/title/(?:tt\d+)/videoplayer/(vi[0-9]*)"~Ui';
- const IMDB_TYPE = '~href="/genre/(?:[a-zA-Z_-]*)/?">(?:[a-zA-Z_ -]*)</a>\s+</li>\s+(?:.*item">)\s+(?:<a href="(?:.*)</a>\s+</li>\s+(?:.*item">)\s+)?([a-zA-Z_ -]*)\s+</li>~Ui';
+ const IMDB_TYPE = '~"titleType":.*"text":"(.*)",~Ui';
const IMDB_URL = '~https?://(?:.*\.|.*)imdb.com/(?:t|T)itle(?:\?|/)(..\d+)~i';
- const IMDB_USER_REVIEW = '~href="/title/[t0-9]*/reviews"[^>]*>([^<]*)\s*User~Ui';
- const IMDB_VOTES = '~"ipl-rating-star__total-votes">\s*\((.*)\)\s*<~Ui';
- const IMDB_WRITER = '~<div[^>]*>\s*(?:Writer|Writers)\s*:\s*<ul[^>]*>(.+)</ul>~Ui';
- const IMDB_YEAR = '~og:title\' content="(?:.*)\((?:.*)(\d{4})(?:.*)\)~Ui';
+ const IMDB_USER_REVIEW = '~href="/title/tt\d+/reviews/\?ref_=ttrv_ov_ururv">(.*)</a>~Ui';
+ const IMDB_VOTES = '~"ratingsSummary":{.*"voteCount":(\d+),.*}~Ui';
+ const IMDB_WRITER = '~>\s*(?:Writer|Writers).*<ul[^>]*>(.+)</ul>~Uxsi';
+ const IMDB_YEAR = '~<title>.*\s*\((?:[^()]+ )?(\d{4}(?:–\d{4})?)\)\s*-\sReference\s*view \s*-\s*IMDb</title>~iU';
/**
* @var string The string returned, if nothing is found.
}
$aCurlInfo = $this->runCurl($this->sUrl);
- $sSource = is_bool($aCurlInfo) ? $aCurlInfo : $aCurlInfo['contents'] ;
+ $sSource = isset($aCurlInfo['contents']) ? $aCurlInfo['contents'] : false;
if (false === $sSource) {
if ($this->IMDB_DEBUG) {
return $this->arrayOutput($this->bArrayOutput, $this->sSeparator, $this->sNotFound, $aReturn);
} else {
- $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo', $this->iId);
+ $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo/', $this->iId);
$aCurlInfo = $this->runCurl($fullAkas);
$sSource = $aCurlInfo['contents'];
if ($aReturned) {
$aReturn = [];
- foreach ($aReturned[1] as $i => $strName) {
+ foreach ($aReturned['url'] as $i => $strName) {
if (strpos($strName, '(') === false) {
- $aReturn[] = [
- 'location' => $this->cleanString($strName),
- ];
- }
- if (strpos($aReturned[2][$i], '(') !== false) {
- $aReturn[] = [
- 'specification' => $this->cleanString($aReturned[2][$i]),
- ];
+ $aReturn[] = [
+ 'url' => IMDBHelper::cleanString($aReturned['url'][$i]),
+ 'location' => IMDBHelper::cleanString($aReturned['location'][$i]),
+ 'specification' => IMDBHelper::cleanString($aReturned['specification'][$i]),
+ ];
}
}
return $this->arrayOutput($this->bArrayOutput, $this->sSeparator, $this->sNotFound, $aReturn);
} else {
- $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo', $this->iId);
+ $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo/', $this->iId);
$aCurlInfo = $this->runCurl($fullAkas);
$sSource = $aCurlInfo['contents'];
echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
}
- return false;
+ return $this->sNotFound;
}
$aReturned = $this->matchRegex(
$sSource,
- '~>(.*)<\/a><\/td>\s+<td class="release_date">(.*)<\/td>~'
+ '~<a class="ipc-metadata-list-item__label[^>]*>([^<]+)</a>.*?<span class="ipc-metadata-list-item__list-content-item"[^>]*>([^<]+)</span>~s'
);
if ($aReturned) {
*/
private function arrayOutput($bArrayOutput, $sSeparator, $sNotFound, $aReturn = '', $bHaveMore = false)
{
- if ($bArrayOutput) {
- if (empty($aReturn) || ! is_array($aReturn)) {
- return [];
- }
-
- if ($bHaveMore) {
- $aReturn[] = '…';
- }
-
- return $aReturn;
- } else {
- if (empty($aReturn) || ! is_array($aReturn)) {
- return $sNotFound;
- }
-
- foreach ($aReturn as $i => $value) {
- if (is_array($value)) {
- $aReturn[$i] = implode($sSeparator, $value);
- }
- }
-
- return implode($sSeparator, $aReturn) . (($bHaveMore) ? '…' : '');
- }
+ if ($aReturn === null) {
+ return $bArrayOutput ? [] : $sNotFound;
+ }
+
+ if ($bArrayOutput) {
+ return $bHaveMore ? [...$aReturn, '…'] : $aReturn;
+ }
+
+ $processValue = fn(mixed $value): string => match (true) {
+ is_array($value) => empty(array_filter($value, fn($v) => $v !== '' && $v !== null))
+ ? $sNotFound
+ : implode($sSeparator, array_map(fn($v) => $v ?: $sNotFound, $value)),
+ $value === '' || $value === null => $sNotFound,
+ default => (string)$value,
+ };
+
+ $result = implode($sSeparator, array_map($processValue, $aReturn));
+ return $bHaveMore ? $result . '…' : $result;
}
/**
[
CURLOPT_CONNECTTIMEOUT => $this->IMDB_TIMEOUT,
CURLOPT_ENCODING => '',
- CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_FRESH_CONNECT => 0,
CURLOPT_HEADER => ($bDownload ? false : true),
CURLOPT_HTTPHEADER => [
if (200 !== $aCurlInfo['http_code']) {
if ($this->IMDB_DEBUG) {
- echo '<pre><b>cURL returned wrong HTTP code “' . $aCurlInfo['http_code'] . '”, aborting.</b></pre>';
+ echo '<pre><b>cURL returned wrong HTTP code “' . $aCurlInfo['http_code'] . '” for “' . $aCurlInfo['url'] . '”, aborting.</b></pre>';
}
return false;