* @license https://opensource.org/licenses/MIT The MIT License * @link https://github.com/FabianBeiner/PHP-IMDB-Grabber/ GitHub Repository * @version 6.2.0 * * * Functionality is the same but modified heavily to remove the does-not-make-sense static helper * which was not static since it depended on the IMDB class. Also some could not be extended or overwritten * */ class IMDB { /** * Set this to true if you run into problems. */ private bool $IMDB_DEBUG = false; /** * @var string Set the preferred language for the User Agent. */ private string $IMDB_BROWSER_LANG; /** * Set this to true if you want to start with normal search and * if you get no result, it will use the advanced method */ const IMDB_SEARCH_ORIGINAL = true; /** * Set this to true if you want to search for exact titles * it falls back to false if theres no result */ const IMDB_EXACT_SEARCH = true; /** * Set the sensitivity for search results in percentage. */ const IMDB_SENSITIVITY = 85; /** * @var string The accept string for curl call */ private string $IMDB_BROWSER_ACCEPT; /** * @var string The user-agent string fpr curl call */ private string $IMDB_BROWSER_AGENT; /** * Define the timeout for cURL requests. */ private int $IMDB_TIMEOUT = 15; /** * 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 = '~
\s*(.*)\s*
~Ui'; const IMDB_PLOT_KEYWORDS = '~Using redirect: ' . basename($sRedirectFile) . ''; } $sRedirect = file_get_contents($sRedirectFile); $this->sUrl = trim($sRedirect); $this->iId = preg_replace('~[\D]~', '', $this->matchRegex($sRedirect, self::IMDB_ID, "1")); $bSearch = false; } } // Does a cache of this movie exist? if(!empty($this->iId)) { $sCacheFile = $this->sRoot . '/cache/' . sha1($this->iId) . '.cache'; if (is_readable($sCacheFile)) { $iDiff = round(abs(time() - filemtime($sCacheFile)) / 60); if ($iDiff < $this->iCache) { if ($this->IMDB_DEBUG) { echo '
Using cache: ' . basename($sCacheFile) . ''; } $this->sSource = file_get_contents($sCacheFile); $this->isReady = true; return true; } } } // Run cURL on the URL. if ($this->IMDB_DEBUG) { echo '
Running cURL: ' . $this->sUrl . ''; } $aCurlInfo = $this->runCurl($this->sUrl); $sSource = is_bool($aCurlInfo) ? $aCurlInfo : $aCurlInfo['contents'] ; if (false === $sSource) { if ($this->IMDB_DEBUG) { echo '
cURL error: ' . var_dump($aCurlInfo) . ''; } return false; } // Was the movie found? $sMatch = $this->matchRegex($sSource, self::IMDB_SEARCH_ADV, "1"); if (false !== $sMatch) { $sUrl = 'https://www.imdb.com/title/' . $sMatch . '/reference'; if ($this->IMDB_DEBUG) { echo '
New redirect saved: ' . basename($sRedirectFile) . ' => ' . $sUrl . ''; } file_put_contents($sRedirectFile, $sUrl); $this->sSource = ''; $this->fetchUrl($sUrl); return true; } $sMatch = $this->matchRegex($sSource, self::IMDB_NOT_FOUND_ADV, "0"); if (false !== $sMatch) { if ($this->IMDB_DEBUG) { echo '
Movie not found: ' . $sSearch . ''; } return false; } $this->sSource = str_replace( [ "\n", "\r\n", "\r", ], '', $sSource ); $this->isReady = true; // Save cache. if (false === $bSearch) { if ($this->IMDB_DEBUG) { echo '
Cache created: ' . basename($sCacheFile) . ''; } file_put_contents($sCacheFile, $this->sSource); } return true; } /** * @return array All data. */ public function getAll(): array { $aData = []; foreach (get_class_methods(__CLASS__) as $method) { if (substr($method, 0, 3) === 'get' && $method !== 'getAll' && $method !== 'getCastImages') { if(!empty($this->_showFields) && !in_array($method,$this->_showFields)) continue; $aData[$method] = [ 'name' => ltrim($method, 'get'), 'value' => $this->{$method}(), ]; } } array_multisort($aData); return $aData; } /** * @return string “Also Known As” or $sNotFound. */ public function getAka(): string { if (true === $this->isReady) { $sMatch = $this->matchRegex($this->sSource, self::IMDB_AKA, "1"); if (false !== $sMatch) { return $this->cleanString($sMatch); } } return $this->sNotFound; } /** * Returns all local names * * @return string All local names. */ public function getAkas() { if (true === $this->isReady) { // Does a cache of this movie exist? $sCacheFile = $this->sRoot . '/cache/' . sha1($this->iId) . '_akas.cache'; $bUseCache = false; if (is_readable($sCacheFile)) { $iDiff = round(abs(time() - filemtime($sCacheFile)) / 60); if ($iDiff < $this->iCache || false) { $bUseCache = true; } } if ($bUseCache) { $aRawReturn = file_get_contents($sCacheFile); $aReturn = unserialize($aRawReturn); return $this->arrayOutput($this->bArrayOutput, $this->sSeparator, $this->sNotFound, $aReturn); } else { $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo', $this->iId); $aCurlInfo = $this->runCurl($fullAkas); $sSource = $aCurlInfo['contents']; if (false === $sSource) { if ($this->IMDB_DEBUG) { echo '
cURL error: ' . var_dump($aCurlInfo) . ''; } return false; } $aReturned = $this->matchRegex($sSource, "~
cURL error: ' . var_dump($aCurlInfo) . ''; } return false; } $aReturned = $this->matchRegex($sSource, self::IMDB_LOCATIONS); if ($aReturned) { $aReturn = []; foreach ($aReturned[1] 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]), ]; } } file_put_contents($sCacheFile, serialize($aReturn)); return $this->arrayOutput($this->bArrayOutput, $this->sSeparator, $this->sNotFound, $aReturn); } } } return $this->arrayOutput($this->bArrayOutput, $this->sSeparator, $this->sNotFound); } /** * @return string The MPAA of the movie or $sNotFound. */ public function getMpaa() { if (true === $this->isReady) { $sMatch = $this->matchRegex($this->sSource, self::IMDB_MPAA, "1"); if (false !== $sMatch) { return $this->cleanString($sMatch); } } return $this->sNotFound; } /** * @return string A list with the plot keywords or $sNotFound. */ public function getPlotKeywords() { if (true === $this->isReady) { $sMatch = $this->matchRegex($this->sSource, self::IMDB_PLOT_KEYWORDS, "1"); if (false !== $sMatch) { $aReturn = explode('|', $this->cleanString($sMatch)); return $this->arrayOutput($this->bArrayOutput, $this->sSeparator, $this->sNotFound, $aReturn); } } return $this->arrayOutput($this->bArrayOutput, $this->sSeparator, $this->sNotFound); } /** * @param int $iLimit The limit. * * @return string The plot of the movie or $sNotFound. */ public function getPlot($iLimit = 0) { if (true === $this->isReady) { $sMatch = $this->matchRegex($this->sSource, self::IMDB_PLOT, "1"); if (false !== $sMatch) { if ($iLimit !== 0) { return $this->shortText($this->cleanString($sMatch), $iLimit); } return $this->cleanString($sMatch); } } return $this->sNotFound; } /** * @param string $sSize Small, big, xxs, xs, s poster? * @param bool $bDownload Return URL to the poster or download it? * * @return bool|string Path to the poster. */ public function getPoster($sSize = 'small', $bDownload = false) { if (true === $this->isReady) { $sMatch = $this->matchRegex($this->sSource, self::IMDB_POSTER, "1"); if (false !== $sMatch) { if ('big' === strtolower($sSize) && false !== strstr($sMatch, '@._')) { $sMatch = substr($sMatch, 0, strpos($sMatch, '@._')) . '@.jpg'; } if ('xxs' === strtolower($sSize) && false !== strstr($sMatch, '@._')) { $sMatch = substr($sMatch, 0, strpos($sMatch, '@._')) . '@._V1_UY67_CR0,0,45,67_AL_.jpg'; } if ('xs' === strtolower($sSize) && false !== strstr($sMatch, '@._')) { $sMatch = substr($sMatch, 0, strpos($sMatch, '@._')) . '@._V1_UY113_CR0,0,76,113_AL_.jpg'; } if ('s' === strtolower($sSize) && false !== strstr($sMatch, '@._')) { $sMatch = substr($sMatch, 0, strpos($sMatch, '@._')) . '@._V1_UX182_CR0,0,182,268_AL_.jpg'; } if (false === $bDownload) { return $this->cleanString($sMatch); } else { $sLocal = $this->saveImage($sMatch, $this->iId); if (file_exists(dirname(__FILE__) . '/' . $sLocal)) { return $sLocal; } else { return $sMatch; } } } } return $this->sNotFound; } /** * @return string The rating of the movie or $sNotFound. */ public function getRating() { if (true === $this->isReady) { $sMatch = $this->matchRegex($this->sSource, self::IMDB_RATING, "1"); if (false !== $sMatch) { return $this->cleanString($sMatch); } } return $this->sNotFound; } /** * @return string The rating count of the movie or $sNotFound. */ public function getRatingCount() { if (true === $this->isReady) { $sMatch = $this->matchRegex($this->sSource, self::IMDB_RATING_COUNT, "1"); if (false !== $sMatch) { return str_replace(',', '', $this->cleanString($sMatch)); } } return $this->sNotFound; } /** * Release date doesn't contain all the information we need to create a media and * we need this function that checks if users can vote target media (if can, it's released). * * @return true If the media is released */ public function isReleased() { $strReturn = $this->getReleaseDate(); if ($strReturn == $this->sNotFound || $strReturn == 'Not yet released') { return false; } return true; } /** * @return string The release date of the movie or $sNotFound. */ public function getReleaseDate() { if (true === $this->isReady) { $sMatch = $this->matchRegex($this->sSource, self::IMDB_RELEASE_DATE, "1"); if (false !== $sMatch) { return $this->cleanString($sMatch); } } return $this->sNotFound; } /** * Returns all local names * * @return string country * @return string release date */ public function getReleaseDates() { if (true === $this->isReady) { // Does a cache of this movie exist? $sCacheFile = $this->sRoot . '/cache/' . sha1($this->iId) . '_akas.cache'; $bUseCache = false; if (is_readable($sCacheFile)) { $iDiff = round(abs(time() - filemtime($sCacheFile)) / 60); if ($iDiff < $this->iCache || false) { $bUseCache = true; } } if ($bUseCache) { $aRawReturn = file_get_contents($sCacheFile); $aReturn = unserialize($aRawReturn); return $this->arrayOutput($this->bArrayOutput, $this->sSeparator, $this->sNotFound, $aReturn); } else { $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo', $this->iId); $aCurlInfo = $this->runCurl($fullAkas); $sSource = $aCurlInfo['contents']; if (false === $sSource) { if ($this->IMDB_DEBUG) { echo '
cURL error: ' . var_dump($aCurlInfo) . ''; } return false; } $aReturned = $this->matchRegex( $sSource, '~>(.*)<\/a><\/td>\s+
cURL returned wrong HTTP code “' . $aCurlInfo['http_code'] . '”, aborting.'; } return false; } return $aCurlInfo; } /** * @param string $sUrl The URL to the image to download. * @param int $cId The cast ID of the actor. * * @return string Local path. */ private function saveImageCast($sUrl, $cId) { if ( ! preg_match('~http~', $sUrl)) { return 'cast/not-found.jpg'; } $sFilename = $this->sRoot . '/cast/' . $cId . '.jpg'; if (file_exists($sFilename)) { return 'cast/' . $cId . '.jpg'; } $aCurlInfo = $this->runCurl($sUrl, true); $sData = $aCurlInfo['contents']; if (false === $sData) { return 'cast/not-found.jpg'; } $oFile = fopen($sFilename, 'x'); fwrite($oFile, $sData); fclose($oFile); return 'cast/' . $cId . '.jpg'; } /** * Makes strings with $this->sSeparator as separator result in an array * * @param $string * @return array|string */ public function slashStringAsArray($string) { $ret = $string; if(strstr($string, $this->sSeparator)) { $ret = array(); $_t = explode($this->sSeparator, $string); foreach ($_t as $v) { $v = trim($v); if(!empty($v)) { $ret[] = $v; } } } return $ret; } }