1 | <?php |
||||
2 | |||||
3 | namespace mQueue\Model; |
||||
4 | |||||
5 | use DOMDocument; |
||||
6 | use DOMXPath; |
||||
7 | use Exception; |
||||
8 | use Zend_Date; |
||||
9 | |||||
10 | /** |
||||
11 | * A movie |
||||
12 | */ |
||||
13 | class Movie extends AbstractModel |
||||
14 | { |
||||
15 | /** |
||||
16 | * Extract IMDb id from URL |
||||
17 | * |
||||
18 | * @param string $string |
||||
19 | * |
||||
20 | * @return null|string the id extracted |
||||
21 | */ |
||||
22 | 2 | public static function extractId(?string $string): ?string |
|||
23 | { |
||||
24 | 2 | if (!$string) { |
|||
25 | 2 | return null; |
|||
26 | } |
||||
27 | |||||
28 | 1 | $string = self::paddedId($string); |
|||
29 | 1 | preg_match_all("/(\d{7,})/", $string, $r); |
|||
30 | 1 | if (isset($r[1][0])) { |
|||
31 | 1 | return $r[1][0]; |
|||
32 | } |
||||
33 | |||||
34 | return null; |
||||
35 | } |
||||
36 | |||||
37 | /** |
||||
38 | * Returns the ID for IMDb with padded 0 |
||||
39 | * |
||||
40 | * @param string $id |
||||
41 | * |
||||
42 | * @return string the id extracted |
||||
43 | */ |
||||
44 | 1 | public static function paddedId(string $id): string |
|||
45 | { |
||||
46 | 1 | return str_pad($id, 7, '0', STR_PAD_LEFT); |
|||
47 | } |
||||
48 | |||||
49 | /** |
||||
50 | * Returns the title, if needed fetch the title from IMDb |
||||
51 | * |
||||
52 | * @return string |
||||
53 | */ |
||||
54 | 1 | public function getTitle() |
|||
55 | { |
||||
56 | // If we didn't get the title yet, fetch it and save in our database |
||||
57 | 1 | if (!($this->title)) { |
|||
58 | $this->fetchData(); |
||||
59 | } |
||||
60 | |||||
61 | 1 | return $this->title; |
|||
62 | } |
||||
63 | |||||
64 | /** |
||||
65 | * Fetch data from IMDb and store in database (possibly overwriting) |
||||
66 | */ |
||||
67 | public function fetchData(): void |
||||
68 | { |
||||
69 | $ch = curl_init($this->getImdbUrl()); |
||||
70 | curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept-Language: en-US,en;q=0.8']); |
||||
71 | curl_setopt($ch, CURLOPT_HEADER, false); |
||||
72 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); |
||||
73 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
||||
74 | |||||
75 | $file = curl_exec($ch); |
||||
76 | curl_close($ch); |
||||
77 | |||||
78 | $document = new DOMDocument(); |
||||
79 | @$document->loadHTML($file); |
||||
0 ignored issues
–
show
It seems like
$file can also be of type true ; however, parameter $source of DOMDocument::loadHTML() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
80 | $xpath = new DOMXPath($document); |
||||
81 | |||||
82 | // Extract title |
||||
83 | $titleEntries = $xpath->evaluate('//meta[contains(@property, "og:title")]/@content'); |
||||
84 | if ($titleEntries->length == 1) { |
||||
85 | $rawTitle = $titleEntries->item(0)->value; |
||||
86 | $this->title = preg_replace('~ - IMDb$~', '', $rawTitle); |
||||
0 ignored issues
–
show
|
|||||
87 | } else { |
||||
88 | $this->title = '[title not available, could not fetch from IMDb]'; |
||||
89 | |||||
90 | return; // If there is not even title give up everything |
||||
91 | } |
||||
92 | |||||
93 | // Extract release date |
||||
94 | $jsonLd = $xpath->evaluate('//script[@type="application/ld+json"]/text()'); |
||||
95 | if ($jsonLd->length == 1) { |
||||
96 | $json = json_decode($jsonLd->item(0)->data, true); |
||||
97 | $this->dateRelease = $json['datePublished'] ?? null; |
||||
0 ignored issues
–
show
|
|||||
98 | } else { |
||||
99 | $this->dateRelease = null; |
||||
100 | } |
||||
101 | |||||
102 | $this->dateUpdate = Zend_Date::now()->get(Zend_Date::ISO_8601); |
||||
0 ignored issues
–
show
|
|||||
103 | $this->setReadOnly(false); // If the movie is coming from a joined query, we need to set non-readonly before saving |
||||
104 | $this->save(); |
||||
105 | } |
||||
106 | |||||
107 | /** |
||||
108 | * Sets the ID for the movie from any string containing a valid ID |
||||
109 | * |
||||
110 | * @param string $id |
||||
111 | * |
||||
112 | * @return Movie |
||||
113 | */ |
||||
114 | public function setId($id) |
||||
115 | { |
||||
116 | $extractedId = self::extractId($id); |
||||
117 | if (!$extractedId) { |
||||
118 | throw new Exception(sprintf('Invalid Id for movie. Given "%1$s", extracted "%2$s"', $id, $extractedId)); |
||||
119 | } |
||||
120 | |||||
121 | $this->id = $extractedId; |
||||
0 ignored issues
–
show
|
|||||
122 | |||||
123 | return $this; |
||||
124 | } |
||||
125 | |||||
126 | /** |
||||
127 | * Returns the IMDb url for the movie |
||||
128 | * |
||||
129 | * @return string |
||||
130 | */ |
||||
131 | public function getImdbUrl(): string |
||||
132 | { |
||||
133 | return 'https://www.imdb.com/title/tt' . self::paddedId($this->id) . '/'; |
||||
134 | } |
||||
135 | |||||
136 | /** |
||||
137 | * Returns the status for this movie and the specified user |
||||
138 | * |
||||
139 | * @param User $user |
||||
140 | * |
||||
141 | * @return Status |
||||
142 | */ |
||||
143 | public function getStatus(User $user = null) |
||||
144 | { |
||||
145 | return StatusMapper::find($this->id, $user); |
||||
146 | } |
||||
147 | |||||
148 | /** |
||||
149 | * Set the status for the specified user |
||||
150 | * |
||||
151 | * @param User $user |
||||
152 | * @param int $rating @see \mQueue\Model\Status |
||||
153 | * |
||||
154 | * @return Status |
||||
155 | */ |
||||
156 | public function setStatus(User $user, $rating) |
||||
157 | { |
||||
158 | $status = StatusMapper::set($this, $user, $rating); |
||||
159 | |||||
160 | return $status; |
||||
161 | } |
||||
162 | |||||
163 | /** |
||||
164 | * Set the source for the movie if any. In any case record the search date and count |
||||
165 | * |
||||
166 | * @param array|false $source |
||||
167 | */ |
||||
168 | public function setSource($source): void |
||||
169 | { |
||||
170 | $this->dateSearch = Zend_Date::now()->get(Zend_Date::ISO_8601); |
||||
0 ignored issues
–
show
|
|||||
171 | ++$this->searchCount; |
||||
0 ignored issues
–
show
The property
searchCount does not exist on mQueue\Model\Movie . Since you implemented __get , consider adding a @property annotation.
![]() |
|||||
172 | if ($source && @$source['score']) { |
||||
173 | $this->identity = $source['identity']; |
||||
0 ignored issues
–
show
|
|||||
174 | $this->quality = $source['quality']; |
||||
0 ignored issues
–
show
|
|||||
175 | $this->score = $source['score']; |
||||
0 ignored issues
–
show
|
|||||
176 | $this->source = $source['link']; |
||||
0 ignored issues
–
show
|
|||||
177 | } |
||||
178 | } |
||||
179 | } |
||||
180 |
If you suppress an error, we recommend checking for the error condition explicitly: