/[drupal]/contributions/modules/democracy_forum/democracy_forum.module
ViewVC logotype

Contents of /contributions/modules/democracy_forum/democracy_forum.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Sat Aug 25 13:55:14 2007 UTC (2 years, 3 months ago) by fajerstarter
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-5
File MIME type: text/x-php
Initial release of Democracy forum module: A module for e-democracy. Brings together a bunch of modules for debate and voting. Adds support for "council meetings".
1 <?php
2 // $Id$
3
4 /**
5 * Views module functions.
6 */
7 if (module_exists('views')) {
8 require_once(drupal_get_path('module', 'democracy_forum') .'/democracy_forum_views.inc');
9 }
10
11 /**
12 * Implementation of hook_block().
13 */
14 function democracy_forum_block($op = 'list', $delta = 1) {
15 if ($op == 'list') {
16 $blocks[1]['info'] = t('Related council issues');
17 $blocks[2]['info'] = t('Council status');
18 return $blocks;
19 }
20 // Only show the blocks if we are on a node and a council term is found.
21 else if ($op == 'view' && user_access('access content') && arg(0) == 'node' && is_numeric(arg(1)) && $term = democracy_forum_council_get_term(arg(1))) {
22 switch ($delta) {
23 case 1:
24 $block['subject'] = t('Other issues in this council meeting');
25 $block['content'] = democracy_forum_council_related($term, arg(1));
26 break;
27
28 case 2:
29 $council_status = democracy_forum_council_status($term, 'long');
30 $block['content'] = $council_status['output'];
31 break;
32
33 }
34 return $block;
35 }
36 }
37
38 /**
39 * Implementation of hook_menu().
40 */
41 function democracy_forum_menu($may_cache) {
42 $items = array();
43
44 if ($may_cache) {
45 $items[] = array(
46 'path' => 'democracyforum',
47 'title' => t('Democracy forum'),
48 'callback' => 'democracy_forum_page',
49 'access' => user_access('access content'),
50 'type' => MENU_SUGGESTED_ITEM
51 );
52 }
53
54 return $items;
55 }
56
57 /**
58 * Wrapper function around theme_democracy_forum_page() to allow the page to
59 * be themed.
60 *
61 * TODO: Some logic from theme_democracy_forum_page() should probably be moved
62 * here to make theming simpler.
63 */
64 function democracy_forum_page() {
65 drupal_add_css(drupal_get_path('module', 'democracy_forum') .'/democracy_forum.css');
66 return theme('democracy_forum_page');
67 }
68
69 /**
70 * Render a page that can be used as a frontpage for the democracy forum.
71 */
72 function theme_democracy_forum_page() {
73 // Load the views by name
74 $view_proposals = views_get_view('proposals');
75 $view_arguments_recent = views_get_view('arguments_recent');
76 $view_council_related = views_get_view('council_related');
77
78 $next_council = _democracy_forum_get_next_council_term();
79 $council_status = democracy_forum_council_status($next_council, 'action');
80
81 $output = '<div id="democracy-forum">';
82 $output .= '<div class="left">';
83 $output .= '<h2>'. t('Council @council-date', array('@council-date' => $next_council->name)) .'</h2>';
84 $output .= '<dl class="actions">'. $council_status['output'] .'</dl>';
85 $output .= l(t('Previous councils'), 'democracyforum/council');
86 $output .= '</div>'; // end div.left
87
88 if ($next_council->tid) {
89 $output .= '<div class="right">';
90 $output .= '<h2>'. t('Council issues') .'</h2>';
91 $output .= views_build_view('embed', $view_council_related, array($next_council->tid));
92 $output .= '</div>'; // end div.righ
93 }
94
95 $output .= '<span class="clear"></span>'; // Force forum to float under
96
97 // Render forum listing if forum module is enabled. Note that forum_page()
98 // also can render a specific forum by term id, e.g. forum_page(34).
99 if (module_exists('forum')) {
100 $output .= '<h2 class="forum">'. t('Forums') .'</h2>';
101 $output .= forum_page();
102 // Set the title again as forum_page() will set it otherwise.
103 drupal_set_title(t('Democracy forum'));
104 }
105
106 $output .= '<div class="left">';
107 $output .= '<h2>'. t('Proposals') .'</h2>';
108 if (user_access('create proposal content')) {
109 $output .= '<dl class="actions"><dt class="proposal">'. l(t('Add a proposal'), 'node/add/proposal') .'</dt></dl>';
110 }
111 // Rended 10 propposals, sorted by term weight/name and update time.
112 // Note that the default view supports filtering by term id, e.g. to display
113 // only proposals with the status "draft" and "archived". If "draft" have term
114 // id 34 and "archived" term id 56 this function would be used:
115 // views_build_view('embed', $view_proposals, array('34 + 56'), false, 10);
116 $output .= views_build_view('embed', $view_proposals, NULL, false, 10);
117 $output .= l(t('Show all proposals'), 'proposals');
118 $output .= '</div>'; // end div.left
119
120 if (module_exists('procon')) {
121 $output .= '<div class="right">';
122 $output .= '<h2>'. t('Latest arguments') .'</h2>';
123 // Rended 10 most recent arguments
124 $output .= views_build_view('embed', $view_arguments_recent, NULL, false, 10);
125 $output .= '</div>'; // end div.righ
126 }
127
128 $output .= '</div>'; // end #democracy-forum
129
130 return $output;
131 }
132
133 /**
134 * Implementation of hook_form_alter().
135 */
136 function democracy_forum_form_alter($form_id, &$form) {
137 $type = $form['type']['#value'];
138
139 if ('advpoll_binary_node_form' == $form_id) {
140 // Council result field for advanced poll content types,
141 $form['democracy_forum_council'] = array(
142 '#type' => 'fieldset',
143 '#title' => t('Council result'),
144 '#collapsible' => TRUE,
145 '#collapsed' => TRUE,
146 '#weight' => 3,
147 '#tree' => TRUE,
148 );
149 $form['democracy_forum_council']['result'] = array(
150 '#type' => 'select',
151 '#title' => t('Result'),
152 '#options' => array(0 => '', 1 => t('Yes'), 2 => t('No')),
153 '#default_value' => isset($form['#node']->democracy_forum_council_result) ? $form['#node']->democracy_forum_council_result : 0,
154 );
155 $form['democracy_forum_council']['link'] = array(
156 '#type' => 'textfield',
157 '#title' => t('Link to decision'),
158 '#default_value' => isset($form['#node']->democracy_forum_council_link) ? $form['#node']->democracy_forum_council_link : '',
159 );
160 }
161 }
162
163 /**
164 * Implementation of hook_nodeapi().
165 */
166 function democracy_forum_nodeapi(&$node, $op, $teaser, $page) {
167 switch ($op) {
168 case 'load':
169 $object = db_fetch_object(db_query('SELECT result, link FROM {democracy_forum_council} WHERE nid = %d', $node->nid));
170 return array('democracy_forum_council_result' => $object->result, 'democracy_forum_council_link' => $object->link);
171 break;
172
173 case 'insert':
174 db_query("INSERT INTO {democracy_forum_council} (nid, result, link) VALUES (%d, %d, '%s')", $node->nid, $node->democracy_forum_council['result'], $node->democracy_forum_council['link']);
175 break;
176
177 case 'update':
178 db_query('DELETE FROM {democracy_forum_council} WHERE nid = %d', $node->nid);
179 db_query("INSERT INTO {democracy_forum_council} (nid, result, link) VALUES (%d, %d, '%s')", $node->nid, $node->democracy_forum_council['result'], $node->democracy_forum_council['link']);
180 break;
181
182 case 'delete':
183 db_query('DELETE FROM {democracy_forum_council} WHERE nid = %d', $node->nid);
184 break;
185
186 case 'validate':
187 if (!$node->democracy_forum_council['result'] && $node->democracy_forum_council['link']) {
188 form_set_error('democracy_forum_council][result', t('Council result can not be blank if a link to a decision is entered.'));
189 }
190 if ($node->democracy_forum_council['link'] && !valid_url($node->democracy_forum_council['link'], TRUE)) {
191 form_set_error('democracy_forum_council][link', t('The entered link is not a valid URL.'));
192 }
193 break;
194
195 }
196 }
197
198 /**
199 * Implementation of hook_link_alter().
200 *
201 * Adopted from forum_link_alter
202 */
203 function democracy_forum_link_alter(&$node, &$links) {
204 foreach ($links as $module => $link) {
205 if (strstr($module, 'taxonomy_term')) {
206 // Link back to the council and not the taxonomy term page. We'll only
207 // do this if the taxonomy term belongs to the council vocabulary.
208 $tid = str_replace('taxonomy/term/', '', $link['href']);
209 $vid = variable_get('democracy_forum_council_vocabulary', '');
210 $term = taxonomy_get_term($tid);
211 if ($term->vid == $vid) {
212 $links[$module]['href'] = str_replace('taxonomy/term', 'democracyforum/council', $link['href']);
213 }
214 }
215 }
216 }
217
218 function democracy_forum_council_related($term, $nid) {
219 // Insert default stylesheet.
220 drupal_add_css(drupal_get_path('module', 'democracy_forum') .'/democracy_forum.css');
221 $view_council_related = views_get_view('council_related');
222 return views_build_view('embed', $view_council_related, array($term->tid, $nid));
223 }
224
225 /**
226 * Helper function to get the status of the council meeting.
227 * $term is the council term object.
228 * $display is the output variant. Available options are 'long', 'short' and
229 * 'action'.
230 *
231 * @return
232 * An associative array with the keys 'output' and 'status'.
233 *
234 * TODO: make the HTML themable.
235 *
236 */
237 function democracy_forum_council_status($term = NULL, $display = 'long') {
238 if (isset($term) && $term) {
239 // Define end time. This suppose that the end time for voting and debate is
240 // the [specified date] 00:00. It's only used for visual stuff but it should
241 // probabably be possible to define a more exact time.
242 $council_end_time = strtotime($term->name);
243 $today = time();
244 if ($today > $council_end_time) {
245 $status = 'passed';
246 }
247 else {
248 $status = 'active';
249 }
250
251 switch ($status) {
252 case 'passed':
253 $next_council_term = _democracy_forum_get_next_council_term();
254 switch ($display) {
255 case 'long':
256 $output = "<div class=\"$status\"><h3>". t('Council <a href="@council-link">@council-date</a>', array('@council-link' => 'democracyforum/council/'. $term->tid, '@council-date' => $term->name)) .'</h3>';
257 $output .= '<p class="status">'. t('Finished') .'</p>';
258 if ($next_council_term) {
259 $output .= '<p class="next">'. t('Next council meeting is <a href="@council-link">@council-date</a>', array('@council-link' => 'democracyforum/council/'. $next_council_term->tid, '@council-date' => $next_council_term->name)) .'.</p>';
260 }
261 $output .= '</div>';
262 break;
263
264 case 'short':
265 $output = t('Finished');
266 break;
267
268 case 'action':
269 $output = l(t('Show results'), 'democracyforum/council');
270 break;
271 }
272 break;
273
274 case 'active':
275 $time_left = format_interval($council_end_time-$today, 1);
276 switch ($display) {
277 case 'long':
278 $output .= "<div class=\"$status\"><h3>". t('Council <a href="@council-link">@council-date</a>', array('@council-link' => 'democracyforum/council/'. $term->tid, '@council-date' => $term->name)) ."</h3><p class=\"status\">". t('Debate and voting end in @time-left.', array('@time-left' => $time_left)) .'</p></div>';
279 break;
280
281 case 'short':
282 $output = t('Active');
283 break;
284
285 case 'action':
286 $next_council_term = _democracy_forum_get_next_council_term();
287 $output = '<dt class="vote">'. l(t('Vote and debate'), 'democracyforum/council/'. check_plain($next_council_term->tid)) .'</dt>';
288 $output .= '<dd class="vote">'. t('Debate and voting end in @time-left', array('@time-left' => $time_left)) .'.</dd>';
289 break;
290 }
291 break;
292 }
293 return array('output' => $output, 'status' => $status);
294 }
295 else {
296 return array('output' => '<dt class="no-council">'. t('No council meeting is planned in the democracy forum at this moment.') .'</dt>');
297 }
298 }
299
300 function democracy_forum_council_get_term($nid) {
301 $vid = variable_get('democracy_forum_council_vocabulary', '');
302 $term = taxonomy_node_get_terms_by_vocabulary($nid, $vid);
303 if($term) {
304 $first_term = array_shift($term);
305 return $first_term;
306 }
307 }
308
309 function theme_democracy_forum_council_result($vote, $link = NULL) {
310 switch ($vote) {
311 case 1:
312 $output = '<span class="yes">'. t('Yes') .'</span>';
313 break;
314
315 case 2:
316 $output = '<span class="no">'. t('No') .'</span>';
317 break;
318 }
319 if ($link) {
320 $output .= ' <a href="'. $link .'">'. t('Link to decision') .'</a>';
321 }
322 return $output;
323 }
324
325 /*
326 * Helper function to get current council term from the council vocabulary
327 *
328 * @return
329 * A term object representing the next council if found, else it
330 * returns false.
331 */
332 function _democracy_forum_get_next_council_term() {
333 $next_council = false;
334 $vid = variable_get('democracy_forum_council_vocabulary', '');
335 $terms = taxonomy_get_tree($vid);
336 $today = time();
337
338 // Get the next council term relative to todays date.
339 foreach ($terms as $term) {
340 if (strtotime($term->name) >= $today) {
341 $next_council = $term;
342 break;
343 }
344 }
345
346 return $next_council;
347 }
348
349
350 /*
351 * Get the winning choice(s) for a binary poll to be used in listings etc.
352 *
353 * Adopted from advpoll_view_results_binary().
354 */
355 function democracy_forum_advpoll_winner_binary($node) {
356 $output = '';
357 // Advpoll binary is currently onl supportet
358 if ($node->type = 'advpoll_binary') {
359 $content_type = 'advpoll';
360 $content_id = $node->nid;
361
362 $results = votingapi_get_voting_results($content_type, $content_id);
363 $votes = array();
364 foreach ($results as $result) {
365 $voteval = $result->tag;
366 if ($voteval == '_advpoll') {
367 if ($result->function == 'total_votes') {
368 $total_votes = $result->value;
369 }
370 }
371 else if (isset($node->choice[$voteval])) {
372 if (!$votes[$voteval]) {
373 $votes[$voteval] = 0;
374 }
375 $votes[$voteval] = $result->value;
376 }
377 }
378
379 if ($node->choice && $total_votes > 0) {
380 // Add in any choices that received no votes.
381 foreach ($node->choice as $i => $ch) {
382 if (!isset($votes[$i])) {
383 $votes[$i] = 0;
384 }
385 }
386
387 // Sort results by votes, descending.
388 arsort($votes);
389
390 // Get the winning choice(s). This part differ from
391 // advpoll_view_results_binary() which this function is based on.
392 foreach ($votes as $i => $count) {
393 $choice = $node->choice[$i];
394 $percentage = round(100 * $votes[$i] / $total_votes, 0);
395 // Only break out if the votes differ from the previous choice
396 // as we want to get all draw votes for this poll.
397 if (isset($previous_votes) && $previous_votes != $votes[$i]) {
398 break;
399 }
400
401 // Convert the label to a nicer looking HTML class that can be used in
402 // the theme function. A style could then color choises named "Yes" or
403 // "Yes, stop crime." as e.g. green as they will get the class "yes".
404 $exploded_label = explode(',', $choice['label']); // Take out the part before a comma
405 $class = preg_replace('/[^a-z]/', '', strtolower(substr(trim($exploded_label[0]), 0, 8))); // Make lowercase and strip out all non-letter characters.
406 $output .= theme('democracy_forum_advpoll_winner_binary', _advpoll_choice_markup($choice['label'], $node->format, false), $percentage, $class);
407 $previous_votes = $votes[$i];
408 }
409 }
410 }
411 return $output;
412 }
413
414 function theme_democracy_forum_advpoll_winner_binary($label, $percentage, $class) {
415 return "<span class=\"$class\">$label</span> ($percentage%) ";
416 }

  ViewVC Help
Powered by ViewVC 1.1.2