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

Contents of /contributions/modules/commentreference/commentreference.module

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


Revision 1.1 - (show annotations) (download) (as text)
Wed Mar 26 23:58:01 2008 UTC (20 months ago) by swentel
Branch: MAIN
CVS Tags: DRUPAL-5--1-0, HEAD
Branch point for: DRUPAL-5, DRUPAL-6--1
File MIME type: text/x-php
Initial commit of commentreference module. Defines a field type for referencing a comment.
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * Defines a field type for referencing a comment - 80 % Based on user and node reference module.
7 *
8 * @author Kristof De Jaeger - http://drupal.org/user/107403 - http://realize.be
9 * @version this is the drupal 5.x version
10 */
11
12 /**
13 * Implementation of hook_menu().
14 */
15 function commentreference_menu($may_cache) {
16 $items = array();
17
18 if ($may_cache) {
19 $items[] = array('path' => 'commentreference/autocomplete', 'title' => t('comment reference autocomplete'),
20 'callback' => 'commentreference_autocomplete', 'access' => user_access('access content'), 'type' => MENU_CALLBACK);
21 }
22
23 return $items;
24 }
25
26 /**
27 * Implementation of hook_field_info().
28 */
29 function commentreference_field_info() {
30 return array(
31 'commentreference' => array('label' => 'Comment Reference'),
32 );
33 }
34
35 /**
36 * Implementation of hook_field_settings().
37 */
38 function commentreference_field_settings($op, $field) {
39 switch ($op) {
40 case 'database columns':
41 $columns = array(
42 'cid' => array('type' => 'int', 'not null' => FALSE, 'default' => NULL),
43 );
44 return $columns;
45 }
46 }
47
48 /**
49 * Implementation of hook_field().
50 */
51 function commentreference_field($op, &$node, $field, &$items, $teaser, $page) {
52 if ($field['widget']['type'] == 'commentreference_autocomplete') {
53 switch ($op) {
54 case 'validate':
55 foreach ($items as $delta => $item) {
56 $error_field = isset($item['error_field']) ? $item['error_field'] : '';
57 unset($item['error_field']);
58 if (!empty($item['cid']) && !in_array($item['cid'], array_keys(_commentreference_potential_references($field)))) {
59 form_set_error($error_field, t('%name : Invalid comment.', array('%name' => t($field['widget']['label']))));
60 }
61 }
62 return;
63 }
64 }
65 }
66
67 /**
68 * Implementation of hook_field_formatter_info().
69 */
70 function commentreference_field_formatter_info() {
71 return array(
72 'default' => array(
73 'label' => 'Default',
74 'field types' => array('commentreference'),
75 ),
76 'plain' => array(
77 'label' => 'Plain text',
78 'field types' => array('commentreference'),
79 ),
80 );
81 }
82
83 /**
84 * Implementation of hook_field_formatter().
85 */
86 function commentreference_field_formatter($field, $item, $formatter, $node) {
87 $text = '';
88 if (isset($item['cid'])) {
89 $referenced_comment = _comment_load($item['cid']);
90 if ($referenced_comment) {
91 // we don't use the theme function because theme_comment_view uses $_GET['q']
92 // variable, and we need the nid of the node where this comment belongs to,
93 // not the one we are looking at.
94 // If anyone really thinks our own theme option is necessary, add a patch
95 // to the issue queue, for now, just passing on a link and the timestamp of the comment.
96 $text = l($referenced_comment->subject, 'node/'. $referenced_comment->nid, NULL, NULL, 'comment-'. $referenced_comment->cid) .' - '. t('@time ago', array('@time' => format_interval(time() - $referenced_comment->timestamp)));
97 }
98 }
99
100 switch ($formatter) {
101 case 'plain':
102 return strip_tags($text);
103
104 default:
105 return $text;
106 }
107 }
108
109 /**
110 * Implementation of hook_widget_info().
111 */
112 function commentreference_widget_info() {
113 return array(
114 'commentreference_select' => array(
115 'label' => 'Select List',
116 'field types' => array('commentreference'),
117 ),
118 'commentreference_autocomplete' => array(
119 'label' => 'Autocomplete Text Field',
120 'field types' => array('commentreference'),
121 ),
122 );
123 }
124
125 /**
126 * Implementation of hook_widget().
127 */
128 function commentreference_widget($op, &$node, $field, &$items) {
129 if ($field['widget']['type'] == 'commentreference_select') {
130 switch ($op) {
131 case 'prepare form values':
132 $items_transposed = content_transpose_array_rows_cols($items);
133 // get rid of null values
134 $items['default cids'] = array_filter((array) $items_transposed['cid']);
135 break;
136
137 case 'form':
138 $form = array();
139
140 $options = _commentreference_potential_references($field, NULL, FALSE, FALSE);
141 if (!$field['required']) {
142 $options = array('none' => t('<none>')) + $options;
143 }
144 if (empty($items['default cids'])) {
145 $items['default cids'][] = 'none';
146 }
147 $form[$field['field_name']] = array('#tree' => TRUE);
148 $form[$field['field_name']]['cids'] = array(
149 '#type' => 'select',
150 '#title' => t($field['widget']['label']),
151 '#default_value' => $items['default cids'],
152 '#multiple' => $field['multiple'],
153 '#size' => $field['multiple'] ? min(count($options), 6) : 0,
154 '#options' => $options,
155 '#required' => $field['required'],
156 '#description' => t($field['widget']['description']),
157 );
158
159 return $form;
160
161 case 'process form values':
162 if ($field['multiple']) {
163 // drop the 'none' option
164 unset($items['cids']['none']);
165 if (!empty($items['cids'])) {
166 $items = array_values(content_transpose_array_rows_cols(array('cid' => $items['cids'])));
167 }
168 else {
169 $items[0]['cid'] = '';
170 }
171 }
172 else {
173 $items[0]['cid'] = ($items['cids'] != 'none') ? $items['cids'] : '';
174 }
175 // Remove the widget's data representation so it isn't saved.
176 unset($items['cids']);
177 foreach ($items as $delta => $item) {
178 $items[$delta]['error_field'] = $field['field_name'] .'][cids';
179 }
180 }
181 }
182 else {
183 switch ($op) {
184 case 'prepare form values':
185 foreach ($items as $delta => $item) {
186 if (!empty($items[$delta]['cid'])) {
187 $items[$delta]['default subject'] = db_result(db_query("SELECT subject FROM {comments} WHERE cid = '%d'", $items[$delta]['cid']));
188 $items[$delta]['default subject'] .= ' [cid:'. $items[$delta]['cid'] .']';
189 }
190 }
191 break;
192
193 case 'form':
194 $form = array();
195 $form[$field['field_name']] = array('#tree' => TRUE);
196
197 if ($field['multiple']) {
198 $form[$field['field_name']]['#type'] = 'fieldset';
199 $form[$field['field_name']]['#description'] = t($field['widget']['description']);
200 $delta = 0;
201 foreach ($items as $item) {
202 if ($item['cid']) {
203 $form[$field['field_name']][$delta]['subject'] = array(
204 '#type' => 'textfield',
205 '#title' => ($delta == 0) ? t($field['widget']['label']) : '',
206 '#autocomplete_path' => 'commentreference/autocomplete/'. $field['field_name'],
207 '#default_value' => $item['default subject'],
208 '#required' => ($delta == 0) ? $field['required'] : FALSE,
209 );
210 $delta++;
211 }
212 }
213 foreach (range($delta, $delta + 2) as $delta) {
214 $form[$field['field_name']][$delta]['subject'] = array(
215 '#type' => 'textfield',
216 '#title' => ($delta == 0) ? t($field['widget']['label']) : '',
217 '#autocomplete_path' => 'commentreference/autocomplete/'. $field['field_name'],
218 '#default_value' => '',
219 '#required' => ($delta == 0) ? $field['required'] : FALSE,
220 );
221 }
222 }
223 else {
224 $form[$field['field_name']][0]['subject'] = array(
225 '#type' => 'textfield',
226 '#title' => t($field['widget']['label']),
227 '#autocomplete_path' => 'commentreference/autocomplete/'. $field['field_name'],
228 '#default_value' => $items[0]['default subject'],
229 '#required' => $field['required'],
230 '#description' => t($field['widget']['description']),
231 );
232 }
233 return $form;
234
235 case 'process form values':
236 foreach ($items as $delta => $item) {
237 $cid = 0;
238 if (!empty($item['subject'])) {
239 preg_match('/^(?:\s*|(.*) )?\[\s*cid\s*:\s*(\d+)\s*\]$/', $item['subject'], $matches);
240 if (!empty($matches)) {
241 // explicit cid
242 $cid = $matches[2];
243 }
244 else {
245 // no explicit cid
246 // TODO :
247 // the best thing would be to present the user with an additional form,
248 // allowing the user to choose between valid candidates with the same title
249 // ATM, we pick the first matching candidate...
250 $cids = _comment_potential_references($field, $item['subject'], TRUE);
251 $cid = (!empty($cids)) ? array_shift(array_keys($cids)) : 0;
252 }
253 }
254 // Remove the widget's data representation so it isn't saved.
255 unset($items[$delta]['subject']);
256 $items[$delta]['cid'] = $cid;
257 $items[$delta]['error_field'] = $field['field_name'] .']['. $delta .'][subject';
258 // Don't save empty fields except the first value
259 if (empty($cid) && $delta > 0) {
260 unset($items[$delta]);
261 }
262 }
263 }
264 }
265 }
266
267 /**
268 * Fetch an array of all candidate referenced comments, for use in presenting the selection form to the user.
269 */
270 function _commentreference_potential_references($field, $string = '', $exact_string = false, $full_comment = TRUE) {
271
272 $args = array();
273
274 // Is status needed ? Should this be 0 always ?
275 $string_clause = ' WHERE c.status = 0 ';
276 if (isset($string)) {
277 $string_clause .= $exact_string ? " AND c.subject LIKE '%s%'" : " AND c.subject LIKE '%%%s%'";
278 $args[] = $string;
279 }
280
281 $result = db_query('SELECT c.subject, c.cid FROM {comments} c '.$string_clause.' ORDER BY c.subject ASC', $args);
282 if (db_num_rows($result) == 0) {
283 return array();
284 }
285
286 $comments = array();
287 while ($comment = db_fetch_object($result)) {
288 if ($full_comment == TRUE)
289 $comments[$comment->cid] = $comment;
290 else
291 $comments[$comment->cid] = $comment->subject;
292 }
293 return $comments;
294 }
295
296 /**
297 * Retrieve a pipe delimited string of autocomplete suggestions
298 */
299 function commentreference_autocomplete($field_name, $string = '') {
300 $fields = content_fields();
301 $field = $fields[$field_name];
302 $matches = array();
303
304 foreach (_commentreference_potential_references($field, $string) as $row) {
305 $matches[$row->subject .' [cid:'. $row->cid .']'] = check_plain($row->subject);
306 }
307 print drupal_to_js($matches);
308 exit();
309 }
310

  ViewVC Help
Powered by ViewVC 1.1.2