VotesHandler   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 69
c 1
b 0
f 0
dl 0
loc 137
rs 10
wmc 25

6 Methods

Rating   Name   Duplication   Size   Complexity  
B getFilterCriteria() 0 24 11
A getFilterForm() 0 8 2
A insert() 0 9 2
B addVote() 0 50 8
A __construct() 0 3 1
A filterFields() 0 3 1
1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Songlist;
4
5
use Criteria;
6
use CriteriaCompo;
7
use XoopsDatabase;
8
use XoopsObject;
9
use XoopsPersistableObjectHandler;
10
11
require_once \dirname(__DIR__) . '/include/songlist.object.php';
12
// require_once \dirname(__DIR__) . '/include/songlist.form.php';
13
use  XoopsModules\Songlist\Form\FormController;
14
15
/**
16
 * Class VotesHandler
17
 */
18
class VotesHandler extends XoopsPersistableObjectHandler
19
{
20
    /**
21
     * VotesHandler constructor.
22
     * @param \XoopsDatabase $db
23
     */
24
    public function __construct(XoopsDatabase $db)
25
    {
26
        parent::__construct($db, 'songlist_votes', Votes::class, 'vid', 'ip');
27
    }
28
29
    /**
30
     * @return array
31
     */
32
    public function filterFields(): array
33
    {
34
        return ['vid', 'sid', 'uid', 'ip', 'netaddy', 'rank'];
35
    }
36
37
    /**
38
     * @param string $filter
39
     * @return \CriteriaCompo
40
     */
41
    public function getFilterCriteria($filter): CriteriaCompo
42
    {
43
        $parts    = \explode('|', $filter);
44
        $criteria = new CriteriaCompo();
45
        foreach ($parts as $part) {
46
            $var = \explode(',', $part);
47
            if (!empty($var[1]) && !\is_numeric($var[0])) {
48
                $object = $this->create();
49
                if (\XOBJ_DTYPE_TXTBOX == $object->vars[$var[0]]['data_type']
50
                    || \XOBJ_DTYPE_TXTAREA == $object->vars[$var[0]]['data_type']) {
51
                    $criteria->add(new Criteria('`' . $var[0] . '`', '%' . $var[1] . '%', ($var[2] ?? 'LIKE')));
52
                } elseif (in_array($object->vars[$var[0]]['data_type'], [XOBJ_DTYPE_INT, XOBJ_DTYPE_DECIMAL, XOBJ_DTYPE_FLOAT])) {
53
                    $criteria->add(new Criteria('`' . $var[0] . '`', $var[1], ($var[2] ?? '=')));
54
                } elseif (\XOBJ_DTYPE_ENUM == $object->vars[$var[0]]['data_type']) {
55
                    $criteria->add(new Criteria('`' . $var[0] . '`', $var[1], ($var[2] ?? '=')));
56
                } elseif (\XOBJ_DTYPE_ARRAY == $object->vars[$var[0]]['data_type']) {
57
                    $criteria->add(new Criteria('`' . $var[0] . '`', '%"' . $var[1] . '";%', ($var[2] ?? 'LIKE')));
58
                }
59
            } elseif (!empty($var[1]) && \is_numeric($var[0])) {
60
                $criteria->add(new Criteria($var[0], $var[1]));
61
            }
62
        }
63
64
        return $criteria;
65
    }
66
67
    /**
68
     * @param string $filter
69
     * @param string $field
70
     * @param string $sort
71
     * @param string $op
72
     * @param string $fct
73
     * @return string
74
     */
75
    public function getFilterForm($filter, $field, $sort = 'created', $op = 'dashboard', $fct = 'list'): string
76
    {
77
        $ele = Utility::getFilterElement($filter, $field, $sort, $op, $fct);
78
        if (\is_object($ele)) {
79
            return $ele->render();
80
        }
81
82
        return '&nbsp;';
83
    }
84
85
    /**
86
     * @param bool $force
87
     * @return mixed
88
     */
89
    public function insert(XoopsObject $obj, $force = true)
90
    {
91
        if ($obj->isNew()) {
92
            $obj->setVar('created', \time());
93
        } else {
94
            $obj->setVar('updated', \time());
95
        }
96
97
        return parent::insert($obj, $force);
98
    }
99
100
    /**
101
     * @param int $sid
102
     * @param string$value
103
     * @return bool
104
     */
105
    public function addVote($sid, $value): bool
106
    {
107
        $criteria = new CriteriaCompo(new Criteria('sid', $sid));
108
109
        $ip = Utility::getIPData(false);
110
        if ($ip['uid'] > 0) {
111
            $criteria->add(new Criteria('uid', $ip['uid']));
112
        } else {
113
            $criteria->add(new Criteria('ip', $ip['ip']));
114
            $criteria->add(new Criteria('netaddy', $ip['network-addy']));
115
        }
116
117
        if (0 == $this->getCount($criteria) && $sid > 0 && $value > 0) {
118
            $vote = $this->create();
119
            $vote->setVar('sid', $sid);
120
            $vote->setVar('uid', $ip['uid']);
121
            $vote->setVar('ip', $ip['ip']);
122
            $vote->setVar('netaddy', $ip['network-addy']);
123
            $vote->setVar('rank', $value);
124
            if ($this->insert($vote)) {
125
                $songsHandler    = \XoopsModules\Songlist\Helper::getInstance()->getHandler('Songs');
126
                $albumsHandler   = \XoopsModules\Songlist\Helper::getInstance()->getHandler('Albums');
127
                $artistsHandler  = \XoopsModules\Songlist\Helper::getInstance()->getHandler('Artists');
128
                $categoryHandler = \XoopsModules\Songlist\Helper::getInstance()->getHandler('Category');
129
                $genreHandler    = \XoopsModules\Songlist\Helper::getInstance()->getHandler('Genre');
130
                $voiceHandler    = \XoopsModules\Songlist\Helper::getInstance()->getHandler('Voice');
131
132
                $song  = $songsHandler->get($sid);
133
                $sql   = [];
134
                $sql[] = 'UPDATE `' . $songsHandler->table . '` SET `rank` = `rank` + ' . $value . ', `votes` = `votes` + 1 WHERE `' . $songsHandler->keyName . '` = ' . $sid;
135
                $sql[] = 'UPDATE `' . $categoryHandler->table . '` SET `rank` = `rank` + ' . $value . ', `votes` = `votes` + 1 WHERE `' . $categoryHandler->keyName . '` = ' . $song->getVar($categoryHandler->keyName);
136
                $sql[] = 'UPDATE `' . $genreHandler->table . '` SET `rank` = `rank` + ' . $value . ', `votes` = `votes` + 1 WHERE `' . $genreHandler->keyName . '` = ' . $song->getVar($genreHandler->keyName);
137
                $sql[] = 'UPDATE `' . $voiceHandler->table . '` SET `rank` = `rank` + ' . $value . ', `votes` = `votes` + 1 WHERE `' . $voiceHandler->keyName . '` = ' . $song->getVar($voiceHandler->keyName);
138
                $sql[] = 'UPDATE `' . $albumsHandler->table . '` SET `rank` = `rank` + ' . $value . ', `votes` = `votes` + 1 WHERE `' . $albumsHandler->keyName . '` = ' . $song->getVar($albumsHandler->keyName);
139
                foreach ($song->getVar('aids') as $aid) {
140
                    $sql[] = 'UPDATE `' . $artistsHandler->table . '` SET `rank` = `rank` + ' . $value . ', `votes` = `votes` + 1 WHERE `' . $artistsHandler->keyName . '` = ' . $aid;
141
                }
142
                foreach ($sql as $question) {
143
                    $GLOBALS['xoopsDB']->queryF($question);
144
                }
145
                \redirect_header($_POST['uri'], 10, \_MD_SONGLIST_MSG_VOTED_FINISHED);
146
                exit(0);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
147
            }
148
            \redirect_header($_POST['uri'], 10, \_MD_SONGLIST_MSG_VOTED_ALREADY);
149
            exit(0);
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
150
        }
151
        \redirect_header($_POST['uri'], 10, \_MD_SONGLIST_MSG_VOTED_SOMETHINGWRONG);
152
        exit(0);
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return boolean. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
153
154
        return false;
0 ignored issues
show
Unused Code introduced by
return false is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
155
    }
156
}
157