Test Failed
Push — master ( dd7c2d...d818fc )
by Christophe
02:23
created

JavascriptChartOutput::checkChartsTypes()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 4
nc 3
nop 1
1
<?php
2
3
namespace CMEN\GoogleChartsBundle\ChartOutput;
4
5
use CMEN\GoogleChartsBundle\Exception\GoogleChartsException;
6
use CMEN\GoogleChartsBundle\GoogleCharts\Chart;
7
8
/**
9
 * @author Christophe Meneses
10
 */
11
class JavascriptChartOutput extends AbstractChartOutput
12
{
13
    /**
14
     * {@inheritdoc}
15
     */
16
    public function startCharts($charts, $elementsID = null)
17
    {
18
        if ($charts instanceof Chart) {
19
            $charts = [$charts];
20
21
            if ($elementsID) {
22
                if (!is_string($elementsID)) {
23
                    throw new GoogleChartsException('A string is expected for HTML element ID.');
24
                }
25
26
                $elementsID = [$elementsID];
27
            }
28
        } elseif (is_array($charts) && !empty($charts)) {
29
            $this->checkChartsTypes($charts);
30
31
            if (null !== $elementsID) {
32
                $this->checkElementsId($charts, $elementsID);
0 ignored issues
show
Bug introduced by
It seems like $elementsID defined by parameter $elementsID on line 16 can also be of type string; however, CMEN\GoogleChartsBundle\...tput::checkElementsId() does only seem to accept array<integer,string>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
33
            }
34
        } else {
35
            throw new GoogleChartsException('An instance of Chart or an array of Chart is expected.');
36
        }
37
38
        $packages = [];
39
        $drawChartName = '';
40
        for ($i = 0; $i < count($charts); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
41
            if ($elementsID) {
42
                $charts[$i]->setElementID($elementsID[$i]);
43
            }
44
45
            if (!in_array($charts[$i]->getPackage(), $packages)) {
46
                $packages[] = $charts[$i]->getPackage();
47
            }
48
            $drawChartName .= $charts[$i]->getElementID();
49
        }
50
51
        $js = $this->loadLibraries($packages);
52
53
        $js .= $this->startCallback('drawChart'.ucfirst(md5($drawChartName)));
54
55
        foreach ($charts as $chart) {
56
            $js .= $chart->startDraw();
57
        }
58
59
        return $js;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function endCharts($charts)
66
    {
67
        if ($charts instanceof Chart) {
68
            $js = $charts->endDraw().$this->endCallback();
69
        } elseif (is_array($charts) && !empty($charts)) {
70
            $this->checkChartsTypes($charts);
71
72
            $js = '';
73
            foreach ($charts as $chart) {
74
                $js .= $chart->endDraw();
75
            }
76
77
            $js .= $this->endCallback();
78
        } else {
79
            throw new GoogleChartsException('An instance of Chart or an array of Chart is expected.');
80
        }
81
82
        return $js;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    public function fullCharts($charts, $elementsID = null)
89
    {
90
        return $this->startCharts($charts, $elementsID).$this->endCharts($charts);
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function loadLibraries($packages)
97
    {
98
        array_walk($packages, function (&$item) {
99
            $item = "'".$item."'";
100
        });
101
102
        ($this->language) ? $language = ", language: '".$this->language."'" : $language = '';
103
104
        $load = "'".$this->version."', {packages:[".implode(',', $packages).']'.$language.'}';
105
106
        return "google.charts.load($load);";
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112
    public function startCallback($name)
113
    {
114
        return "google.charts.setOnLoadCallback($name); function $name() {";
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function endCallback()
121
    {
122
        return '}';
123
    }
124
125
    /**
126
     * Checks if all elements ID are string and same number as charts.
127
     *
128
     * @param Chart[]  $charts
129
     * @param string[] $elementsID
130
     *
131
     * @throws GoogleChartsException
132
     */
133
    private function checkElementsId(array $charts, array $elementsID)
134
    {
135
        if (count($charts) != count($elementsID)) {
136
            throw new GoogleChartsException(
137
                'Array charts and array HTML elements ID do not have the same number of element.'
138
            );
139
        }
140
141
        foreach ($elementsID as $elementId) {
142
            if (!is_string($elementId)) {
143
                throw new GoogleChartsException('A string is expected for HTML element ID.');
144
            }
145
        }
146
    }
147
148
    /**
149
     * Checks if all elements of an array are instances of Chart. Throws an exception if not.
150
     *
151
     * @param Chart[] $charts
152
     *
153
     * @throws GoogleChartsException
154
     */
155
    private function checkChartsTypes(array $charts)
156
    {
157
        foreach ($charts as $chart) {
158
            if (!$chart instanceof Chart) {
159
                throw new GoogleChartsException('An array of Chart is expected.');
160
            }
161
        }
162
    }
163
}
164