Completed
Push — synctree2 ( 6ff00f )
by Richard
05:22
created

Stats::getCounts()   C

Complexity

Conditions 8
Paths 18

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
eloc 21
nc 18
nop 1
dl 0
loc 30
ccs 17
cts 17
cp 1
crap 8
rs 5.3846
c 0
b 0
f 0
1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
namespace Xoops\Core\Kernel\Model;
13
14
use Xoops\Core\Kernel\CriteriaElement;
15
use Xoops\Core\Kernel\XoopsModelAbstract;
16
17
/**
18
 * Object stats handler class.
19
 *
20
 * @category  Xoops\Core\Kernel\Model\Stats
21
 * @package   Xoops\Core\Kernel
22
 * @author    Taiwen Jiang <[email protected]>
23
 * @copyright 2000-2015 XOOPS Project (http://xoops.org)
24
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
25
 * @link      http://xoops.org
26
 * @since     2.3.0
27
 */
28
class Stats extends XoopsModelAbstract
29
{
30
    /**
31
     * count objects matching a condition
32
     *
33
     * @param CriteriaElement|null $criteria criteria to match
34
     *
35
     * @return int count of objects
36
     */
37 8
    public function getCount(CriteriaElement $criteria = null)
38
    {
39 8
        $qb = \Xoops::getInstance()->db()->createXoopsQueryBuilder();
40
41 8
        $groupBy = false;
42 8
        if (isset($criteria) && ($criteria instanceof CriteriaElement)) {
43 3
            $temp = $criteria->getGroupBy();
44 3
            if (!empty($temp)) {
45
                $qb->select($temp);
46
                $groupBy = true;
47
            }
48
        }
49 8
        if (!$groupBy) {
50 8
            $qb->select('COUNT(*)');
51
        } else {
52
            $qb->addSelect('COUNT(*)');
53
        }
54
55 8
        $qb->from($this->handler->table, null);
56 8
        if (isset($criteria) && ($criteria instanceof CriteriaElement)) {
57 3
            $qb = $criteria->renderQb($qb);
58
        }
59
        try {
60 8
            $result = $qb->execute();
61 8
            if (!$result) {
62
                return 0;
63
            }
64
        } catch (\Exception $e) {
65
            \Xoops::getInstance()->events()->triggerEvent('core.exception', $e);
66
            return 0;
67
        }
68
69 8
        if ($groupBy == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
70 8
            list ($count) = $result->fetch(\PDO::FETCH_NUM);
71 8
            return $count;
72
        } else {
73
            $ret = array();
74
            while (list ($id, $count) = $result->fetch(\PDO::FETCH_NUM)) {
75
                $ret[$id] = $count;
76
            }
77
            return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $ret; (array) is incompatible with the return type documented by Xoops\Core\Kernel\Model\Stats::getCount of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
78
        }
79
    }
80
81
    /**
82
     * get counts matching a condition
83
     *
84
     * @param CriteriaElement|null $criteria criteria to match
85
     *
86
     * @return array of counts
87
     */
88 2
    public function getCounts(CriteriaElement $criteria = null)
89
    {
90 2
        $qb = \Xoops::getInstance()->db()->createXoopsQueryBuilder();
91
92 2
        $ret = array();
93 2
        $limit = null;
0 ignored issues
show
Unused Code introduced by
$limit is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
94 2
        $start = null;
0 ignored issues
show
Unused Code introduced by
$start is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
95 2
        $groupby_key = $this->handler->keyName;
96 2
        if (isset($criteria) && ($criteria instanceof CriteriaElement)) {
97
            if ($groupBy = $criteria->getGroupBy()) {
98
                $groupby_key = $groupBy;
99
            }
100
        }
101 2
        $qb->select($groupby_key)
102 2
            ->addSelect('COUNT(*)')
103 2
            ->from($this->handler->table, null)
104 2
            ->groupBy($groupby_key);
105
106 2
        if (isset($criteria) && ($criteria instanceof CriteriaElement)) {
107
            $qb = $criteria->renderQb($qb);
108
        }
109 2
        $result = $qb->execute();
110 2
        if (!$result) {
111
            return $ret;
112
        }
113 2
        while (list ($id, $count) = $result->fetch(\PDO::FETCH_NUM)) {
114 2
            $ret[$id] = $count;
115
        }
116 2
        return $ret;
117
    }
118
}
119