MovieMapper::findAllForFetching()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 14
ccs 0
cts 9
cp 0
rs 10
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
namespace mQueue\Model;
4
5
use Zend_Date;
6
use Zend_Db_Expr;
7
use Zend_Db_Table_Select;
8
9
abstract class MovieMapper extends AbstractMapper
10
{
11
    /**
12
     * Returns a movie by its ID
13
     *
14
     * @param int $id
15
     *
16
     * @return null|Movie
17
     */
18 16
    public static function find($id)
19
    {
20 16
        $result = self::getDbTable()->find([$id]);
21
22 16
        return $result->current();
23
    }
24
25
    /**
26
     * Returns all movies
27
     *
28
     * @return Movie[]
29
     */
30
    public static function fetchAll()
31
    {
32
        $resultSet = self::getDbTable()->fetchAll();
33
34
        return $resultSet;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $resultSet returns the type Zend_Db_Table_Rowset_Abstract which is incompatible with the documented return type mQueue\Model\Movie[].
Loading history...
35
    }
36
37
    /**
38
     * Returns movies for search
39
     *
40
     * @return Movie[]
41
     */
42
    public static function findAllForSearch()
43
    {
44
        $futureYears = [];
45
        $date = Zend_Date::now();
46
        for ($i = 0; $i < 10; ++$i) {
47
            $date->addYear(1);
48
            $futureYears[] = $date->get(Zend_Date::YEAR_8601);
49
        }
50
51
        $select = self::getDbTable()->select()->setIntegrityCheck(false)
52
            ->from('movie')
53
            ->join('status', 'status.idMovie = movie.id AND status.isLatest AND rating = ' . Status::Need, [])
54
            ->where('source IS NULL')
55
            ->where('dateSearch IS NULL OR dateSearch < DATE_SUB(NOW(), INTERVAL searchCount MONTH)')// Search for same movie with an incrementally longer interval (1 month, 2 month, 3 month, etc.)
56
            ->where('dateRelease IS NOT NULL')// Movie must be released ...
57
            ->where('dateRelease < DATE_SUB(NOW(), INTERVAL 1 MONTH)')// ...at least released one month ago, or longer
58
            ->group('movie.id')
59
            ->order('COUNT(movie.id) DESC')// First, order by popularity, so get the most needed first
60
            ->order('RAND() ASC')// Then, randomize a little bit so we don't always look for the same movies
61
            ->limit(5);
62
63
        $records = self::getDbTable()->fetchAll($select);
64
65
        return $records;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $records returns the type Zend_Db_Table_Rowset_Abstract which is incompatible with the documented return type mQueue\Model\Movie[].
Loading history...
66
    }
67
68
    /**
69
     * Returns movies for data fetching
70
     *
71
     * @param int $limit
72
     *
73
     * @return Movie[]
74
     */
75
    public static function findAllForFetching($limit = null)
76
    {
77
        $select = self::getDbTable()->select()->setIntegrityCheck(false)
78
            ->from('movie')
79
            ->where('dateUpdate IS NULL OR dateUpdate < DATE_SUB(NOW(), INTERVAL 1 MONTH)')// Don't fetch data for movies, more than once a month
80
            ->order('RAND()'); // Randomize order, so we don't watch only old movies
81
82
        if ($limit) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $limit of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
83
            $select->limit(20);
84
        }
85
86
        $records = self::getDbTable()->fetchAll($select);
87
88
        return $records;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $records returns the type Zend_Db_Table_Rowset_Abstract which is incompatible with the documented return type mQueue\Model\Movie[].
Loading history...
89
    }
90
91
    /**
92
     * Returns a query filtered according to parameters. This query may be used with paginator.
93
     *
94
     * @param array $filters
95
     * @param string $orderBy valid SQL sorting snippet
96
     *
97
     * @return Zend_Db_Table_Select
98
     */
99 1
    public static function getFilteredQuery(array $filters, string $orderBy)
100
    {
101 1
        $orderBy = preg_replace('/^(status\d+)(.*)/', '\\1.rating\\2', $orderBy);
102
103 1
        $select = self::getDbTable()->select()->setIntegrityCheck(false)
104 1
            ->from('movie')
105 1
            ->order($orderBy);
106
107 1
        $i = 0;
108 1
        $maxDate = '';
109 1
        $filtersDone = [];
110 1
        foreach ($filters as $key => $filter) {
111 1
            if (!is_array($filter)) {
112 1
                continue;
113
            }
114
115 1
            $filterUniqueId = $filter['user'];
116 1
            if (!preg_match('/^filter\d+$/', $key) || in_array($filterUniqueId, $filtersDone)) {
117
                continue;
118
            }
119
120 1
            $filtersDone[] = $filterUniqueId;
121 1
            $showNoRating = in_array(0, $filter['status']);
122 1
            $alias = 'status' . $i++;
123 1
            $allowNull = ' OR ' . $alias . '.idUser IS NULL';
124 1
            if ($filter['condition'] === 'is') {
125 1
                $condition = '';
126 1
                $allowNull = $showNoRating ? $allowNull : '';
127
            } else {
128
                $condition = 'NOT ';
129
                $allowNull = !$showNoRating ? $allowNull : '';
130
            }
131 1
            $select->joinLeft([$alias => 'status'], '(movie.id = ' . $alias . '.idMovie AND ' . $alias . '.idUser = ' . $filter['user'] . ')' . $allowNull, []);
132
133 1
            $select->where($alias . '.isLatest = 1 OR ' . $alias . '.isLatest IS NULL');
134
135
            // Filter by status
136 1
            $select->where($alias . '.rating ' . $condition . 'IN (?)' . $allowNull, $filter['status']);
137
138
            // Filter by title
139 1
            if (isset($filter['title'])) {
140 1
                $title = $filter['title'];
141 1
                $id = Movie::extractId($title);
142 1
                $titles = explode(' ', trim($title));
143 1
                foreach ($titles as $part) {
144 1
                    if ($part) {
145
                        $select->where('movie.title LIKE ? OR movie.id = "' . $id . '"', '%' . $part . '%');
146
                    }
147
                }
148
            }
149
150
            // Filter by presence of source
151 1
            if (isset($filter['withSource']) && $filter['withSource']) {
152
                $select->where('movie.source IS NOT NULL');
153
            }
154
155 1
            if ($maxDate) {
156
                $maxDate = 'IF(`' . $alias . '`.`dateUpdate` IS NULL OR `' . $alias . '`.`dateUpdate` < ' . $maxDate . ', ' . $maxDate . ', `' . $alias . '`.`dateUpdate`)';
157
            } else {
158 1
                $maxDate = '`' . $alias . '`.`dateUpdate`';
159
            }
160
        }
161
162 1
        $select->columns(['date' => new Zend_Db_Expr($maxDate)]);
163
164 1
        return $select;
165
    }
166
167
    /**
168
     * Delete obsolete sources for all movies.
169
     * An obsolete source is either a source older than 3 months, or
170
     * a source which is not needed anymore (nobody need the movie anymore)
171
     */
172
    public static function deleteObsoleteSources(): void
173
    {
174
        $db = self::getDbTable()->getAdapter();
175
        $update = 'UPDATE `movie` SET dateUpdate = dateUpdate, dateSearch = NULL, searchCount = 0, identity = 0, quality = 0, score = 0, source = NULL';
176
177
        // Delete sources older than 6 months
178
        $db->query($update . ' WHERE `source` IS NOT NULL AND `dateSearch` < DATE_SUB(NOW(), INTERVAL 6 MONTH)');
179
180
        // Delete non-needed sources
181
        $db->query($update . ' WHERE `movie`.`id` NOT IN (SELECT `status`.`idMovie` FROM `status` WHERE `rating` = ? AND `isLatest`)', [Status::Need]);
182
    }
183
}
184