12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504 |
- <?php
- /**
- * PHP IMDb.com Grabber
- *
- * This PHP library enables you to scrape data from IMDB.com.
- *
- *
- * If you want to thank me for this library, please buy me something at Amazon
- * (https://www.amazon.de/hz/wishlist/ls/8840JITISN9L/) or use
- * https://www.paypal.me/FabianBeiner. Thank you! 🙌
- *
- * @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
- */
- class IMDB
- {
- /**
- * Set this to true if you run into problems.
- */
- const IMDB_DEBUG = false;
- /**
- * Set the preferred language for the User Agent.
- */
- const IMDB_LANG = 'en-US,en;q=0.9';
- /**
- * 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;
- /**
- * Define the timeout for cURL requests.
- */
- const 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 = '~<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_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_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_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_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_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_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_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_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';
- /**
- * @var string The string returned, if nothing is found.
- */
- public static $sNotFound = 'n/A';
- /**
- * @var null|int The ID of the movie.
- */
- public $iId = null;
- /**
- * @var bool Is the content ready?
- */
- public $isReady = false;
- /**
- * @var string Char that separates multiple entries.
- */
- public $sSeparator = ' / ';
- /**
- * @var null|string The URL to the movie.
- */
- public $sUrl = null;
- /**
- * @var bool Return responses enclosed in array
- */
- public $bArrayOutput = false;
- /**
- * @var int Maximum cache time.
- */
- private $iCache = 1440;
- /**
- * @var null|string The root of the script.
- */
- private $sRoot = null;
- /**
- * @var null|string Holds the source.
- */
- private $sSource = null;
- /**
- * @var string What to search for?
- */
- private $sSearchFor = 'all';
- /**
- * @param string $sSearch IMDb URL or movie title to search for.
- * @param null $iCache Custom cache time in minutes.
- * @param string $sSearchFor What to search for?
- *
- * @throws Exception
- */
- public function __construct($sSearch, $iCache = null, $sSearchFor = 'all')
- {
- $this->sRoot = dirname(__FILE__);
- if ( ! is_writable($this->sRoot . '/posters') && ! mkdir($this->sRoot . '/posters')) {
- throw new Exception('The directory “' . $this->sRoot . '/posters” isn’t writable.');
- }
- if ( ! is_writable($this->sRoot . '/cache') && ! mkdir($this->sRoot . '/cache')) {
- throw new Exception('The directory “' . $this->sRoot . '/cache” isn’t writable.');
- }
- if ( ! is_writable($this->sRoot . '/cast') && ! mkdir($this->sRoot . '/cast')) {
- throw new Exception('The directory “' . $this->sRoot . '/cast” isn’t writable.');
- }
- if ( ! function_exists('curl_init')) {
- throw new Exception('You need to enable the PHP cURL extension.');
- }
- if (in_array(
- $sSearchFor,
- [
- 'movie',
- 'tv',
- 'episode',
- 'game',
- 'documentary',
- 'all',
- ]
- )) {
- $this->sSearchFor = $sSearchFor;
- }
- if (true === self::IMDB_DEBUG) {
- ini_set('display_errors', 1);
- ini_set('display_startup_errors', 1);
- error_reporting(-1);
- echo '<pre><b>Running:</b> fetchUrl("' . $sSearch . '")</pre>';
- }
- if (null !== $iCache && (int) $iCache > 0) {
- $this->iCache = (int) $iCache;
- }
- if (self::IMDB_EXACT_SEARCH) {
- if ($this->fetchUrl($sSearch, self::IMDB_SEARCH_ORIGINAL, true)) {
- return true;
- }
- }
- if ($this->fetchUrl($sSearch, self::IMDB_SEARCH_ORIGINAL)) {
- return true;
- }
- if ($this->fetchUrl($sSearch, !self::IMDB_SEARCH_ORIGINAL)) {
- return true;
- }
- }
- /**
- * @param string $sSearch IMDb URL or movie title to search for.
- *
- * @return bool True on success, false on failure.
- */
- private function fetchUrl($sSearch, $orgSearch = false, $exactSearch = false)
- {
- $sSearch = trim($sSearch);
- // Try to find a valid URL.
- $sId = IMDBHelper::matchRegex($sSearch, self::IMDB_ID, 1);
- if (false !== $sId) {
- $this->iId = preg_replace('~[\D]~', '', $sId);
- $this->sUrl = 'https://www.imdb.com/title/tt' . $this->iId . '/reference';
- $bSearch = false;
- } else {
- if (!$orgSearch) {
- switch (strtolower($this->sSearchFor)) {
- case 'movie':
- $sParameters = '&title_type=feature';
- break;
- case 'tv':
- $sParameters = '&title_type=tv_movie,tv_series,tv_special,tv_miniseries';
- break;
- case 'episode':
- $sParameters = '&title_type=tv_episode';
- break;
- case 'game':
- $sParameters = '&title_type=video_game';
- break;
- case 'documentary':
- $sParameters = '&title_type=documentary';
- break;
- case 'video':
- $sParameters = '&title_type=video';
- break;
- default:
- $sParameters = '';
- }
- if (preg_match('~([^0-9+])\(?([0-9]{4})\)?~', $sSearch, $fMatch)) {
- $sParameters .= '&release_date=' . $fMatch[2] . '-01-01,' . $fMatch[2] . '-12-31';
- $sSearch = preg_replace('~([^0-9+])\(?([0-9]{4})\)?~','', $sSearch);
- }
- $this->sUrl = 'https://www.imdb.com/search/title/?title=' . rawurlencode(str_replace(' ', '+', $sSearch)) . $sParameters;
- } else {
- switch (strtolower($this->sSearchFor)) {
- case 'movie':
- $sParameters = '&s=tt&ttype=ft';
- break;
- case 'tv':
- $sParameters = '&s=tt&ttype=tv';
- break;
- case 'episode':
- $sParameters = '&s=tt&ttype=ep';
- break;
- case 'game':
- $sParameters = '&s=tt&ttype=vg';
- break;
- default:
- $sParameters = '&s=tt';
- }
- if (preg_match('~([^0-9+])\(?([0-9]{4})\)?~', $sSearch, $fMatch)) {
- $sYear = $fMatch[2];
- $sTempSearch = preg_replace('~([^0-9+])\(?([0-9]{4})\)?~','', $sSearch);
- $sSearch = $sTempSearch . ' (' . $sYear . ')';
- }
- if ($exactSearch) {
- $sParameters .= '&exact=true';
- }
- $this->sUrl = 'https://www.imdb.com/find/?q=' . rawurlencode(str_replace(' ', ' ', $sSearch)) . $sParameters;
- }
- $bSearch = true;
- // Was this search already performed and cached?
- $sRedirectFile = $this->sRoot . '/cache/' . sha1($this->sUrl) . '.redir';
- if (is_readable($sRedirectFile)) {
- if (self::IMDB_DEBUG) {
- echo '<pre><b>Using redirect:</b> ' . basename($sRedirectFile) . '</pre>';
- }
- $sRedirect = file_get_contents($sRedirectFile);
- $this->sUrl = trim($sRedirect);
- $this->iId = preg_replace('~[\D]~', '', IMDBHelper::matchRegex($sRedirect, self::IMDB_ID, 1));
- $bSearch = false;
- }
- }
- // Does a cache of this movie exist?
- if (! is_null($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 (true === self::IMDB_DEBUG) {
- echo '<pre><b>Using cache:</b> ' . basename($sCacheFile) . '</pre>';
- }
- $this->sSource = file_get_contents($sCacheFile);
- $this->isReady = true;
- return true;
- }
- }
- }
- // Run cURL on the URL.
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>Running cURL:</b> ' . $this->sUrl . '</pre>';
- }
- $aCurlInfo = IMDBHelper::runCurl($this->sUrl);
- $sSource = $aCurlInfo['contents'];
- if (false === $sSource) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
- }
- return false;
- }
- if (!$orgSearch) {
- // Was the movie found?
- $sMatch = IMDBHelper::matchRegex($sSource, self::IMDB_SEARCH_ADV, 1);
- if (false !== $sMatch) {
- $sUrl = 'https://www.imdb.com/title/' . $sMatch . '/reference';
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>New redirect saved:</b> ' . basename($sRedirectFile) . ' => ' . $sUrl . '</pre>';
- }
- file_put_contents($sRedirectFile, $sUrl);
- $this->sSource = null;
- self::fetchUrl($sUrl);
- return true;
- }
- $sMatch = IMDBHelper::matchRegex($sSource, self::IMDB_NOT_FOUND_ADV, 0);
- if (false !== $sMatch) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>Movie not found:</b> ' . $sSearch . '</pre>';
- }
- return false;
- }
- } else {
- $aReturned = IMDBHelper::matchRegex($sSource, self::IMDB_SEARCH_ORG);
- if ($aReturned) {
- $rData = [];
- $fTempPercent = 0.00;
- $iTempId = "";
- $sYear = 0;
- if (preg_match('~([^0-9+])\(?([0-9]{4})\)?~', $sSearch, $fMatch)) {
- $sYear = $fMatch[2];
- $sTempSearch = preg_replace('~([^0-9+])\(?([0-9]{4})\)?~','', $sSearch);
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>YEAR:</b> ' . $sTempSearch . ' => ' . $sYear . '</pre>';
- }
- }
- foreach ($aReturned[1] as $i => $value) {
- $sId = $aReturned[2][$i];
- $sTitle = $aReturned[3][$i];
- $perc = 0.00;
- $year = 0;
- if ($sYear === 0) {
- $sim = similar_text($sSearch, $sTitle, $perc);
- } else {
- $sMatch = IMDBHelper::matchRegex($aReturned[1][$i], '~\(?([0-9]{4})\)?~', 1);
- if (false !== $sMatch) {
- $year = $sMatch;
- }
- if ($sYear != $year) {
- continue;
- }
- $sim = similar_text($sTempSearch, $sTitle, $perc);
- }
- $rData[] = [
- 'id' => $sId,
- 'title' => $sTitle,
- 'year' => $year,
- 'match' => floatval($perc)
- ];
- }
- if (sizeof($rData) === 0) {
- return false;
- }
- if (true === self::IMDB_DEBUG) {
- foreach ($rData as $sArray) {
- echo '<pre><b>Found results:</b> ' . $sArray['id'] . ' => ' . $sArray['title'] . ' (' . $sArray['match']. '%) </pre>';
- }
- }
- //get highest match of search results
- $matches = array_column($rData, 'match');
- $maxv = max($matches);
- $marray = array_filter($rData, function($item) use ($maxv) {
- return $item['match'] == $maxv;
- });
- $marray = reset($marray);
- if (sizeof($marray) > 0) {
- if (!$exactSearch && round($marray['match'], 0) < self::IMDB_SENSITIVITY) {
- echo '<pre><b>Bad sensitivity:</b> ' . $marray['id'] . ' => ' . $marray['title'] . ' (' . $marray['match']. '%) </pre>';
- return false;
- }
- $sUrl = 'https://www.imdb.com/title/' . $marray['id'] . '/reference';
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>Get best result:</b> ' . $marray['title'] . ' ' . $marray['id'] . ' => ' . $marray['match'] . '% </pre>';
- echo '<pre><b>New redirect saved:</b> ' . basename($sRedirectFile) . ' => ' . $sUrl . '</pre>';
- }
- file_put_contents($sRedirectFile, $sUrl);
- $this->sSource = null;
- self::fetchUrl($sUrl);
- return true;
- }
- }
- $sMatch = IMDBHelper::matchRegex($sSource, self::IMDB_NOT_FOUND_ORG, 0);
- if (false !== $sMatch) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>Movie not found:</b> ' . $sSearch . '</pre>';
- }
- return false;
- }
- return false;
- }
- $this->sSource = str_replace(
- [
- "\n",
- "\r\n",
- "\r",
- ],
- '',
- $sSource
- );
- $this->isReady = true;
- // Save cache.
- if (false === $bSearch) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>Cache created:</b> ' . basename($sCacheFile) . '</pre>';
- }
- file_put_contents($sCacheFile, $this->sSource);
- }
- return true;
- }
- /**
- * @return array All data.
- */
- public function getAll()
- {
- $aData = [];
- foreach (get_class_methods(__CLASS__) as $method) {
- if (substr($method, 0, 3) === 'get' && $method !== 'getAll' && $method !== 'getCastImages') {
- $aData[$method] = [
- 'name' => ltrim($method, 'get'),
- 'value' => $this->{$method}(),
- ];
- }
- }
- array_multisort($aData);
- return $aData;
- }
- /**
- * @return string “Also Known As” or $sNotFound.
- */
- public function getAka()
- {
- if (true === $this->isReady) {
- $aReturn = [];
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_AKA, 1);
- if (false !== $sMatch) {
- $aReturn[] = explode('|', IMDBHelper::cleanString($sMatch));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$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 IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- } else {
- $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo', $this->iId);
- $aCurlInfo = IMDBHelper::runCurl($fullAkas);
- $sSource = $aCurlInfo['contents'] ?? false;
- if (false === $sSource) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
- }
- return false;
- }
- $aReturned = IMDBHelper::matchRegex($sSource, "~<td class=\"aka-item__name\">(.*?)<\/td>\s+<td class=\"aka-item__title\">(.*?)<\/td>~");
- if ($aReturned) {
- $aReturn = [];
- foreach ($aReturned[1] ?? [] as $i => $strName) {
- if (strpos($strName, '(') === false) {
- $aReturn[] = [
- 'title' => IMDBHelper::cleanString($aReturned[2][$i]),
- 'country' => IMDBHelper::cleanString($strName),
- ];
- }
- }
- file_put_contents($sCacheFile, serialize($aReturn));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * Returns meta score
- *
- * @return string metascore
- * @return string reviews
- */
- public function getMetaScore()
- {
- if (true === $this->isReady) {
- // Does a cache of this movie exist?
- $sCacheFile = $this->sRoot . '/cache/' . sha1($this->iId) . '_metascore.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 IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- } else {
- $fullCritics = sprintf('https://www.imdb.com/title/tt%s/criticreviews', $this->iId);
- $aCurlInfo = IMDBHelper::runCurl($fullCritics);
- $sSource = $aCurlInfo['contents'] ?? false;
- if (false === $sSource) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
- }
- return false;
- }
- $aReturned = IMDBHelper::matchRegex(
- $sSource,
- '~metascore_wrap(?:.*)\s+(?:.*)\s+(?:.*)ratingValue\">([0-9]+)<\/span>(?:\s+(?:.*)){4}ratingCount\">([0-9]+)~'
- );
- if ($aReturned) {
- $aReturn = [];
- $aReturn[] = [
- 'metascore' => IMDBHelper::cleanString($aReturned[1][0]),
- 'reviews' => IMDBHelper::cleanString($aReturned[2][0]),
- ];
- file_put_contents($sCacheFile, serialize($aReturn));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * Returns Critic Reviews based on Metascore
- *
- * @return string rating
- * @return string url
- * @return string publisher
- * @return string author
- * @return string review
- */
- public function getMetaCritics()
- {
- if (true === $this->isReady) {
- // Does a cache of this movie exist?
- $sCacheFile = $this->sRoot . '/cache/' . sha1($this->iId) . '_criticreviews.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 IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- } else {
- $fullCritics = sprintf('https://www.imdb.com/title/tt%s/criticreviews', $this->iId);
- $aCurlInfo = IMDBHelper::runCurl($fullCritics);
- $sSource = $aCurlInfo['contents'] ?? false;
- if (false === $sSource) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
- }
- return false;
- }
- $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>~'
- );
- if ($aReturned) {
- $aReturn = [];
- foreach ($aReturned[1] as $i => $strScore) {
- $aReturn[] = [
- 'rating' => IMDBHelper::cleanString($strScore),
- 'url' => IMDBHelper::cleanString($aReturned[2][$i]),
- 'publisher' => IMDBHelper::cleanString($aReturned[3][$i]),
- 'author' => IMDBHelper::cleanString($aReturned[4][$i]),
- 'review' => IMDBHelper::cleanString($aReturned[5][$i]),
- ];
- }
- file_put_contents($sCacheFile, serialize($aReturn));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string “Aspect Ratio” or $sNotFound.
- */
- public function getAspectRatio()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_ASPECT_RATIO, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The awards of the movie or $sNotFound.
- */
- public function getAwards()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_AWARDS, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param int $iLimit How many cast members should be returned?
- * @param bool $bMore Add … if there are more cast members than printed.
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with linked cast members or $sNotFound.
- */
- public function getCastAsUrl($iLimit = 0, $bMore = true, $sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_CAST);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- if (0 !== $iLimit && $i >= $iLimit) {
- break;
- }
- $aReturn[] = '<a href="https://www.imdb.com/name/' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- $bHaveMore = ($bMore && (count($aMatch[2]) > $iLimit));
- return IMDBHelper::arrayOutput(
- $this->bArrayOutput,
- $this->sSeparator,
- self::$sNotFound,
- $aReturn,
- $bHaveMore
- );
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param int $iLimit How many cast members should be returned?
- * @param bool $bMore Add … if there are more cast members than printed.
- *
- * @return string A list with cast members or $sNotFound.
- */
- public function getCast($iLimit = 0, $bMore = true)
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_CAST);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- if (0 !== $iLimit && $i >= $iLimit) {
- break;
- }
- $aReturn[] = IMDBHelper::cleanString($sName);
- }
- $bMore = (0 !== $iLimit && $bMore && (count($aMatch[2]) > $iLimit) ? '…' : '');
- $bHaveMore = ($bMore && (count($aMatch[2]) > $iLimit));
- return IMDBHelper::arrayOutput(
- $this->bArrayOutput,
- $this->sSeparator,
- self::$sNotFound,
- $aReturn,
- $bHaveMore
- );
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @param int $iLimit How many cast images should be returned?
- * @param bool $bMore Add … if there are more cast members than printed.
- * @param string $sSize small, mid or big cast images
- * @param bool $bDownload Return URL or Download
- *
- * @return array Array with cast name as key, and image as value.
- */
- public function getCastImages($iLimit = 0, $bMore = true, $sSize = 'small', $bDownload = false)
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_CAST_IMAGE);
- $aReturn = [];
- if (count($aMatch[4])) {
- foreach ($aMatch[4] as $i => $sName) {
- if (0 !== $iLimit && $i >= $iLimit) {
- break;
- }
- $sMatch = $aMatch[2][$i];
- if ('big' === strtolower($sSize) && false !== strstr($aMatch[2][$i], '@._')) {
- $sMatch = substr($aMatch[2][$i], 0, strpos($aMatch[2][$i], '@._')) . '@.jpg';
- } elseif ('mid' === strtolower($sSize) && false !== strstr($aMatch[2][$i], '@._')) {
- $sMatch = substr($aMatch[2][$i], 0, strpos($aMatch[2][$i], '@._')) . '@._V1_UX214_AL_.jpg';
- }
- if (false === $bDownload) {
- $sMatch = IMDBHelper::cleanString($sMatch);
- } else {
- $sLocal = IMDBHelper::saveImageCast($sMatch, $aMatch[3][$i]);
- if (file_exists(dirname(__FILE__) . '/' . $sLocal)) {
- $sMatch = $sLocal;
- } else {
- //the 'big' image isn't available, try the 'mid' one (vice versa)
- if ('big' === strtolower($sSize) && false !== strstr($aMatch[2][$i], '@._')) {
- //trying the 'mid' one
- $sMatch = substr(
- $aMatch[2][$i],
- 0,
- strpos($aMatch[2][$i], '@._')
- ) . '@._V1_UX214_AL_.jpg';
- } else {
- //trying the 'big' one
- $sMatch = substr($aMatch[2][$i], 0, strpos($aMatch[2][$i], '@._')) . '@.jpg';
- }
- $sLocal = IMDBHelper::saveImageCast($sMatch, $aMatch[3][$i]);
- if (file_exists(dirname(__FILE__) . '/' . $sLocal)) {
- $sMatch = $sLocal;
- } else {
- $sMatch = IMDBHelper::cleanString($aMatch[2][$i]);
- }
- }
- }
- $aReturn[IMDBHelper::cleanString($aMatch[4][$i])] = $sMatch;
- }
- $bMore = (0 !== $iLimit && $bMore && (count($aMatch[4]) > $iLimit) ? '…' : '');
- $bHaveMore = ($bMore && (count($aMatch[4]) > $iLimit));
- $aReturn = array_replace(
- $aReturn,
- array_fill_keys(
- array_keys($aReturn, self::$sNotFound),
- 'cast/not-found.jpg'
- )
- );
- return $aReturn;
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @param int $iLimit How many cast members should be returned?
- * @param bool $bMore Add … if there are more cast members than
- * printed.
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with linked cast members and their character or
- * $sNotFound.
- */
- public function getCastAndCharacterAsUrl($iLimit = 0, $bMore = true, $sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_CAST);
- $aMatchChar = IMDBHelper::matchRegex($this->sSource, self::IMDB_CHAR);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- if (0 !== $iLimit && $i >= $iLimit) {
- break;
- }
- $sChar = str_replace(' / ', ' and ', $aMatchChar[1][$i]);
- $aReturn[] = '<a href="https://www.imdb.com/name/' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a> as ' . IMDBHelper::cleanString($sChar);
- }
- $bHaveMore = ($bMore && (count($aMatch[2]) > $iLimit));
- return IMDBHelper::arrayOutput(
- $this->bArrayOutput,
- $this->sSeparator,
- self::$sNotFound,
- $aReturn,
- $bHaveMore
- );
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @param int $iLimit How many cast members should be returned?
- * @param bool $bMore Add … if there are more cast members than printed.
- *
- * @return string A list with cast members and their character or
- * $sNotFound.
- */
- public function getCastAndCharacter($iLimit = 0, $bMore = true)
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_CAST);
- $aMatchChar = IMDBHelper::matchRegex($this->sSource, self::IMDB_CHAR);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- if (0 !== $iLimit && $i >= $iLimit) {
- break;
- }
- $sChar = str_replace(' / ', ' and ', $aMatchChar[1][$i]);
- $aReturn[] = IMDBHelper::cleanString($sName) . ' as ' . IMDBHelper::cleanString($sChar);
- }
- $bHaveMore = ($bMore && (count($aMatch[2]) > $iLimit));
- return IMDBHelper::arrayOutput(
- $this->bArrayOutput,
- $this->sSeparator,
- self::$sNotFound,
- $aReturn,
- $bHaveMore
- );
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string The certification of the movie or $sNotFound.
- */
- public function getCertification()
- {
- if (true === $this->isReady) {
- $aReturn = [];
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_CERTIFICATION, 1);
- if (false !== $sMatch) {
- $aReturn[] = explode('|', IMDBHelper::cleanString($sMatch));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string Color or $sNotFound.
- */
- public function getColor()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_COLOR, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The company producing the movie or $sNotFound.
- */
- public function getCompany()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getCompanyAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string The linked company producing the movie or $sNotFound.
- */
- public function getCompanyAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_COMPANIES);
- $aReturn = [];
- if (isset($aMatch[1][0])) {
- $bMatch = IMDBHelper::matchRegex($aMatch[1][0], self::IMDB_COMPANY);
- if (count($bMatch[2])) {
- foreach ($bMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/company/' . IMDBHelper::cleanString(
- $bMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string A list with countries or $sNotFound.
- */
- public function getCountry()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getCountryAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with linked countries or $sNotFound.
- */
- public function getCountryAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_COUNTRY);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/country/' . trim(
- $aMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string A list with the creators or $sNotFound.
- */
- public function getCreator()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getCreatorAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked creators or $sNotFound.
- */
- public function getCreatorAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_CREATOR, 1);
- $aMatch = IMDBHelper::matchRegex($sMatch, self::IMDB_NAME);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/name/' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string The description of the movie or $sNotFound.
- */
- public function getDescription()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_SERIESEP_DESC, 1);
- if (false !== $sMatch) {
- if (strpos($sMatch, self::IMDB_NOT_FOUND_DES) === false) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_SERIES_DESC, 1);
- if (false !== $sMatch) {
- if (strpos($sMatch, self::IMDB_NOT_FOUND_DES) === false) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_MOVIE_DESC, 1);
- if (false !== $sMatch) {
- if (strpos($sMatch, self::IMDB_NOT_FOUND_DES) === false) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string A list with the directors or $sNotFound.
- */
- public function getDirector()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getDirectorAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked directors or $sNotFound.
- */
- public function getDirectorAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_DIRECTOR, 1);
- $aMatch = IMDBHelper::matchRegex($sMatch, self::IMDB_NAME);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/name/' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return array A list (name, url, year, country, type) with Distributors or $sNotFound.
- */
- public function getDistributor($iLimit = 0, $bMore = true)
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_DISTRIBUTOR);
- $aReturn = [];
- if (isset($aMatch[1][0])) {
- $bMatch = IMDBHelper::matchRegex($aMatch[1][0], self::IMDB_DISTRIBUTORS);
- if (count($bMatch[2])) {
- foreach ($bMatch[2] as $i => $sName) {
- if (0 !== $iLimit && $i >= $iLimit) {
- break;
- }
- $aReturn[] = [
- 'distributor' => IMDBHelper::cleanString($sName),
- 'url' => 'https://www.imdb.com/company/' . IMDBHelper::cleanString($bMatch[1][$i]) .'',
- 'year' => IMDBHelper::cleanString($bMatch[3][$i]),
- 'country' => IMDBHelper::cleanString($bMatch[4][$i]),
- 'type' => IMDBHelper::cleanString($bMatch[5][$i]),
- ];
- }
- $bMore = (0 !== $iLimit && $bMore && (count($aMatch[2]) > $iLimit) ? '…' : '');
- $bHaveMore = ($bMore && (count($aMatch[2]) > $iLimit));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn, $bHaveMore);
- }
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked distributors or $sNotFound.
- */
- public function getDistributorAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_DISTRIBUTOR);
- $aReturn = [];
- if (isset($aMatch[1][0])) {
- $bMatch = IMDBHelper::matchRegex($aMatch[1][0], self::IMDB_DISTRIBUTORS);
- if (count($bMatch[2])) {
- foreach ($bMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/company/' . IMDBHelper::cleanString(
- $bMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string The episode title of the tv show or $sNotFound.
- */
- public function getEpisodeTitle()
- {
- if (true === $this->isReady) {
- if (preg_match('/Episode/i', $this->getType())) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_TITLE_EP, 1);
- if (false !== $sMatch && "" !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string A list with the genres or $sNotFound.
- */
- public function getGenre()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getGenreAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked genres or $sNotFound.
- */
- public function getGenreAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_GENRE);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach (array_unique($aMatch[2]) as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/search/title?genres=' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string cumulative worldwide gross or $sNotFound.
- */
- public function getGross()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_GROSS, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string A list with the languages or $sNotFound.
- */
- public function getLanguage()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getLanguageAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked languages or $sNotFound.
- */
- public function getLanguageAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_LANGUAGE);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/language/' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string A list with the location or $sNotFound.
- */
- public function getLocation()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getLocationAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked location or $sNotFound.
- */
- public function getLocationAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_LOCATION);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/search/title?locations=' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * Returns all locations
- *
- * @return string location
- * @return string specification
- */
- public function getLocations()
- {
- if (true === $this->isReady) {
- // Does a cache of this movie exist?
- $sCacheFile = $this->sRoot . '/cache/' . sha1($this->iId) . '_locations.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 IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- } else {
- $fullLocations = sprintf('https://www.imdb.com/title/tt%s/locations', $this->iId);
- $aCurlInfo = IMDBHelper::runCurl($fullLocations);
- $sSource = $aCurlInfo['contents'] ?? false;
- if (false === $sSource) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
- }
- return false;
- }
- $aReturned = IMDBHelper::matchRegex($sSource, self::IMDB_LOCATIONS);
- if ($aReturned) {
- $aReturn = [];
- foreach ($aReturned[1] 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]),
- ];
- }
- }
- file_put_contents($sCacheFile, serialize($aReturn));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string The MPAA of the movie or $sNotFound.
- */
- public function getMpaa()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_MPAA, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string A list with the music composers or $sNotFound.
- */
- public function getMusic()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getMusicAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked music composers or $sNotFound.
- */
- public function getMusicAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_MUSIC, 1);
- $aMatch = IMDBHelper::matchRegex($sMatch, self::IMDB_NAME);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/name/' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @param int $iLimit How many photo images should be returned?
- * @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.
- */
- public function getPhotos($iLimit = 0, $bMore = true, $sSize = 'small')
- {
- if (true === $this->isReady) {
- // Does a cache of this movie exist?
- $sCacheFile = $this->sRoot . '/cache/' . sha1($this->iId) . '_gallery.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);
- $anReturn = [];
- foreach ($aReturn as $i => $sAreturn) {
- if (0 !== $iLimit && $i >= $iLimit) {
- break;
- }
- $title = $sAreturn['title'];
- $url = $sAreturn['url'];
- if ('big' === strtolower($sSize) && false !== strstr($url, '._')) {
- $url = substr($url, 0, strpos($url, '._')) . '.jpg';
- }
- $anReturn[] = [
- 'title' => $title,
- 'url' => $url,
- ];
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $anReturn);
- } else {
- $isPage = true;
- $aReturn = [];
- $page = 1;
- while ($isPage) {
- $fullPhotos = sprintf('https://www.imdb.com/title/tt%s/mediaindex?page=%d', $this->iId, $page);
- $aCurlInfo = IMDBHelper::runCurl($fullPhotos);
- $sSource = $aCurlInfo['contents'];
- if (false === $sSource) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
- }
- return false;
- }
- $aReturned = IMDBHelper::matchRegex($sSource, '~title="(.*?)"\s+><img(?:.*)\s+src="(.*?)"\s+\/>~');
- if ($aReturned) {
- foreach ($aReturned[1] as $i => $strName) {
- $aReturn[] = [
- 'title' => IMDBHelper::cleanString($strName),
- 'url' => IMDBHelper::cleanString($aReturned[2][$i]),
- ];
- }
- }
- file_put_contents($sCacheFile, serialize($aReturn));
- if (!preg_match('~class="prevnext"\s>Next~', $sSource)) {
- $isPage = false;
- }
- $page++;
- }
- $anReturn = [];
- foreach ($aReturn as $i => $sAreturn) {
- if (0 !== $iLimit && $i >= $iLimit) {
- break;
- }
- $title = $sAreturn['title'];
- $url = $sAreturn['url'];
- if ('big' === strtolower($sSize) && false !== strstr($url, '._')) {
- $url = substr($url, 0, strpos($url, '._')) . '.jpg';
- }
- $anReturn[] = [
- 'title' => $title,
- 'url' => $url,
- ];
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $anReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string A list with the plot keywords or $sNotFound.
- */
- public function getPlotKeywords()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_PLOT_KEYWORDS, 1);
- if (false !== $sMatch) {
- $aReturn = explode('|', IMDBHelper::cleanString($sMatch));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$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 = IMDBHelper::matchRegex($this->sSource, self::IMDB_PLOT, 1);
- if (false !== $sMatch) {
- if ($iLimit !== 0) {
- return IMDBHelper::getShortText(IMDBHelper::cleanString($sMatch), $iLimit);
- }
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$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 = IMDBHelper::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 IMDBHelper::cleanString($sMatch);
- } else {
- $sLocal = IMDBHelper::saveImage($sMatch, $this->iId);
- if (file_exists(dirname(__FILE__) . '/' . $sLocal)) {
- return $sLocal;
- } else {
- return $sMatch;
- }
- }
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The rating of the movie or $sNotFound.
- */
- public function getRating()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_RATING, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The rating count of the movie or $sNotFound.
- */
- public function getRatingCount()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_RATING_COUNT, 1);
- if (false !== $sMatch) {
- return str_replace(',', '', IMDBHelper::cleanString($sMatch));
- }
- }
- return self::$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 == self::$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 = IMDBHelper::matchRegex($this->sSource, self::IMDB_RELEASE_DATE, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$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) . '_dates.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 IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- } else {
- $fullAkas = sprintf('https://www.imdb.com/title/tt%s/releaseinfo', $this->iId);
- $aCurlInfo = IMDBHelper::runCurl($fullAkas);
- $sSource = $aCurlInfo['contents'] ?? false;
- if (false === $sSource) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
- }
- return false;
- }
- $aReturned = IMDBHelper::matchRegex(
- $sSource,
- '~>(.*)\s+<\/a><\/td>\s+<td class=\"release-date-item__date\" align=\"right\">(.*)<\/td>~'
- );
- if ($aReturned) {
- $aReturn = [];
- foreach ($aReturned[1] as $i => $strName) {
- if (strpos($strName, '(') === false) {
- $aReturn[] = [
- 'country' => IMDBHelper::cleanString($strName),
- 'releasedate' => IMDBHelper::cleanString($aReturned[2][$i]),
- ];
- }
- }
- file_put_contents($sCacheFile, serialize($aReturn));
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string The runtime of the movie or $sNotFound.
- */
- public function getRuntime()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_RUNTIME, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string A list with the seasons or $sNotFound.
- */
- public function getSeasons()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getSeasonsAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked seasons or $sNotFound.
- */
- public function getSeasonsAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $aMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_SEASONS);
- $aReturn = [];
- if (count($aMatch[1])) {
- foreach (range(1, max($aMatch[1])) as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/title/tt' . $this->iId . '/episodes?season=' . $sName . '"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . $sName . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- * @return string The sound mix of the movie or $sNotFound.
- */
- public function getSoundMix()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_SOUND_MIX, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The tagline of the movie or $sNotFound.
- */
- public function getTagline()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_TAGLINE, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param bool $bForceLocal Try to return the original name of the movie.
- *
- * @return string The title of the movie or $sNotFound.
- */
- public function getTitle($bForceLocal = false)
- {
- if (true === $this->isReady) {
- if (true === $bForceLocal) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_TITLE_ORIG, 1);
- if (false !== $sMatch && "" !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_TITLE, 1);
- $sMatch = preg_replace('~\(\d{4}\)$~Ui', '', $sMatch);
- if (false !== $sMatch && "" !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string returns the given position at top-250 or $sNotFound.
- */
- public function getTop250()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_TOP250, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param bool $bEmbed Link to player directly?
- *
- * @return string The URL to the trailer of the movie or $sNotFound.
- */
- public function getTrailerAsUrl($bEmbed = false)
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_TRAILER, 1);
- if (false !== $sMatch) {
- if ($bEmbed) {
- $sUrl = 'https://www.imdb.com/video/imdb/' . $sMatch . '/imdb/embed';
- } else {
- $sUrl = 'https://www.imdb.com/video/' . $sMatch;
- }
- return IMDBHelper::cleanString($sUrl);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return array Array with season, episode, title, rating, votes, airdate, plot, id.
- */
- public function getTVInfo()
- {
- if (true === $this->isReady) {
- // Does a cache of this movie exist?
- $sCacheFile = $this->sRoot . '/cache/' . sha1($this->iId) . '_tv.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);
- $anReturn = [];
- foreach ($aReturn as $i => $sAreturn) {
- $season = $sAreturn['season'];
- $episode = $sAreturn['episode'];
- $title = $sAreturn['title'];
- $rating = $sAreturn['rating'];
- $votes = $sAreturn['votes'];
- $airdate = $sAreturn['airdate'];
- $plot = $sAreturn['plot'];
- $id = $sAreturn['id'];
- $anReturn[] = [
- 'season' => $season,
- 'episode' => $episode,
- 'title' => $title,
- 'rating' => $rating,
- 'votes' => $votes,
- 'airdate' => $airdate,
- 'plot' => $plot,
- 'id' => $id
- ];
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $anReturn);
- } else {
- $isPage = true;
- $aReturn = [];
- $page = 1;
- while ($isPage) {
- $fullEpisodes = sprintf('https://www.imdb.com/title/tt%s/episodes/?season=%d', $this->iId, $page);
- $aCurlInfo = IMDBHelper::runCurl($fullEpisodes);
- $sSource = $aCurlInfo['contents'];
- if (false === $sSource) {
- if (true === self::IMDB_DEBUG) {
- echo '<pre><b>cURL error:</b> ' . var_dump($aCurlInfo) . '</pre>';
- }
- return false;
- }
- $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]),
- ];
- }
- }
- }
- }
- file_put_contents($sCacheFile, serialize($aReturn));
- if (preg_match('~href="\?season=-1~s', $sSource) || !preg_match('~id="load_next_episodes"~', $sSource)) {
- break;
- }
- $page++;
- }
- $anReturn = [];
- foreach ($aReturn as $i => $sAreturn) {
- $season = $sAreturn['season'];
- $episode = $sAreturn['episode'];
- $title = $sAreturn['title'];
- $rating = $sAreturn['rating'];
- $votes = $sAreturn['votes'];
- $airdate = $sAreturn['airdate'];
- $plot = $sAreturn['plot'];
- $id = $sAreturn['id'];
- $anReturn[] = [
- 'season' => $season,
- 'episode' => $episode,
- 'title' => $title,
- 'rating' => $rating,
- 'votes' => $votes,
- 'airdate' => $airdate,
- 'plot' => $plot,
- 'id' => $id
- ];
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $anReturn);
- }
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound);
- }
- /**
- *
- * @return string type of the title or $sNotFound.
- */
- public function getType()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_TYPE, 1);
- if (false !== $sMatch && "" !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The IMDb URL.
- */
- public function getUrl()
- {
- if (true === $this->isReady) {
- return IMDBHelper::cleanString(str_replace('reference', '', $this->sUrl));
- }
- return self::$sNotFound;
- }
- /**
- * @return string The user review of the movie or $sNotFound.
- */
- public function getUserReview()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_USER_REVIEW, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The votes of the movie or $sNotFound.
- */
- public function getVotes()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_VOTES, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string A list with the writers or $sNotFound.
- */
- public function getWriter()
- {
- if (true === $this->isReady) {
- $sMatch = $this->getWriterAsUrl();
- if (self::$sNotFound !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @param string $sTarget Add a target to the links?
- *
- * @return string A list with the linked writers or $sNotFound.
- */
- public function getWriterAsUrl($sTarget = '')
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_WRITER, 1);
- $aMatch = IMDBHelper::matchRegex($sMatch, self::IMDB_NAME);
- $aReturn = [];
- if (count($aMatch[2])) {
- foreach ($aMatch[2] as $i => $sName) {
- $aReturn[] = '<a href="https://www.imdb.com/name/' . IMDBHelper::cleanString(
- $aMatch[1][$i]
- ) . '/"' . ($sTarget ? ' target="' . $sTarget . '"' : '') . '>' . IMDBHelper::cleanString(
- $sName
- ) . '</a>';
- }
- return IMDBHelper::arrayOutput($this->bArrayOutput, $this->sSeparator, self::$sNotFound, $aReturn);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The year of the movie or $sNotFound.
- */
- public function getYear()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_YEAR, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- /**
- * @return string The budget of the movie or $sNotFound.
- */
- public function getBudget()
- {
- if (true === $this->isReady) {
- $sMatch = IMDBHelper::matchRegex($this->sSource, self::IMDB_BUDGET, 1);
- if (false !== $sMatch) {
- return IMDBHelper::cleanString($sMatch);
- }
- }
- return self::$sNotFound;
- }
- }
- class IMDBHelper extends IMDB
- {
- /**
- * Regular expression helper.
- *
- * @param string $sContent The content to search in.
- * @param string $sPattern The regular expression.
- * @param null $iIndex The index to return.
- *
- * @return bool If no match was found.
- * @return string If one match was found.
- * @return array If more than one match was found.
- */
- public static function matchRegex($sContent, $sPattern, $iIndex = null)
- {
- preg_match_all($sPattern, $sContent ?? '', $aMatches);
- if ($aMatches === false) {
- return false;
- }
- if ($iIndex !== null && is_int($iIndex)) {
- if (isset($aMatches[$iIndex][0])) {
- return $aMatches[$iIndex][0];
- }
- return false;
- }
- return $aMatches;
- }
- /**
- * Preferred output in responses with multiple elements
- *
- * @param bool $bArrayOutput Native array or string with separators.
- * @param string $sSeparator String separator.
- * @param string $sNotFound Not found text.
- * @param array $aReturn Original input.
- * @param bool $bHaveMore Have more elements indicator.
- *
- * @return string|array Multiple results separated by selected separator string, or enclosed into native array.
- */
- public static function arrayOutput($bArrayOutput, $sSeparator, $sNotFound, $aReturn = null, $bHaveMore = false)
- {
- if ($bArrayOutput ?? false) {
- if ($aReturn == null || ! is_array($aReturn)) {
- return [];
- }
- if ($bHaveMore) {
- $aReturn[] = '…';
- }
- return $aReturn;
- } else {
- if ($aReturn == null || ! is_array($aReturn)) {
- return $sNotFound;
- }
- foreach ($aReturn as $i => $value) {
- if (is_array($value)) {
- $aReturn[$i] = implode($sSeparator, $value);
- }
- }
- return implode($sSeparator, $aReturn) . (($bHaveMore) ? '…' : '');
- }
- }
- /**
- * @param string $sInput Input (eg. HTML).
- *
- * @return string Cleaned string.
- */
- public static function cleanString($sInput)
- {
- $aSearch = [
- 'Full summary »',
- 'Full synopsis »',
- 'Add summary »',
- 'Add synopsis »',
- 'See more »',
- 'See why on IMDbPro.',
- "\n",
- "\r",
- ];
- $aReplace = [
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- '',
- ];
- $sInput = str_replace('</li>', ' | ', $sInput ?? '');
- $sInput = strip_tags($sInput ?? '');
- $sInput = str_replace(' ', ' ', $sInput ?? '');
- $sInput = str_replace($aSearch, $aReplace, $sInput ?? '');
- $sInput = html_entity_decode($sInput ?? '', ENT_QUOTES | ENT_HTML5);
- $sInput = preg_replace('/\s+/', ' ', $sInput ?? '');
- $sInput = trim($sInput ?? '');
- $sInput = rtrim($sInput ?? '', ' |');
- return ($sInput ? trim($sInput ?? '') : self::$sNotFound);
- }
- /**
- * @param string $sText The long text.
- * @param int $iLength The maximum length of the text.
- *
- * @return string The shortened text.
- */
- public static function getShortText($sText, $iLength = 100)
- {
- if (mb_strlen($sText) <= $iLength) {
- return $sText;
- }
- list($sShort) = explode("\n", wordwrap($sText, $iLength - 1));
- if (substr($sShort, -1) !== '.') {
- return $sShort . '…';
- }
- return $sShort;
- }
- /**
- * @param string $sUrl The URL to the image to download.
- * @param int $iId The ID of the movie.
- *
- * @return string Local path.
- */
- public static function saveImage($sUrl, $iId)
- {
- if (preg_match('~title_addposter.jpg|imdb-share-logo.png~', $sUrl)) {
- return 'posters/not-found.jpg';
- }
- $sFilename = dirname(__FILE__) . '/posters/' . $iId . '.jpg';
- if (file_exists($sFilename)) {
- return 'posters/' . $iId . '.jpg';
- }
- $aCurlInfo = self::runCurl($sUrl, true);
- $sData = $aCurlInfo['contents'];
- if (false === $sData) {
- return 'posters/not-found.jpg';
- }
- $oFile = fopen($sFilename, 'x');
- fwrite($oFile, $sData);
- fclose($oFile);
- return 'posters/' . $iId . '.jpg';
- }
- /**
- * @param string $sUrl The URL to fetch.
- * @param bool $bDownload Download?
- *
- * @return bool|mixed Array on success, false on failure.
- */
- public static function runCurl($sUrl, $bDownload = false)
- {
- $oCurl = curl_init($sUrl);
- curl_setopt_array(
- $oCurl,
- [
- CURLOPT_BINARYTRANSFER => ($bDownload ? true : false),
- CURLOPT_CONNECTTIMEOUT => self::IMDB_TIMEOUT,
- CURLOPT_ENCODING => '',
- CURLOPT_FOLLOWLOCATION => 0,
- CURLOPT_FRESH_CONNECT => 0,
- CURLOPT_HEADER => ($bDownload ? false : true),
- CURLOPT_HTTPHEADER => [
- 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
- 'Accept-Charset: utf-8, iso-8859-1;q=0.5',
- 'Accept-Language: ' . self::IMDB_LANG,
- ],
- CURLOPT_REFERER => 'https://www.imdb.com',
- CURLOPT_RETURNTRANSFER => 1,
- CURLOPT_SSL_VERIFYHOST => 0,
- CURLOPT_SSL_VERIFYPEER => 0,
- CURLOPT_TIMEOUT => self::IMDB_TIMEOUT,
- CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0',
- CURLOPT_VERBOSE => 0,
- ]
- );
- $sOutput = curl_exec($oCurl);
- $aCurlInfo = curl_getinfo($oCurl);
- curl_close($oCurl);
- $aCurlInfo['contents'] = $sOutput;
- 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>';
- }
- 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.
- */
- public static function saveImageCast($sUrl, $cId)
- {
- if ( ! preg_match('~http~', $sUrl)) {
- return 'cast/not-found.jpg';
- }
- $sFilename = dirname(__FILE__) . '/cast/' . $cId . '.jpg';
- if (file_exists($sFilename)) {
- return 'cast/' . $cId . '.jpg';
- }
- $aCurlInfo = self::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';
- }
- }
|