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); |
|
|
|
|
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) { |
|
|
|
|
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
|
|
|
|
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.