Completed
Push — master ( 3ac19d...cb4b66 )
by Adrien
02:36
created

Movie::getStatus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace mQueue\Model;
4
5
use DOMDocument;
6
use DOMXPath;
7
use Exception;
8
use Zend_Date;
9
use Zend_Registry;
10
11
/**
12
 * A movie
13
 */
14
class Movie extends AbstractModel
15
{
16
    /**
17
     * All known IMDb hostnames indexed by their language
18
     *
19
     * @var array
20
     */
21
    public static $imdbHostnames = [
22
        'en' => 'www.imdb.com',
23
        'fr' => 'www.imdb.fr',
24
        'de' => 'www.imdb.de',
25
        'es' => 'www.imdb.es',
26
        'it' => 'www.imdb.it',
27
        'pt' => 'www.imdb.pt',
28
        'akas' => 'akas.imdb.com',
29
    ];
30
31
    /**
32
     * Extract IMDb id from URL
33
     *
34
     * @param string $string
35
     *
36
     * @return null|string the id extracted
37
     */
38 2
    public static function extractId($string)
39
    {
40 2
        preg_match_all("/(\d{7,8})/", $string, $r);
41 2
        if (isset($r[1][0])) {
42 1
            return $r[1][0];
43
        }
44
45 2
        return null;
46
    }
47
48
    /**
49
     * Returns the title, if needed fetch the title from IMDb
50
     *
51
     * @return string
52
     */
53 1
    public function getTitle()
54
    {
55
        // If we didn't get the title yet, fetch it and save in our database
56 1
        if (!($this->title)) {
0 ignored issues
show
Documentation introduced by
The property title does not exist on object<mQueue\Model\Movie>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
57
            $this->fetchData();
58
        }
59
60 1
        return $this->title;
0 ignored issues
show
Documentation introduced by
The property title does not exist on object<mQueue\Model\Movie>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
61
    }
62
63
    /**
64
     * Fetch data from IMDb and store in database (possibly overwriting)
65
     */
66
    public function fetchData(): void
67
    {
68
        $ch = curl_init($this->getImdbUrl('akas'));
69
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept-Language: en-US,en;q=0.8']);
70
        curl_setopt($ch, CURLOPT_HEADER, false);
71
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
72
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
73
74
        $file = curl_exec($ch);
75
        curl_close($ch);
76
77
        $document = new DOMDocument();
78
        @$document->loadHTML($file);
79
        $xpath = new DOMXPath($document);
80
81
        // Extract title
82
        $titleEntries = $xpath->evaluate('//meta[contains(@property, "og:title")]/@content');
83
        if ($titleEntries->length == 1) {
84
            $rawTitle = $titleEntries->item(0)->value;
85
            $this->title = preg_replace('~ - IMDb$~', '', $rawTitle);
0 ignored issues
show
Documentation introduced by
The property title does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
86
        } else {
87
            $this->title = '[title not available, could not fetch from IMDb]';
0 ignored issues
show
Documentation introduced by
The property title does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
88
89
            return; // If there is not even title give up everything
90
        }
91
92
        // Extract release date
93
        $dateReleaseEntries = $xpath->evaluate('//*[@id="overview-top"]//meta[contains(@itemprop, "datePublished")]/@content');
94
        if ($dateReleaseEntries->length == 1) {
95
            $this->dateRelease = $dateReleaseEntries->item(0)->value;
0 ignored issues
show
Documentation introduced by
The property dateRelease does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
96
        } else {
97
            $this->dateRelease = null;
0 ignored issues
show
Documentation introduced by
The property dateRelease does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
98
        }
99
100
        $this->dateUpdate = Zend_Date::now()->get(Zend_Date::ISO_8601);
0 ignored issues
show
Documentation introduced by
The property dateUpdate does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
101
        $this->setReadOnly(false); // If the movie is coming from a joined query, we need to set non-readonly before saving
102
        $this->save();
103
    }
104
105
    /**
106
     * Sets the ID for the movie from any string containing a valid ID
107
     *
108
     * @param string $id
109
     *
110
     * @return \mQueue\Model\Movie
111
     */
112
    public function setId($id)
113
    {
114
        $extractedId = self::extractId($id);
115
        if (!$extractedId) {
116
            throw new Exception(sprintf('Invalid Id for movie. Given "%1$s", extracted "%2$s"', $id, $extractedId));
117
        }
118
119
        $this->id = $extractedId;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
120
121
        return $this;
122
    }
123
124
    /**
125
     * Returns the IMDb url for the movie
126
     *
127
     * @param string $lang suggested language for hostname
0 ignored issues
show
Documentation introduced by
Should the type for parameter $lang not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
128
     *
129
     * @return string
130
     */
131
    public function getImdbUrl($lang = null)
132
    {
133
        if ($lang == null) {
134
            $lang = Zend_Registry::get('Zend_Locale')->getLanguage();
135
        }
136
137
        if (isset(self::$imdbHostnames[$lang])) {
138
            $hostname = self::$imdbHostnames[$lang];
139
        } else {
140
            $hostname = reset(self::$imdbHostnames);
141
        }
142
143
        return 'http://' . $hostname . '/title/tt' . $this->id . '/';
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<mQueue\Model\Movie>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
144
    }
145
146
    /**
147
     * Returns the status for this movie and the specified user
148
     *
149
     * @param \mQueue\Model\User $user
0 ignored issues
show
Documentation introduced by
Should the type for parameter $user not be null|User?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
150
     *
151
     * @return \mQueue\Model\Status
152
     */
153
    public function getStatus(User $user = null)
154
    {
155
        return StatusMapper::find($this->id, $user);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<mQueue\Model\Movie>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
156
    }
157
158
    /**
159
     * Set the status for the specified user
160
     *
161
     * @param \mQueue\Model\User $user
162
     * @param int $rating @see \mQueue\Model\Status
163
     *
164
     * @return \mQueue\Model\Status
165
     */
166
    public function setStatus(User $user, $rating)
167
    {
168
        $status = StatusMapper::set($this, $user, $rating);
169
170
        return $status;
171
    }
172
173
    /**
174
     * Set the source for the movie if any. In any case record the search date and count
175
     *
176
     * @param array|false $source
177
     */
178
    public function setSource($source): void
179
    {
180
        $this->dateSearch = Zend_Date::now()->get(Zend_Date::ISO_8601);
0 ignored issues
show
Documentation introduced by
The property dateSearch does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
181
        ++$this->searchCount;
0 ignored issues
show
Documentation introduced by
The property searchCount does not exist on object<mQueue\Model\Movie>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
182
        if ($source && @$source['score']) {
183
            $this->identity = $source['identity'];
0 ignored issues
show
Documentation introduced by
The property identity does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
184
            $this->quality = $source['quality'];
0 ignored issues
show
Documentation introduced by
The property quality does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
185
            $this->score = $source['score'];
0 ignored issues
show
Documentation introduced by
The property score does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
186
            $this->source = $source['link'];
0 ignored issues
show
Documentation introduced by
The property source does not exist on object<mQueue\Model\Movie>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
187
        }
188
    }
189
}
190