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

Contents of /contributions/modules/flexinode/flexinode.module

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


Revision 1.82 - (show annotations) (download) (as text)
Tue Jan 23 20:54:01 2007 UTC (2 years, 10 months ago) by ber
Branch: MAIN
CVS Tags: DRUPAL-4-7--0-1, HEAD
Changes since 1.81: +1 -3 lines
File MIME type: text/x-php
Removed to leftover debug print_r's. Sorry.
1 <?php
2 // $Id: flexinode.module,v 1.81 2006/12/25 17:05:35 ber Exp $
3
4 // Copyright 2003-2004 Jonathan Chaffer. See LICENSE for redistribution allowances.
5
6 /**
7 * Return a list of all installed field types.
8 */
9 function flexinode_field_types() {
10 static $types;
11
12 if (!isset($types)) {
13 $types = array();
14 $path = drupal_get_path('module', 'flexinode');
15 $files = file_scan_directory($path, '^field_.*\.inc$');
16 foreach ($files as $filename => $file) {
17 include_once($filename);
18 $function = 'flexinode_'. $file->name .'_name';
19 if(function_exists($function)) {
20 $types[] = substr($file->name, 6);
21 }
22 }
23 }
24 return $types;
25 }
26
27 // Load all installed field types.
28 flexinode_field_types();
29
30 /**
31 * Implementation of hook_help().
32 */
33 function flexinode_help($section) {
34 switch ($section) {
35 case 'admin/help#flexinode':
36 $output = '<p>'. t('The flexinode module allows administrators to create simple new content types. Administrators find it very useful to create new types of content without having to program a new content module. This module is the core of flexinode. You will need other modules, such as flexinode_admin, to actually manage the content types.') .'</p>';
37 $output .= '<p>'. t('When creating a new flexinode, administrators are presented with a flexinode form to create their new content type. Once administrators have created their flexinode they can accept the format or choose to theme the content type to change it\'s presentation. For users, creating content that is a flexinode is just like adding other content. The flexinode content type will show up alongside all normal content.') .'</p>';
38 case 'admin/modules#description':
39 return t('Manages flexinode content and fields.');
40 }
41
42 $output = '';
43
44 if (strpos($section, 'node/add') === 0) {
45 foreach (flexinode_content_types() as $type => $name) {
46 if ($section == 'node/add#flexinode-' . $type) {
47 $ctype = flexinode_load_content_type($type);
48 $output .= t($ctype->description);
49 }
50 if ($section == 'node/add/flexinode-' . $type) {
51 $ctype = flexinode_load_content_type($type);
52 $output .= t($ctype->help);
53 }
54 }
55 }
56
57 return $output;
58 }
59
60 /**
61 * Implementation of hook_perm().
62 */
63 function flexinode_perm() {
64 $perms = array('administer content types');
65 foreach (flexinode_content_types() as $ctype) {
66 $perms[] = 'create '. $ctype->name .' content';
67 $perms[] = 'edit own '. $ctype->name .' content';
68 $perms[] = 'edit any '. $ctype->name .' content';
69 }
70 return $perms;
71 }
72
73 /**
74 * Implementation of hook_menu().
75 */
76 function flexinode_menu($may_cache) {
77 $items = array();
78
79 if ($may_cache) {
80 foreach (flexinode_content_types() as $ctype) {
81 $items[] = array(
82 'path' => 'node/add/flexinode-'. $ctype->ctype_id,
83 'title' => t($ctype->name),
84 'access' => user_access('create '. $ctype->name .' content') or $admin_access
85 );
86 }
87 }
88
89 return $items;
90 }
91
92 /**
93 * CORE HOOKS
94 */
95
96 /**
97 * Implementation of hook_node_info().
98 */
99 function flexinode_node_info() {
100 $types = array();
101 foreach (flexinode_content_types() as $type => $name) {
102 $types['flexinode-'. $name->ctype_id] =
103 array('name' => $name->name ? t($name->name) : t('flexible content'),
104 'base' => 'flexinode');
105 }
106 return $types;
107 }
108
109 /**
110 * Implementation of hook_access().
111 */
112 function flexinode_access($op, $node) {
113 global $user;
114
115 if (!is_object($node)) {
116 $type = $node;
117 $node = new StdClass();
118 $node->type = $type;
119 }
120
121 if ($op == 'create') {
122 return user_access('create '. node_get_name($node) .' content');
123 }
124
125 if ($op == 'update') {
126 foreach ($node as $fieldname => $field) {
127 if (preg_match('!flexinode_[0-9]+_format!', $fieldname) && !filter_access($field)) {
128 return FALSE;
129 }
130 }
131 }
132
133 if ($op == 'update' || $op == 'delete') {
134 if (user_access('edit any '. node_get_name($node) .' content')) {
135 return TRUE;
136 }
137 elseif (user_access('edit own '. node_get_name($node) .' content') && ($user->uid == $node->uid)) {
138 return TRUE;
139 }
140 }
141 }
142
143 /**
144 * Implementation of hook_load().
145 */
146 function flexinode_load($node) {
147 $ctype = flexinode_load_content_type(substr($node->type, 10));
148
149 // build the query
150 $fields_to_select = array();
151 $table_joins = array();
152
153 foreach ($ctype->fields as $field) {
154 $fieldname = 'flexinode_'. $field->field_id;
155
156 $fields_to_select[] = flexinode_invoke('db_select', $field);
157 $table_joins[] = 'LEFT JOIN {flexinode_data} '. $fieldname .' ON n.nid = '. $fieldname .'.nid AND '. $fieldname .'.field_id = ' . $field->field_id;
158 }
159
160 if (count($fields_to_select) > 0) {
161 // make the query
162 $flexinode = db_fetch_object(db_query('SELECT '. implode(', ', $fields_to_select) .' FROM {node} n '. implode(' ', $table_joins) .' WHERE n.nid = %d', $node->nid));
163
164 // unserialize necessary fields
165 foreach ($ctype->fields as $field) {
166 $fieldname = 'flexinode_'. $field->field_id;
167 $field_data = flexinode_invoke('load', $field, $flexinode);
168 if ($field_data) {
169 $flexinode->$fieldname = $field_data;
170 }
171 }
172 }
173
174 $flexinode->ctype_id = $ctype->ctype_id;
175
176 return $flexinode;
177 }
178
179 /**
180 * Implementation of hook_insert().
181 */
182 function flexinode_insert($node) {
183 $ctype = flexinode_load_content_type($node->ctype_id);
184 foreach ($ctype->fields as $field) {
185 flexinode_invoke('insert', $field, $node);
186 }
187 }
188
189 /**
190 * Implementation of hook_update().
191 */
192 function flexinode_update($node) {
193 $ctype = flexinode_load_content_type($node->ctype_id);
194 foreach ($ctype->fields as $field) {
195 flexinode_invoke('delete', $field, $node, FALSE);
196 }
197 db_query('DELETE FROM {flexinode_data} WHERE nid = %d', $node->nid);
198 foreach ($ctype->fields as $field) {
199 flexinode_invoke('insert', $field, $node);
200 }
201 }
202
203 /**
204 * Implementation of hook_delete().
205 */
206 function flexinode_delete($node) {
207 $ctype = flexinode_load_content_type($node->ctype_id);
208 foreach ($ctype->fields as $field) {
209 flexinode_invoke('delete', $field, $node, TRUE);
210 }
211 db_query('DELETE FROM {flexinode_data} WHERE nid = %d', $node->nid);
212 }
213
214 /**
215 * Implementation of hook_form().
216 */
217 function flexinode_form(&$node, &$param) {
218 // Set form parameters so we can accept file uploads.
219 $form['#attributes'] = array('enctype' => 'multipart/form-data');
220
221 if (!isset($node->ctype_id)) {
222 $node->ctype_id = substr($node->type, 10);
223 }
224 $ctype = flexinode_load_content_type($node->ctype_id);
225
226 foreach ($ctype->fields as $field) {
227 $items = flexinode_invoke('form', $field, $node);
228 foreach($items as $key => $item) {
229 $form[$key] = $item;
230 }
231 }
232
233 $form['title'] = array(
234 '#type' => 'textfield',
235 '#title' => t('Title'),
236 '#default_value' => $node->title,
237 '#size' => 60,
238 '#maxlength' => 128,
239 '#required' => TRUE,
240 );
241
242 $form['ctype_id'] = array(
243 '#type' => 'hidden',
244 '#value' => $node->ctype_id,
245 );
246
247 return $form;
248 }
249
250 /**
251 * Implementation of hook_validate().
252 */
253 function flexinode_validate($node) {
254 if (isset($node->ctype_id)) {
255 $ctype = flexinode_load_content_type($node->ctype_id);
256 foreach ($ctype->fields as $field) {
257 $fieldname = 'flexinode_'. $field->field_id;
258 $validation = flexinode_invoke('validate', $field, $node);
259 }
260 }
261 }
262
263 /**
264 * Implementation of hook_submit().
265 */
266 function flexinode_submit(&$node) {
267 if (isset($node->ctype_id)) {
268 $ctype = flexinode_load_content_type($node->ctype_id);
269 foreach ($ctype->fields as $field) {
270 if ($result = flexinode_invoke('execute', $field, $node)) {
271 $fieldname = 'flexinode_'. $field->field_id;
272 $node->$fieldname = $result;
273 }
274 }
275 // Pre-render the body and teaser fields, so the Drupal search works.
276 $node = flexinode_content($node);
277 }
278 }
279
280 /**
281 * Implementation of hook_view().
282 */
283 function flexinode_view(&$node, $teaser = FALSE, $page = FALSE) {
284 $node = flexinode_content($node, $teaser);
285 }
286
287 function flexinode_content($node, $teaser = FALSE) {
288 if (isset($node->ctype_id)) {
289 $ctype = flexinode_load_content_type($node->ctype_id);
290
291 $node->readmore = FALSE;
292 $node->body = '<div class="flexinode-body flexinode-'. $node->ctype_id .'">';
293 $node->teaser = '<div class="flexinode-body flexinode-'. $node->ctype_id .'">';
294
295 foreach ($ctype->fields as $field) {
296 $fieldname = 'flexinode_'. $field->field_id;
297 if (isset($node->$fieldname)) {
298 $body_data = flexinode_invoke('format', $field, $node, FALSE);
299 $teaser_data = flexinode_invoke('format', $field, $node, TRUE);
300 if (!empty($body_data) && $body_data) {
301 $node->body .= theme('flexinode_'. $field->field_type, $field->field_id, $field->label, $node->$fieldname, $teaser ? $teaser_data : $body_data);
302 if ($field->show_teaser) {
303 if ($body_data != $teaser_data) {
304 $node->readmore = TRUE;
305 }
306 $node->teaser .= theme('flexinode_'. $field->field_type, $field->field_id, $field->label, $node->$fieldname, $teaser_data);
307 }
308 else {
309 $node->readmore = TRUE;
310 }
311 }
312 }
313 }
314
315 $node->body .= '</div>';
316 $node->teaser .= '</div>';
317
318 return $node;
319 }
320 }
321
322 /**
323 * Implementation of hook_file_download().
324 */
325 function flexinode_file_download($file) {
326 if (!$file) return false;
327 $result = db_fetch_object(db_query("SELECT f.* FROM {flexinode_data} f WHERE f.textual_data = '%s'", $file));
328 if (!$result) return false;
329 $filedb = unserialize($result->serialized_data);
330 if ($filedb->type) {
331 return array('Content-type: '. $filedb->type, 'Content-Disposition: attachment; filename="'. $file .'"');
332 }
333 if ($path = file_create_path($file)) {
334 list($width, $height, $type, $attr) = getimagesize($path);
335 $types = array(
336 IMAGETYPE_GIF => 'image/gif',
337 IMAGETYPE_JPEG => 'image/jpeg',
338 IMAGETYPE_PNG => 'image/png',
339 IMAGETYPE_SWF => 'application/x-shockwave-flash',
340 IMAGETYPE_PSD => 'image/psd',
341 IMAGETYPE_BMP => 'image/bmp',
342 IMAGETYPE_TIFF_II => 'image/tiff',
343 IMAGETYPE_TIFF_MM => 'image/tiff',
344 IMAGETYPE_JPC => 'application/octet-stream',
345 IMAGETYPE_JP2 => 'image/jp2',
346 IMAGETYPE_JPX => 'application/octet-stream',
347 IMAGETYPE_JB2 => 'application/octet-stream',
348 IMAGETYPE_SWC => 'application/x-shockwave-flash',
349 IMAGETYPE_IFF => 'image/iff',
350 IMAGETYPE_WBMP => 'image/vnd.wap.wbmp',
351 IMAGETYPE_XBM => 'image/xbm'
352 );
353 if (isset($types[$type])) {
354 return array('Content-type: '. $types[$type], 'Content-Disposition: attachment; filename="'. $file .'"');
355 }
356 else {
357 $type = (function_exists('mime_content_type') ? mime_content_type($path) : 'application/x-download');
358 return array('Content-type: '. $type, 'Content-Disposition: attachment; filename="'. $file .'"');
359 }
360 }
361 }
362
363 /**
364 * Implementation of hook_nodeapi().
365 */
366 function flexinode_nodeapi(&$node, $op, $teaser, $page) {
367 switch ($op) {
368 case 'rss item':
369 if (isset($node->ctype_id)) {
370 $keys = array();
371 $ctype = flexinode_load_content_type($node->ctype_id);
372 foreach ($ctype->fields as $field) {
373 $fieldname = 'flexinode_'. $field->field_id;
374 $key = array();
375 if (isset($node->$fieldname)) {
376 $key = flexinode_invoke('rss', $field, $node);
377 if(count($key)) {
378 $keys[] = $key;
379 }
380 }
381 }
382 return $keys;
383 }
384 break;
385 }
386 }
387
388 /**
389 * Implementation of hook_cron().
390 */
391 function flexinode_cron() {
392 flexinode_invoke_all('cron');
393 }
394
395 /**
396 * FLEXINODE CONTENT TYPE FUNCTIONS
397 */
398
399 /**
400 * Return a list of content types.
401 *
402 * The returned array contains basic information about each type, but the heavy
403 * lifting of loading all field descriptions, for example, is not yet done.
404 */
405 function flexinode_content_types() {
406 static $types;
407 if (!isset($types)) {
408 $types = array();
409 $result = db_query('SELECT * FROM {flexinode_type}');
410 while ($type = db_fetch_object($result)) {
411 $types[$type->ctype_id] = $type;
412 }
413 }
414 return $types;
415 }
416
417 /**
418 * Return a content type object.
419 */
420 function flexinode_load_content_type($ctype_id) {
421 static $content_types;
422
423 if (isset($content_types[$ctype_id])) {
424 return $content_types[$ctype_id];
425 }
426
427 $ctype = db_fetch_object(db_query('SELECT * FROM {flexinode_type} WHERE ctype_id = %d', $ctype_id));
428
429 $ctype->fields = array();
430 $result = db_query('SELECT * FROM {flexinode_field} WHERE ctype_id = %d ORDER BY weight ASC, label ASC', $ctype_id);
431 while ($field = db_fetch_object($result)) {
432 $field->options = unserialize($field->options);
433 $ctype->fields[] = $field;
434 }
435
436 $content_types[$ctype_id] = $ctype;
437 return $ctype;
438 }
439
440
441 /**
442 * FLEXINODE FIELD FUNCTIONS
443 */
444
445 /**
446 * Invoke a field hook.
447 *
448 * Each field type has different behavior, so the differences are separated out
449 * into include files which themselves behave much like Drupal modules.
450 */
451 function flexinode_invoke($hook, $field, $a1 = NULL, $a2 = NULL, $a3 = NULL) {
452 $type = is_string($field) ? $field : $field->field_type;
453 $function = 'flexinode_field_'. $type .'_'. $hook;
454
455 if (function_exists($function)) {
456 return ($function($field, $a1, $a2, $a3));
457 }
458 }
459
460 /**
461 * Invoke a field hook for all field types.
462 */
463 function flexinode_invoke_all($hook, $a1 = NULL, $a2 = NULL, $a3 = NULL) {
464 $result = array();
465 foreach (flexinode_field_types() as $type) {
466 $function = 'flexinode_field_'. $type .'_'. $hook;
467 if (function_exists($function)) {
468 $result = array_merge($result, $function($a1, $a2, $a3));
469 }
470 }
471 return $result;
472 }
473
474 /**
475 * Return a field object.
476 */
477 function flexinode_load_field($field_id) {
478 $field = db_fetch_object(db_query('SELECT * FROM {flexinode_field} WHERE field_id = %d', $field_id));
479 $field->options = unserialize($field->options);
480 return $field;
481 }

  ViewVC Help
Powered by ViewVC 1.1.2