/
PollForm.php
209 lines (175 loc) · 5.76 KB
/
PollForm.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
<?php
class PollForm extends Form {
static $show_results_link = false;
/**
* After submission, redirect back to the # anchor. Set to null to disable the feature.
*/
static $redirect_to_anchor = 'SSPoll';
protected $poll;
protected $chartOptions = array(
'width'=>'300',
'height'=>'200',
'colours'=>array('4D89F9', 'C6D9FD')
);
function __construct($controller, $name, $poll) {
if(!$poll) {
user_error("The poll doesn't exist.", E_USER_ERROR);
}
$this->poll = $poll;
$data = array();
foreach($poll->Choices() as $choice) {
$data[$choice->ID] = $choice->Title;
}
if($poll->MultiChoice) {
$choiceField = new CheckboxSetField('PollChoices', '', $data);
}
else {
$choiceField = new OptionsetField('PollChoices', '', $data);
}
$fields = new FieldList(
$choiceField
);
if(PollForm::$show_results_link) {
$showResultsURL = Director::get_current_page()->Link() . '?poll_results';
$showResultsLink = new LiteralField('ShowPollLink', '<a class="show-results" href="' . $showResultsURL . '">Show results</a>');
$fields->push($showResultsLink);
}
$actions = new FieldList(
new FormAction('submitPoll', 'Submit', null, null, 'button')
);
$validator = new PollForm_Validator('PollChoices');
parent::__construct($controller, $name, $fields, $actions, $validator);
}
function submitPoll($data, $form) {
$choiceIDs = is_array($data['PollChoices']) ? $data['PollChoices'] : array($data['PollChoices']);
$choicesIDs = implode(',', $choiceIDs);
$choices = DataObject::get('PollChoice', sprintf('"ID" IN (%s)', $choicesIDs));
if($choices) {
foreach($choices as $choice) {
$choice->addVote();
}
$form->poll->markAsVoted();
}
// Redirect back to anchor (partly copied from Director::redirectBack)
if (self::$redirect_to_anchor) {
if($this->request->requestVar('_REDIRECT_BACK_URL')) {
$url = $this->request->requestVar('_REDIRECT_BACK_URL');
} else if($this->request->getHeader('Referer')) {
$url = $this->request->getHeader('Referer');
} else {
$url = Director::baseURL();
}
$url .= '#'.self::$redirect_to_anchor.'-'.$this->poll->ID;
$this->controller->redirect($url);
}
else {
$this->controller->redirectBack();
}
}
/**
* Renders the poll using the PollForm.ss
*/
function forTemplate() {
if (!$this->poll || !$this->poll->getVisible() || !$this->poll->Choices()) return null;
$this->DefaultForm = $this->renderWith('Form');
return $this->customise($this)->renderWith(array(
$this->class,
'Form'
));
}
/**
* Set the default chart options
*/
function setChartOption($option, $value) {
$this->chartOptions[$option] = $value;
}
/**
* Access the default chart options
*/
function getChartOption($option) {
if (isset($this->chartOptions[$option])) return $this->chartOptions[$option];
}
/**
* Access the Poll object associated with this form
*/
function Poll() {
return $this->poll;
}
/**
* Check if user bypassed the voting form and requested to see the results.
*/
function isForcedDisplay() {
return isset($_REQUEST['poll_results']);
}
/**
* Collate the information from PollForm and Poll to figure out if the results should be shown.
*/
function getShouldShowResults() {
return $this->poll->isVoted() || $this->isForcedDisplay();
}
/**
* Get current configuration so it can be used in the template
*/
function getShowResultsLink() {
return $this->show_results_link;
}
/**
* URL to an chart image that is render by Google Chart API
* @link http://code.google.com/apis/chart/docs/making_charts.html
* This is quite rudimentary, and can be modified by combination of methods:
* - defining a PollForm decorator and replaceChart method
* - creating a custom PollForm.ss template in your theme folder
* - subclassing this form for full control
*
* @return string
*/
function getChart() {
$extended = $this->extend('replaceChart');
if (isset($extended) && count($extended)) return array_shift($extended);
if (!$this->poll || !$this->poll->getVisible() || !$this->poll->Choices()) return null;
$apiURL = 'https://chart.googleapis.com/chart';
$choices = $this->poll->Choices('', '"Order" ASC');
// Fall back to default
$labels = array();
$data = array();
$count = 0;
if ($choices) foreach($choices as $choice) {
$labels[] = "t{$choice->Title} ({$choice->Votes}),000000,0,$count,11,1.0,:10:";
$data[] = $choice->Votes;
$count++;
}
$labels = implode('|', $labels);
$data = implode(',', $data);
$max = (int)(($this->poll->getMaxVotes()+1) * 1.5);
$height = $this->chartOptions['height'];
$width = $this->chartOptions['width'];
$colours = implode($this->chartOptions['colours'], '|');
$href = "https://chart.googleapis.com/chart?".
"chs={$width}x$height". // Chart size
"&chbh=a". // Bar width and spacing
"&cht=bhg". // Chart type
"&chco=$colours". // Alternating bar colours
"&chds=0,$max". // Chart scale
"&chd=t1:$data". // Data
"&chm=$labels"; // Custom labels
return "<img class='poll-chart' src='$href'/>";
}
}
/**
* Customise the validation message. Also enforce at least one selection in multi-choice poll (checkboxes!)
*/
class PollForm_Validator extends RequiredFields {
function php($data) {
$this->form->Fields()->dataFieldByName('PollChoices')->setCustomValidationMessage('Please select at least one option.');
return parent::php($data);
}
function javascript() {
$js = <<<JS
$('PollForm_Poll_PollChoices').requiredErrorMsg = 'Please select at least one option.';
if (jQuery('#PollForm_Poll_PollChoices').find('input[checked]').length==0) {
validationError(jQuery('#PollForm_Poll_PollChoices')[0], 'Please select at least one option.', 'required');
}
JS;
return $js . parent::javascript();
}
}