Test Failed
Push — master ( d818fc...2d2f9a )
by Christophe
08:50
created

ChartOutput::loadLibraries()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
3
namespace CMEN\GoogleChartsBundle\Output\Javascript;
4
5
use CMEN\GoogleChartsBundle\Exception\GoogleChartsException;
6
use CMEN\GoogleChartsBundle\GoogleCharts\Chart;
7
use CMEN\GoogleChartsBundle\GoogleCharts\Charts\Diff\DiffChart;
8
use CMEN\GoogleChartsBundle\Output\AbstractChartOutput;
9
use CMEN\GoogleChartsBundle\Output\DataOutputInterface;
10
use CMEN\GoogleChartsBundle\Output\EventsOutputInterface;
11
use CMEN\GoogleChartsBundle\Output\OptionsOutputInterface;
12
13
/**
14
 * @author Christophe Meneses
15
 */
16
class ChartOutput extends AbstractChartOutput
17
{
18
    /** @var OptionsOutputInterface */
19
    private $optionsOutput;
20
21
    /** @var DataOutputInterface */
22
    private $dataOutput;
23
24
    /** @var EventsOutputInterface */
25
    private $eventsOutput;
26
27
    /**
28
     * ChartOutput constructor.
29
     *
30
     * @param string                 $version
31
     * @param string                 $language
32
     * @param OptionsOutputInterface $optionsOutput
33
     * @param DataOutputInterface    $dataOutput
34
     * @param EventsOutputInterface  $eventsOutput
35
     */
36
    public function __construct(
37
        $version,
38
        $language,
39
        OptionsOutputInterface $optionsOutput,
40
        DataOutputInterface $dataOutput,
41
        EventsOutputInterface $eventsOutput
42
    ) {
43
        parent::__construct($version, $language);
44
45
        $this->optionsOutput = $optionsOutput;
46
        $this->dataOutput = $dataOutput;
47
        $this->eventsOutput = $eventsOutput;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function startChart(Chart $chart)
54
    {
55
        if (null === $chart->getElementID()) {
56
            throw new GoogleChartsException('Container is not defined.');
57
        }
58
59
        $js = 'var '.$chart->getName().' = new google.'.$chart->getLibrary().'.'.$chart->getType().
60
            '(document.getElementById("'.$chart->getElementID().'"));';
61
62
        if (!$chart instanceof DiffChart) {
63
            $js .= $this->dataOutput->draw($chart->getData(), $chart->getDataName());
64
        } else {
65
            $js .= $this->dataOutput->draw($chart->getOldChart()->getData(), 'old_'.$chart->getDataName()).
66
                $this->dataOutput->draw($chart->getNewChart()->getData(), 'new_'.$chart->getDataName()).
67
                'var '.$chart->getDataName().' = '.$chart->getName().
68
                '.computeDiff(old_'.$chart->getDataName().',
69
                 new_'.$chart->getDataName().');';
70
        }
71
72
        $js .= $this->optionsOutput->draw($chart->getOptions(), $chart->getOptionsName());
73
74
        return $js;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function endChart(Chart $chart)
81
    {
82
        if ('visualization' == $chart->getLibrary()) {
83
            $options = $chart->getOptionsName();
84
        } else {
85
            /* Options conversion for material charts */
86
            $options = 'google.'.$chart->getLibrary().'.'.$chart->getType().
87
                '.convertOptions('.$chart->getOptionsName().')';
88
        }
89
90
        return $this->eventsOutput->draw($chart->getEvents(), $chart->getName()).$chart->getName().
91
            '.draw('.$chart->getDataName().', '.$options.');';
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function startCharts($charts, $elementsID = null)
98
    {
99
        if ($charts instanceof Chart) {
100
            $charts = [$charts];
101
102
            if ($elementsID) {
103
                if (!is_string($elementsID)) {
104
                    throw new GoogleChartsException('A string is expected for HTML element ID.');
105
                }
106
107
                $elementsID = [$elementsID];
108
            }
109
        } elseif (is_array($charts) && !empty($charts)) {
110
            $this->checkChartsTypes($charts);
111
112
            if (null !== $elementsID) {
113
                $this->checkElementsId($charts, $elementsID);
0 ignored issues
show
Bug introduced by
It seems like $elementsID defined by parameter $elementsID on line 97 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...
114
            }
115
        } else {
116
            throw new GoogleChartsException('An instance of Chart or an array of Chart is expected.');
117
        }
118
119
        $packages = [];
120
        $drawChartName = '';
121
        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...
122
            if ($elementsID) {
123
                $charts[$i]->setElementID($elementsID[$i]);
124
            }
125
126
            if (!in_array($charts[$i]->getPackage(), $packages)) {
127
                $packages[] = $charts[$i]->getPackage();
128
            }
129
            $drawChartName .= $charts[$i]->getElementID();
130
        }
131
132
        $js = $this->loadLibraries($packages);
133
134
        $js .= $this->startCallback('drawChart'.ucfirst(md5($drawChartName)));
135
136
        foreach ($charts as $chart) {
137
            $js .= $this->startChart($chart);
138
        }
139
140
        return $js;
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    public function endCharts($charts)
147
    {
148
        if ($charts instanceof Chart) {
149
            $js = $this->endChart($charts).$this->endCallback();
150
        } elseif (is_array($charts) && !empty($charts)) {
151
            $this->checkChartsTypes($charts);
152
153
            $js = '';
154
            foreach ($charts as $chart) {
155
                $js .= $this->endChart($chart);
156
            }
157
158
            $js .= $this->endCallback();
159
        } else {
160
            throw new GoogleChartsException('An instance of Chart or an array of Chart is expected.');
161
        }
162
163
        return $js;
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     */
169
    public function fullCharts($charts, $elementsID = null)
170
    {
171
        return $this->startCharts($charts, $elementsID).$this->endCharts($charts);
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177
    public function loadLibraries($packages)
178
    {
179
        array_walk($packages, function (&$item) {
180
            $item = "'".$item."'";
181
        });
182
183
        ($this->language) ? $language = ", language: '".$this->language."'" : $language = '';
184
185
        $load = "'".$this->version."', {packages:[".implode(',', $packages).']'.$language.'}';
186
187
        return "google.charts.load($load);";
188
    }
189
190
    /**
191
     * {@inheritdoc}
192
     */
193
    public function startCallback($name)
194
    {
195
        return "google.charts.setOnLoadCallback($name); function $name() {";
196
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201
    public function endCallback()
202
    {
203
        return '}';
204
    }
205
}
206