1
|
<?php
|
2
|
// $Id: softwareTracker.module 2505 2008-05-28 15:47:04Z a.kohlbecker $
|
3
|
|
4
|
/**
|
5
|
* @file
|
6
|
* TODO ???
|
7
|
*/
|
8
|
|
9
|
|
10
|
/**
|
11
|
* Display help and module information
|
12
|
* @param section which section of the site we're displaying help
|
13
|
* @return help text for section
|
14
|
*/
|
15
|
function softwareTracker_help($section='') {
|
16
|
|
17
|
$out = '';
|
18
|
switch ($section) {
|
19
|
case "admin/modules#description":
|
20
|
$out = t("");
|
21
|
break;
|
22
|
case 'node/add#portfolio':
|
23
|
return t("A Software Tracker Page to describe and categorize applications, services etc.");
|
24
|
}
|
25
|
return $out;
|
26
|
}
|
27
|
|
28
|
|
29
|
/**
|
30
|
* Implementation of hook_node_info().
|
31
|
* Define the node type
|
32
|
*/
|
33
|
function softwareTracker_node_info() {
|
34
|
return array('softwareTracker' => array(
|
35
|
'name' => t('Software Tracker Node'),
|
36
|
'module' => 'softwareTracker'),
|
37
|
'description' => t("Note Type for a Software Tracker Application.
|
38
|
Software (applications, services etc) can be
|
39
|
categorized and described by means of this node type.")
|
40
|
);
|
41
|
}
|
42
|
|
43
|
/**
|
44
|
* Valid permissions for this module
|
45
|
* @return array An array of valid permissions for the portfolio module
|
46
|
*/
|
47
|
function softwareTracker_perm() {
|
48
|
return array(
|
49
|
'create tracker entry',
|
50
|
'edit tracker entry',
|
51
|
'edit own tracker entry',
|
52
|
'publish tracker entry'
|
53
|
);
|
54
|
}
|
55
|
|
56
|
|
57
|
function softwareTracker_access($op, &$node) {
|
58
|
global $user;
|
59
|
|
60
|
|
61
|
// drupal_set_message('<pre>'.print_r($node, true).'</pre>');
|
62
|
if ($op == 'create') {
|
63
|
return user_access('create tracker entry');
|
64
|
}
|
65
|
else if ($op == 'view') {
|
66
|
return (user_access('access content') && $node->status > 0)
|
67
|
|| (
|
68
|
($user->uid == $node->uid && user_access('edit own tracker entry'))
|
69
|
|| user_access('edit tracker entry')
|
70
|
);
|
71
|
}
|
72
|
else if ($op == 'update' || $op == 'delete') {
|
73
|
if(
|
74
|
($user->uid == $node->uid && user_access('edit own tracker entry'))
|
75
|
|| user_access('edit tracker entry')
|
76
|
) {
|
77
|
return true;
|
78
|
}
|
79
|
else {
|
80
|
return false;
|
81
|
}
|
82
|
}
|
83
|
else {
|
84
|
return false;
|
85
|
}
|
86
|
}
|
87
|
|
88
|
|
89
|
function softwareTracker_menu($may_cache) {
|
90
|
|
91
|
global $user;
|
92
|
|
93
|
if($may_cache){
|
94
|
// --- admin items
|
95
|
$items[] = array(
|
96
|
'path' => 'admin/settings/softwareTracker',
|
97
|
'title' => t('Software Tracker'),
|
98
|
'description' => t('Configure the SoftwareTracker Module'),
|
99
|
'callback' => 'drupal_get_form',
|
100
|
'callback arguments' => array('softwareTracker_settings'),
|
101
|
'access' => user_access('administer site configuration'),
|
102
|
'type' => MENU_NORMAL_ITEM, // optional
|
103
|
);
|
104
|
|
105
|
// --- software list items
|
106
|
/*
|
107
|
* softwareTracker
|
108
|
* softwareTracker/list
|
109
|
* softwareTracker/list/all/fadd/{vocab}/{term}
|
110
|
* softwareTracker/list/all/frem/{vocab}/{term}
|
111
|
* softwareTracker/list/own
|
112
|
* softwareTracker/list/unpublished
|
113
|
* softwareTracker/search
|
114
|
* softwareTracker/feed/{mode}/{type}/{domain}
|
115
|
*/
|
116
|
|
117
|
$items[] = array(
|
118
|
'path' => 'softwareTracker',
|
119
|
'title' => t('List All'),
|
120
|
'description' => t('List of all tracker entries'),
|
121
|
'callback' => 'softwareTracker_filtered_list',
|
122
|
'callback arguments' => array('list', 'all'),
|
123
|
'access' => true,
|
124
|
'type' => MENU_CALLBACK,
|
125
|
);
|
126
|
|
127
|
$items[] = array(
|
128
|
'path' => 'softwareTracker/list',
|
129
|
'title' => t('List All'),
|
130
|
'description' => t('List of all tracker entries'),
|
131
|
'callback' => 'softwareTracker_filtered_list', //'node_page', //softwareTracker_filtered_list',
|
132
|
'access' => true,
|
133
|
'type' => MENU_CALLBACK,
|
134
|
);
|
135
|
|
136
|
$items[] = array(
|
137
|
'path' => 'softwareTracker/list/all',
|
138
|
'title' => t('All'),
|
139
|
'description' => t('List of all tracker entries'),
|
140
|
'callback' => 'softwareTracker_filtered_list',
|
141
|
'callback arguments' => array('all'),
|
142
|
'access' => true,
|
143
|
'type' => MENU_DEFAULT_LOCAL_TASK,
|
144
|
);
|
145
|
|
146
|
$items[] = array(
|
147
|
'path' => 'softwareTracker/list/own',
|
148
|
'title' => t('Own'),
|
149
|
'description' => t('List of own tracker entries'),
|
150
|
'callback' => 'softwareTracker_filtered_list',
|
151
|
'callback arguments' => array('own'),
|
152
|
'access' => $user->uid != 0, // anonymous has uid 0
|
153
|
'type' => MENU_LOCAL_TASK,
|
154
|
);
|
155
|
|
156
|
$items[] = array(
|
157
|
'path' => 'softwareTracker/list/unpublished',
|
158
|
'title' => t('Unpublished'),
|
159
|
'description' => t('List of unpublished tracker entries'),
|
160
|
'callback' => 'softwareTracker_filtered_list',
|
161
|
'callback arguments' => array('unpublished'),
|
162
|
'access' => $user->uid != 0, // anonymous has uid 0
|
163
|
'type' => MENU_LOCAL_TASK,
|
164
|
);
|
165
|
|
166
|
$items[] = array(
|
167
|
'path' => 'softwareTracker/feed',
|
168
|
//'title' => t('RSS'),
|
169
|
//'description' => t('RSS feed of tracker entries'),
|
170
|
'callback' => 'softwareTracker_feed',
|
171
|
'type' => MENU_CALLBACK,
|
172
|
);
|
173
|
|
174
|
|
175
|
} else {
|
176
|
// Add the CSS for this module
|
177
|
// We put this in !$may_cache so it's only added once per request
|
178
|
drupal_add_css(drupal_get_path('module', 'softwareTracker') .'/softwareTracker.css');
|
179
|
}
|
180
|
return $items;
|
181
|
|
182
|
}
|
183
|
|
184
|
|
185
|
// ====================== Admin & Edit Forms ===================== //
|
186
|
|
187
|
function softwareTracker_settings() {
|
188
|
|
189
|
$form = array();
|
190
|
|
191
|
$vocabs = taxonomy_get_vocabularies('softwareTracker');
|
192
|
$options = array();
|
193
|
$options[''] = "-- please select --";
|
194
|
foreach($vocabs as $voc){
|
195
|
$options["$voc->vid"] = $voc->name;
|
196
|
}
|
197
|
/*
|
198
|
$form['softwareTracker_debug'] = array(
|
199
|
'#type' => 'markup',
|
200
|
'#value' =>'<pre style="font-size:80%">'.print_r($vocabs, true).'</pre>'
|
201
|
);
|
202
|
*/
|
203
|
|
204
|
$form['softwareTracker_vocab_os_platform'] = array(
|
205
|
'#type' => 'select',
|
206
|
'#title' => t('Operation System Vocabulary'),
|
207
|
'#default_value' => variable_get('softwareTracker_vocab_os_platform', 'none'),
|
208
|
'#options' => $options,
|
209
|
'#description' => t('The vocabulary containing operation system terms'),
|
210
|
'#required' => true,
|
211
|
'#weight' => -10
|
212
|
);
|
213
|
|
214
|
$form['softwareTracker_vocab_type'] = array(
|
215
|
'#type' => 'select',
|
216
|
'#title' => t('Software Type Vocabulary'),
|
217
|
'#default_value' => variable_get('softwareTracker_vocab_type', 'none'),
|
218
|
'#options' => $options,
|
219
|
'#required' => true,
|
220
|
'#weight' => -9
|
221
|
);
|
222
|
|
223
|
$form['softwareTracker_vocab_domain'] = array(
|
224
|
'#type' => 'select',
|
225
|
'#title' => t('Software Domain'),
|
226
|
'#default_value' => variable_get('softwareTracker_vocab_domain', 'none'),
|
227
|
'#options' => $options,
|
228
|
'#required' => true,
|
229
|
'#weight' => -8
|
230
|
);
|
231
|
|
232
|
return system_settings_form($form);
|
233
|
}
|
234
|
|
235
|
function softwareTracker_form(&$node, &$param) {
|
236
|
|
237
|
$form = array();
|
238
|
$form['#attributes'] = array('enctype' => 'multipart/form-data');
|
239
|
|
240
|
if(user_access('publish tracker entry')){
|
241
|
$form['publish_tracker_entry'] = array(
|
242
|
'#type'=>'checkbox',
|
243
|
'#title' => t('Publish this tracker entry'),
|
244
|
'#default_value' => $node->status,
|
245
|
'#weight' => -6
|
246
|
);
|
247
|
}
|
248
|
|
249
|
$form['title'] = array(
|
250
|
'#type' => 'textfield',
|
251
|
'#title' => t('Title'),
|
252
|
'#default_value' => $node->title,
|
253
|
'#description' => t('The name of the application, service etc.'),
|
254
|
'#required' => TRUE,
|
255
|
'#weight' => -5
|
256
|
);
|
257
|
|
258
|
$form['certified'] = array(
|
259
|
'#type' => 'checkbox',
|
260
|
'#title' => t('Edit Certification'),
|
261
|
'#default_value' => $node->certified != 0 ? 1 : 0,
|
262
|
'#description' => t('Check this box if software is certified by <a href="http://www.e-taxonomy.eu/">EDIT</a>.'.ord($node->certified)),
|
263
|
'#required' => false,
|
264
|
'#weight' => -4
|
265
|
);
|
266
|
|
267
|
|
268
|
// --------- icon fieldset ---------
|
269
|
$form['icon'] = array(
|
270
|
'#type' => 'fieldset',
|
271
|
'#title' => t('Icon'),
|
272
|
'#collapsible' => TRUE,
|
273
|
'#collapsed' => !$node->icon,
|
274
|
'#weight' => -2
|
275
|
);
|
276
|
|
277
|
$form['icon']['icon_file'] = array(
|
278
|
'#type' => 'file',
|
279
|
'#title' => t('Icon'),
|
280
|
'#required' => FALSE,
|
281
|
);
|
282
|
|
283
|
if ($node->icon) {
|
284
|
$form['icon']['#description'] = t('An icon already exists ['.$node->icon.'], if you upload another one the current file will be replaced.');
|
285
|
|
286
|
$form['icon']['icon_drop'] = array(
|
287
|
'#type' => 'checkbox',
|
288
|
'#title' => t('Drop Icon'),
|
289
|
'#description' => t('Check this to drop <i>'.$node->icon.'</i>'),
|
290
|
'#required' => FALSE
|
291
|
);
|
292
|
}
|
293
|
|
294
|
$form['icon']['icon_in_store'] = array(
|
295
|
'#type' => 'hidden',
|
296
|
'#default_value' => $node->icon
|
297
|
);
|
298
|
|
299
|
// --------- END icon fieldset ---------
|
300
|
|
301
|
$form['characterization'] = array(
|
302
|
'#type' => 'textarea',
|
303
|
'#title' => t('Description'),
|
304
|
'#default_value' => $node->characterization,
|
305
|
'#required' => FALSE,
|
306
|
'#rows' => 8,
|
307
|
'#weight' => 1
|
308
|
);
|
309
|
|
310
|
$form['review'] = array(
|
311
|
'#type' => 'textarea',
|
312
|
'#title' => t('Review'),
|
313
|
'#default_value' => $node->review,
|
314
|
'#required' => FALSE,
|
315
|
'#rows' => 8,
|
316
|
'#weight' => 2
|
317
|
);
|
318
|
|
319
|
$form['version'] = array(
|
320
|
'#type' => 'textfield',
|
321
|
'#title' => t('Version'),
|
322
|
'#description' => t('The software version'),
|
323
|
'#default_value' => $node->version,
|
324
|
'#required' => FALSE,
|
325
|
'#weight' => 4
|
326
|
);
|
327
|
|
328
|
// !!!!!!!!!!!!!!!!!!!!! ('#weight' => 5) is reserved by drupal !!
|
329
|
|
330
|
$form['software_author'] = array(
|
331
|
'#type' => 'textfield',
|
332
|
'#title' => t('Author'),
|
333
|
'#description' => t('The author (person, institution, company etc.) of the software.'),
|
334
|
'#default_value' => $node->software_author,
|
335
|
'#required' => FALSE,
|
336
|
'#weight' => 6
|
337
|
);
|
338
|
|
339
|
$form['home_url'] = array(
|
340
|
'#type' => 'textfield',
|
341
|
'#title' => t('Homepage URL'),
|
342
|
'#description' => t('The homepage of the software. You must not forget to add the leading http://'),
|
343
|
'#default_value' => ($node->home_url ? $node->home_url : 'http://'),
|
344
|
'#required' => FALSE,
|
345
|
'#weight' => 7
|
346
|
);
|
347
|
|
348
|
$form['download_url'] = array(
|
349
|
'#type' => 'textfield',
|
350
|
'#title' => t('Download URL'),
|
351
|
'#description' => t('URL for direct download or to the page from where the software can be downloaded, ordered etc. You must not forget to add the leading http://'),
|
352
|
'#default_value' => ($node->download_url ? $node->download_url : 'http://'),
|
353
|
'#required' => FALSE,
|
354
|
'#weight' => 8
|
355
|
);
|
356
|
|
357
|
$form['license'] = array(
|
358
|
'#type' => 'select',
|
359
|
'#title' => t('License Type'),
|
360
|
'#default_value' => isset($node->license) ? $node->license : 'unknown',
|
361
|
//TODO a vocabulary should be used for license type
|
362
|
'#options' => array('unknown'=>'unknown', 'open source'=>'open source', 'freeware'=>'freeware', 'shareware'=>'shareware', 'commercial'=>'commercial' ),
|
363
|
'#weight' => 9
|
364
|
);
|
365
|
|
366
|
$form['price'] = array(
|
367
|
'#type' => 'textfield',
|
368
|
'#title' => t('Price'),
|
369
|
'#default_value' => $node->price,
|
370
|
'#required' => FALSE,
|
371
|
'#weight' => 10
|
372
|
);
|
373
|
|
374
|
$form['system_requirements'] = array(
|
375
|
'#type' => 'textarea',
|
376
|
'#title' => t('System Requirements'),
|
377
|
//'#description' => t('The software version'),
|
378
|
'#default_value' => $node->system_requirements,
|
379
|
'#required' => FALSE,
|
380
|
'#rows' => 8,
|
381
|
'#weight' => 12
|
382
|
);
|
383
|
|
384
|
$form['interface'] = array(
|
385
|
'#type' => 'textarea',
|
386
|
'#title' => t('Interfaces & Data Standards'),
|
387
|
//'#description' => t('The software version'),
|
388
|
'#default_value' => $node->interface,
|
389
|
'#required' => FALSE,
|
390
|
'#rows' => 8,
|
391
|
'#weight' => 13
|
392
|
);
|
393
|
|
394
|
|
395
|
// --------- screenshot fieldset ---------
|
396
|
$form['screenshot'] = array(
|
397
|
'#type' => 'fieldset',
|
398
|
'#title' => t('Screenshot'),
|
399
|
'#collapsible' => TRUE,
|
400
|
'#collapsed' => !$node->screenshot,
|
401
|
'#weight' => 14
|
402
|
);
|
403
|
|
404
|
$form['screenshot']['screenshot_file'] = array(
|
405
|
'#type' => 'file',
|
406
|
'#title' => t('Screenshot'),
|
407
|
'#required' => FALSE,
|
408
|
);
|
409
|
|
410
|
if ($node->screenshot) {
|
411
|
$form['screenshot']['#description'] = t('A screenshot already exists ['.$node->screenshot.'], if you upload another screenshot the current one will be replaced.');
|
412
|
|
413
|
$form['screenshot']['screenshot_drop'] = array(
|
414
|
'#type' => 'checkbox',
|
415
|
'#title' => t('Drop screenshot'),
|
416
|
'#description' => t('Check this to drop <i>'.$node->screenshot.'</i>'),
|
417
|
'#required' => FALSE,
|
418
|
);
|
419
|
}
|
420
|
|
421
|
$form['screenshot']['screenshot_in_store'] = array(
|
422
|
'#type' => 'hidden',
|
423
|
'#default_value' => $node->screenshot
|
424
|
);
|
425
|
|
426
|
// --------- END screenshot fieldset ---------
|
427
|
|
428
|
return $form;
|
429
|
}
|
430
|
|
431
|
|
432
|
// ================== Data & Submission Handling ================= //
|
433
|
|
434
|
function softwareTracker_submit(&$node) {
|
435
|
if(isset($node->publish_tracker_entry)){
|
436
|
$node->status = $node->publish_tracker_entry;
|
437
|
}
|
438
|
|
439
|
_softwareTracker_store_upload($node, 'screenshot');
|
440
|
_softwareTracker_store_upload($node, 'icon');
|
441
|
}
|
442
|
|
443
|
function _softwareTracker_files_dir(){
|
444
|
/** dir path must end with '/' **/
|
445
|
$dir_path = file_directory_path().'/softwareTracker/';
|
446
|
file_check_directory($dir_path, true);
|
447
|
return $dir_path;
|
448
|
}
|
449
|
|
450
|
|
451
|
/**
|
452
|
* //TODO 2 Strategies of dublicate handling:
|
453
|
* upload:
|
454
|
* - overwrite existing if for same node
|
455
|
* - rename newly uploaded if same name exists
|
456
|
* //TODO simplify messages
|
457
|
*
|
458
|
* @param unknown_type $node
|
459
|
* @param unknown_type $elementName
|
460
|
*/
|
461
|
function _softwareTracker_store_upload(&$node, $elementName){
|
462
|
|
463
|
/*
|
464
|
* File object :
|
465
|
* $file->filename original name of the file which was uploaded
|
466
|
* $file->filepath path to the temp file
|
467
|
* $file->source form element name
|
468
|
* $file->filemime the mimetype
|
469
|
* $file->filesize the size of the file
|
470
|
*/
|
471
|
$node_vars = (array)$node;
|
472
|
|
473
|
$key_file = $elementName.'_file';
|
474
|
$key_drop = $elementName.'_drop';
|
475
|
$key_in_store = $elementName.'_in_store';
|
476
|
|
477
|
if($node_vars[$key_drop]){
|
478
|
$imagepath = $node_vars[$key_in_store];
|
479
|
drupal_set_message('deleting: <pre style="font-size:90%">'.$key_file.' = '.$imagepath.'</pre>');
|
480
|
$sql_check = "SELECT COUNT(*) AS cnt FROM {software_tracker_node} WHERE ".$elementName." = '%s'";
|
481
|
$res = db_fetch_array(db_query($sql_check, $imagepath));
|
482
|
drupal_set_message($sql_check.' ; '.$imagepath.' : '.print_r($res, true) );
|
483
|
if($res['cnt'] < 2){ // only used in current page){ // only used in current page
|
484
|
// image in not used by another portfolio page, so it can be deleted
|
485
|
if(file_delete($imagepath)){
|
486
|
watchdog('content', 'deleted '.$imagepath, WATCHDOG_NOTICE);
|
487
|
} else {
|
488
|
watchdog('content', 'error deleting '.$imagepath, WATCHDOG_ERROR);
|
489
|
}
|
490
|
} else {
|
491
|
watchdog('content', 'not deleting <i>'. $imagepath . '</i> since it is still used in '.( $res['cnt'] ).' other pages', WATCHDOG_WARNING);
|
492
|
}
|
493
|
} else if ($image = file_check_upload($key_file)) {
|
494
|
drupal_set_message('uploading <pre style="font-size:90%">'.$key_file.' = '.print_r($image, true).'</pre>');
|
495
|
$basepath = _softwareTracker_files_dir();
|
496
|
if(file_exists($basepath.'/'.$image->filename)){
|
497
|
if(!file_delete($basepath.'/'.$image->filename)){
|
498
|
watchdog('content', 'error deleting '.$basepath.'/'.$image->filename, WATCHDOG_ERROR);
|
499
|
} else {
|
500
|
watchdog('content', 'deleted '.$basepath.'/'.$image->filename, WATCHDOG_ERROR);
|
501
|
}
|
502
|
} else {
|
503
|
watchdog('content', $basepath.'/'.$image->filename. ' not jet existing', WATCHDOG_NOTICE);
|
504
|
}
|
505
|
|
506
|
$uploaded_image = file_save_upload($key_file, $basepath, true);
|
507
|
|
508
|
$evalStr = "\$node->$key_file = \$uploaded_image ;";
|
509
|
eval($evalStr);
|
510
|
|
511
|
if($uploaded_image)
|
512
|
drupal_set_message('saving upload <i>'.$image->filename.'</i> to <i>'.$uploaded_image->filepath.'</i>');
|
513
|
else
|
514
|
drupal_set_message ('error uploading <i>'.$image->filename.'</i> to <i>'.$uploaded_image->filepath.'</i>', 'error');
|
515
|
}
|
516
|
}
|
517
|
|
518
|
function softwareTracker_load(&$node) {
|
519
|
$additions = db_fetch_object(db_query('SELECT * FROM {software_tracker_node} '.
|
520
|
'WHERE nid = %d', $node->nid));
|
521
|
|
522
|
// hide the default title for softwareTracker content
|
523
|
//$additions->title = '';
|
524
|
|
525
|
return $additions;
|
526
|
}
|
527
|
|
528
|
|
529
|
function softwareTracker_insert($node) {
|
530
|
global $user;
|
531
|
|
532
|
$sql = "INSERT INTO {software_tracker_node} (
|
533
|
nid, software_author, home_url, download_url,
|
534
|
version, license, price, screenshot, icon, characterization,
|
535
|
review, review_authors,
|
536
|
system_requirements, interface) ".
|
537
|
"VALUES (%d, '%s', '%s', '%s',
|
538
|
'%s', '%s', '%s', '%s', '%s', '%s',
|
539
|
'%s', '%s',
|
540
|
'%s', '%s')";
|
541
|
db_query($sql,
|
542
|
$node->nid, $node->software_author, $node->home_url, $node->download_url,
|
543
|
$node->version, $node->license, $node->price, $node->screenshot_file->filepath, $node->icon_file->filepath, $node->characterization,
|
544
|
$node->review, $user->uid,
|
545
|
$node->system_requirements, $node->interface
|
546
|
);
|
547
|
if($error = db_error()){
|
548
|
watchdog('content', 'Software Tracker Node - (nid: '.$node->nid.'):'.$error.'<pre>'.$sql.'</pre>', WATCHDOG_ERROR);
|
549
|
} else {
|
550
|
watchdog('content', 'Software Tracker Node - Inserted(nid: '.$node->nid.')', WATCHDOG_NOTICE);
|
551
|
}
|
552
|
|
553
|
}
|
554
|
|
555
|
|
556
|
function softwareTracker_update($node) {
|
557
|
global $user;
|
558
|
|
559
|
$auth_ids = split(',',$node->review_authors);
|
560
|
if(!array_search($user->uid, $auth_ids)){
|
561
|
$auth_ids[] = $user->uid;
|
562
|
}
|
563
|
$review_authors = implode(',', $auth_ids);
|
564
|
|
565
|
$sql = "UPDATE {software_tracker_node} SET
|
566
|
software_author='%s', home_url='%s', download_url='%s',
|
567
|
version='%s', license='%s', price='%s', characterization='%s',
|
568
|
review='%s', review_authors='%s',
|
569
|
system_requirements='%s', interface='%s', certified=%s";
|
570
|
$args = array(
|
571
|
$node->software_author, $node->home_url, $node->download_url,
|
572
|
$node->version, $node->license, $node->price, $node->characterization,
|
573
|
$node->review, $review_authors,
|
574
|
$node->system_requirements, $node->interface, $node->certified);
|
575
|
|
576
|
if( !empty($node->icon_file) || $node->icon_drop){
|
577
|
$sql .= ", icon='%s'";
|
578
|
$args[] = $node->icon_file->filepath;
|
579
|
}
|
580
|
if( !empty($node->screenshot_file) || $node->screenshot_drop){
|
581
|
$sql .= ", screenshot='%s'";
|
582
|
$args[] = $node->screenshot_file->filepath;
|
583
|
}
|
584
|
$sql .= " WHERE nid = %d";
|
585
|
$args[] = $node->nid;
|
586
|
|
587
|
db_query($sql, $args);
|
588
|
if($error = db_error()){
|
589
|
watchdog('content', 'Software Tracker Node - (nid: '.$node->nid.'):'.$error.'<pre>'.$sql.'</pre>', WATCHDOG_ERROR);
|
590
|
} else {
|
591
|
watchdog('content', 'Software Tracker Node - Updated (nid: '.$node->nid.')', WATCHDOG_NOTICE);
|
592
|
}
|
593
|
}
|
594
|
|
595
|
function softwareTracker_delete($node) {
|
596
|
db_query("DELETE FROM {software_tracker_node} WHERE nid = %d", $node->nid);
|
597
|
watchdog('content', 'Software Tracker Node - Deleted', WATCHDOG_NOTICE);
|
598
|
}
|
599
|
|
600
|
|
601
|
function _softwareTracker_init_session(){
|
602
|
$_SESSION['softwareTracker'] = array('type'=>false, 'domain'=>false);
|
603
|
}
|
604
|
/**
|
605
|
* gets the softwareTracker related session array and retuns it by reference
|
606
|
*
|
607
|
* @return array by reference
|
608
|
*/
|
609
|
function & _softwareTracker_get_session(){
|
610
|
if(!isset($_SESSION['softwareTracker'])){
|
611
|
_softwareTracker_init_session();
|
612
|
}
|
613
|
return $_SESSION['softwareTracker'];
|
614
|
}
|
615
|
|
616
|
function _softwareTracker_set_session(&$vals){
|
617
|
if(!isset($_SESSION['softwareTracker'])){
|
618
|
_softwareTracker_init_session();
|
619
|
}
|
620
|
return $_SESSION['softwareTracker'] = $vals;
|
621
|
}
|
622
|
|
623
|
function _softwareTracker_set_search_params($list_mode, $vocab, $tid = false){
|
624
|
|
625
|
// array of session values by reference
|
626
|
$sessvals = _softwareTracker_get_session();
|
627
|
$sessvals['mode'] = $list_mode;
|
628
|
if($vocab){
|
629
|
$sessvals[$vocab] = ($tid == 'all' ? false : array($tid));
|
630
|
_softwareTracker_set_session($sessvals);
|
631
|
}
|
632
|
}
|
633
|
|
634
|
function softwareTracker_search($mode, $vtids, $days = false){
|
635
|
global $user;
|
636
|
|
637
|
// --- prepare array of comma sperated termID strings to be used in sql IN (1,2,3) statements
|
638
|
$tid_strings = array();
|
639
|
|
640
|
foreach(array_keys($vtids) as $vid){
|
641
|
if($vtids[$vid] && is_array($vtids[$vid])){
|
642
|
$terms = $vtids[$vid];
|
643
|
} else {
|
644
|
$term_instances = taxonomy_get_tree($vid);
|
645
|
$terms = array();
|
646
|
foreach($term_instances as $t){
|
647
|
$terms[] = $t->tid;
|
648
|
}
|
649
|
}
|
650
|
$tid_str = '';
|
651
|
foreach($terms as $t){
|
652
|
$tid_str .= (strlen($tid_str) > 0?',':'').$t;
|
653
|
}
|
654
|
$tid_strings[] = $tid_str;
|
655
|
}
|
656
|
|
657
|
// --- build inner select
|
658
|
$sql_where = '';
|
659
|
$cnt = 0;
|
660
|
while($tid_str = array_pop($tid_strings)){
|
661
|
$is_last_token = count($tid_strings) == 0;
|
662
|
if($is_last_token){
|
663
|
$sql_where_tmp = " tid IN (".$tid_str.")";
|
664
|
} else {
|
665
|
$sql_where_tmp = "SELECT nid from {term_node} WHERE tid IN (".$tid_str.")";
|
666
|
}
|
667
|
if($cnt == 0){
|
668
|
$sql_where = $sql_where_tmp;
|
669
|
} else {
|
670
|
$sql_where = $sql_where_tmp.' AND tn.nid IN('.$sql_where.')';
|
671
|
}
|
672
|
++$cnt;
|
673
|
}
|
674
|
|
675
|
switch($mode){
|
676
|
case 'all':
|
677
|
break;
|
678
|
case 'own':
|
679
|
$sql_where = ' n.uid='.$user->uid.' AND '.$sql_where;
|
680
|
break;
|
681
|
case 'unpublished':
|
682
|
$sql_where = ' n.status=0 AND '.$sql_where;
|
683
|
}
|
684
|
|
685
|
$sql_orderby = 'n.title'; // n.title, n.changed, n.created
|
686
|
|
687
|
if($days){
|
688
|
$oneDay = 60 * 60 * 24;
|
689
|
$now = time();
|
690
|
$sql_where .= ' AND '.$now.' - n.changed < '.($oneDay * $days);
|
691
|
}
|
692
|
|
693
|
$sql = 'SELECT n.* from {term_node} AS tn inner join {node} as n on n.nid = tn.nid
|
694
|
WHERE 1=1 AND '.$sql_where.' GROUP BY nid ORDER BY '.$sql_orderby;
|
695
|
//drupal_set_message(db_prefix_tables($sql));
|
696
|
$res = db_query($sql);
|
697
|
$nodes = array();
|
698
|
while(db_num_rows($res) > 0 && $row = db_fetch_array($res)) {
|
699
|
$node = node_load($row['nid']);
|
700
|
$nodes[] = $node;
|
701
|
}
|
702
|
/* drupal_set_message($sql);
|
703
|
$res = db_query($sql);
|
704
|
while (db_num_rows($res) > 0 && $node = db_fetch_object($res)) {
|
705
|
$nodes[] = $node;
|
706
|
}
|
707
|
*/
|
708
|
|
709
|
return $nodes;
|
710
|
}
|
711
|
|
712
|
|
713
|
// ====================== Output Generation ====================== //
|
714
|
|
715
|
/*
|
716
|
* @param a3
|
717
|
* For "view", passes in the $teaser parameter from node_view().
|
718
|
* For "validate", passes in the $form parameter from node_validate().
|
719
|
|
720
|
* @param a4
|
721
|
* For "view", passes in the $page parameter from node_view().
|
722
|
*
|
723
|
* @return This varies depending on the operation.
|
724
|
* The "submit", "insert", "update", "delete", "print' and "view" operations have no return value.
|
725
|
* The "load" operation should return an array containing pairs of fields => values to be merged into the node object.
|
726
|
*/
|
727
|
|
728
|
/*
|
729
|
function softwareTracker_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
|
730
|
drupal_set_message('nodeapi op='.$op.' node->title:'.$node->title);
|
731
|
switch($op){
|
732
|
case 'load':
|
733
|
$node->title = 'Search Results';
|
734
|
return array('title'=>'Search Results');
|
735
|
|
736
|
break;
|
737
|
case 'view':
|
738
|
$node->title = 'Search Results';
|
739
|
$teaserForm = $a3;
|
740
|
form_set_value($teaserForm['title'], 'Search Results');
|
741
|
$pageForm = $a4;
|
742
|
form_set_value($pageForm['title'], 'Search Results');
|
743
|
drupal_set_message('nodeapi #2');
|
744
|
break;
|
745
|
|
746
|
}
|
747
|
}
|
748
|
*/
|
749
|
|
750
|
function softwareTracker_uids_to_names($uidsStr){
|
751
|
$uids = explode(',', $uidsStr);
|
752
|
$user_str = '';
|
753
|
$sepatator = '; ';
|
754
|
$sep = '';
|
755
|
foreach($uids as $uid){
|
756
|
if(strlen($user_str) > 0){
|
757
|
$sep = $sepatator; }
|
758
|
$user = user_load(array('uid'=>$uid));
|
759
|
if($user){
|
760
|
$user_str .= $sep.$user->name;
|
761
|
} else {
|
762
|
$user_str .= $sep.'missing user: ['.$uid.']';
|
763
|
}
|
764
|
}
|
765
|
return $user_str;
|
766
|
}
|
767
|
|
768
|
function softwareTracker_block($op = 'list', $delta = 'domain', $edit = array()) {
|
769
|
if ($op == 'list') {
|
770
|
/*
|
771
|
$blocks['type'] =
|
772
|
array('info' => t('Software Type Preselection (Lists terms of the software type vocabulary)'),
|
773
|
/ *'weight' => 0, 'enabled' => 1, 'region' => 'left'* /);
|
774
|
$blocks['domain'] =
|
775
|
array('info' => t('Software Domain Preselection (Lists terms of the software domain vocabulary)'),
|
776
|
/ *'weight' => 1, 'enabled' => 1, 'region' => 'left'* /);
|
777
|
*
|
778
|
*/
|
779
|
$blocks[0] = array('info' => t('Software Tracker Search Box'));
|
780
|
return $blocks;
|
781
|
}
|
782
|
else if ($op == 'view') {
|
783
|
$content = _softwareTracker_block_content('type');
|
784
|
$content .= "<br/>";
|
785
|
$content .= _softwareTracker_block_content('domain');
|
786
|
} else {
|
787
|
$content .= 'ERROR: software tracker '.$delta.' vocabulary not properly setup please edit the '.l('settings', 'admin/settings/softwareTracker');
|
788
|
}
|
789
|
$block = array(
|
790
|
'subject' => 'Browse Software',
|
791
|
'content' => $content);
|
792
|
|
793
|
return $block;
|
794
|
}
|
795
|
|
796
|
|
797
|
function _softwareTracker_block_content($delta){
|
798
|
|
799
|
$content = '';
|
800
|
switch($delta) {
|
801
|
case 'type':
|
802
|
$vid = variable_get('softwareTracker_vocab_type', 'none');
|
803
|
$default_option = t('All Types');
|
804
|
break;
|
805
|
case 'domain':
|
806
|
$vid = variable_get('softwareTracker_vocab_domain', 'none');
|
807
|
$default_option = t('All Categories');
|
808
|
break;
|
809
|
}
|
810
|
if($vid !== 'none'){
|
811
|
$terms = taxonomy_get_tree($vid);
|
812
|
$sessvals = _softwareTracker_get_session();
|
813
|
if(isset($sessvals[$delta])){
|
814
|
$vocvals = $sessvals[$delta];
|
815
|
} else {
|
816
|
$vocvals = false;
|
817
|
}
|
818
|
|
819
|
$sessvals = _softwareTracker_get_session();
|
820
|
//drupal_set_message('<pre>'.print_r($sessvals, true).'<pre>');
|
821
|
$list_mode = (isset($sessvals['mode']) ? $sessvals['mode'] : 'all');
|
822
|
|
823
|
//$content .= '<pre style="font-size:80%">'.print_r($terms, true).'</pre>';
|
824
|
$content .= '<ul class="softwareTracker">'.chr(10);
|
825
|
$content .= '<li class="default'.($vocvals === false?' active':'').'">'
|
826
|
.l('<span>'.$default_option.'</span>',
|
827
|
'softwareTracker/list/'.$list_mode.'/'.$delta.'/all', array(), null, null, false, true)
|
828
|
.'</li>'.chr(10);
|
829
|
|
830
|
|
831
|
foreach($terms as $t){
|
832
|
$is_active = $vocvals && in_array($t->tid, $vocvals);
|
833
|
|
834
|
$content .= '<li '.($is_active? 'class="active"':'').'>'
|
835
|
.l('<span>'.$t->name.'</span>',
|
836
|
'softwareTracker/list/'.$list_mode.'/'.$delta.'/'.$t->tid, array(), null, null, false, true)
|
837
|
.'</li>'.chr(10);
|
838
|
}
|
839
|
|
840
|
$content .= "</ul>\n";
|
841
|
|
842
|
}
|
843
|
return $content;
|
844
|
}
|
845
|
|
846
|
function _softwareTracker_version_title(&$node){
|
847
|
$version = trim(strtolower($node->version));
|
848
|
if($version){
|
849
|
$version = str_replace('version', '', $version);
|
850
|
$version = str_replace('v.', '', $version);
|
851
|
$version = str_replace('v', '', $version);
|
852
|
$version = t('v').$version;
|
853
|
}
|
854
|
return $node->title.' '.$version;
|
855
|
}
|
856
|
|
857
|
function _softwareTracker_module_image($filename){
|
858
|
|
859
|
$source = base_path().drupal_get_path('module', 'softwareTracker').'/images/'.$filename;
|
860
|
return $source;
|
861
|
}
|
862
|
|
863
|
|
864
|
function softwareTracker_view(&$node, $teaser = FALSE, $page = FALSE) {
|
865
|
|
866
|
$node = node_prepare($node, $teaser);
|
867
|
if($teaser){
|
868
|
|
869
|
$node->content['softwareTracker_teaser'] = array(
|
870
|
'#value' => theme('softwareTracker_teaser', $node),
|
871
|
'#weight' => 1
|
872
|
);
|
873
|
|
874
|
} else {
|
875
|
|
876
|
$node->content['softwareTracker_page'] = array(
|
877
|
'#value' => theme('softwareTracker_page', $node),
|
878
|
'#weight' => 1
|
879
|
);
|
880
|
}
|
881
|
return $node;
|
882
|
}
|
883
|
|
884
|
function theme_softwareTracker_teaser($node){
|
885
|
/**
|
886
|
* $node->nid,
|
887
|
* $node->title, $node->software_author, $node->home_url, $node->download_url,
|
888
|
* $node->lastReviewed,
|
889
|
* $node->version, $node->licence, $node->price, $node->screenshot->filepath,
|
890
|
* $node->icon->filepath, $node->characterization,
|
891
|
* $node->review, $node->review_authors,
|
892
|
* $node->system_requirements, $node->interface
|
893
|
*/
|
894
|
$modulePath = drupal_get_path('module','softwareTracker'); //cache this value somewhere
|
895
|
|
896
|
$out = '<div class="'.($node->status?'':'node-unpublished').'">';
|
897
|
$out .= '<h2 class="software_title">'.($node->icon ? '<img class="icon" src="'.base_path().$node->icon.'"/>': '').l(_softwareTracker_version_title($node), 'node/'.$node->nid);
|
898
|
if($node->certified == 1){
|
899
|
$out .= ' <img src="'._softwareTracker_module_image('EDIT_icon.gif').'" class="certification" alt="software is certified by EDIT" title="software is certified by EDIT" />'.chr(10);
|
900
|
|
901
|
}
|
902
|
$out .= ' <span class="reviewed_when">'.format_date($node->changed).'</span></h2>'.chr(10);
|
903
|
|
904
|
$out .= '<p>'.$node->characterization.'</p>'.chr(10).'</div>'.chr(10);
|
905
|
return $out;
|
906
|
}
|
907
|
|
908
|
|
909
|
function theme_softwareTracker_page($node){
|
910
|
/**
|
911
|
* $node->nid,
|
912
|
* $node->title, $node->software_author, $node->home_url, $node->download_url,
|
913
|
* $node->lastReviewed,
|
914
|
* $node->version, $node->licence, $node->price, $node->screenshot->filepath,
|
915
|
* $node->icon->filepath, $node->characterization,
|
916
|
* $node->system_requirements, $node->interface
|
917
|
*/
|
918
|
|
919
|
// 1.) alter breadcrumbs
|
920
|
|
921
|
$breadcrumbs = array('softwareTracker');
|
922
|
if($node->characterization) $breadcrumbs[] = l(t('Description'), $_GET['q'], array(), null, 'description');
|
923
|
if($node->review) $breadcrumbs[] = l(t('Review'), $_GET['q'], array(), null, 'review');
|
924
|
if($node->system_requirements) $breadcrumbs[] = l(t('System Requirements'), $_GET['q'], array(), null, 'requirements');
|
925
|
if($node->interface) $breadcrumbs[] = l(t('Interfaces & Data Standarts'), $_GET['q'], array(), null, 'interface');
|
926
|
$breadcrumbs[] = l('Comments', $_GET['q'], array(), null, 'comments');
|
927
|
drupal_set_breadcrumb($breadcrumbs);
|
928
|
|
929
|
// 2.) render node content
|
930
|
$out = '<!-- BEGIN theme_softwareTracker_page() -->'
|
931
|
.chr(10)
|
932
|
.'<h2 class="software_title">'.($node->icon ? '<img class="icon" src="'.base_path().$node->icon.'"/>': '').l(_softwareTracker_version_title($node), 'node/'.$node->nid);
|
933
|
if($node->certified == 1){
|
934
|
$out .= ' <img src="'._softwareTracker_module_image('EDIT_icon.gif').'" class="certification" alt="software is certified by EDIT" title="software is certified by EDIT" />'.chr(10);
|
935
|
|
936
|
}
|
937
|
$out .= ' <span class="reviewed_when" title="Date of last change">'.format_date($node->changed).'<span></h2>'.chr(10);
|
938
|
|
939
|
|
940
|
$out .= '<table class="softwareTracker">'.chr(10);
|
941
|
$out .= '<tr><td>'.t('Author').':</td><td>'.$node->software_author.'</td></tr>'.chr(10);
|
942
|
$out .= '<tr><td>'.t('Version').':</td><td>'.$node->version.'</td></tr>'.chr(10);
|
943
|
$out .= '<tr><td>'.t('Home').':</td><td><a href="'.$node->home_url.'" target="_blank">'.$node->home_url.'</a></td></tr>'.chr(10);
|
944
|
$out .= '<tr><td>'.t('Licence').':</td><td>'.$node->license.'</td></tr>'.chr(10);
|
945
|
$out .= '<tr><td>'.t('Price').':</td><td>'.$node->price.'</td></tr>'.chr(10);
|
946
|
$out .= '<tr><td>'.t('Download').':</td><td><a href="'.$node->download_url.'" target="_blank">'.$node->download_url.'</a></td></tr>'.chr(10);
|
947
|
$out .= '</table>'.chr(10);
|
948
|
|
949
|
if($node->characterization){
|
950
|
$out .= '<a name="description" /></a><h2>'.t('Description').'</h2>'.chr(10);
|
951
|
$out .= '<p>'.$node->characterization.'</p>'.chr(10);
|
952
|
}
|
953
|
if($node->review || $node->review_authors){
|
954
|
$out .= '<a name="review" /></a><h2>'.t('Review').'</h2>'.chr(10);
|
955
|
if($node->review_authors){
|
956
|
$out .= '<div class="review_authors">Edited by '.softwareTracker_uids_to_names($node->review_authors).'</div>';
|
957
|
}
|
958
|
$out .= '<p>'.( $node->review ? $node->review : t('--- No Review --')).'</p>'.chr(10);
|
959
|
}
|
960
|
if($node->system_requirements){
|
961
|
$out .= '<a name="requirements"></a><h2>'.t('System Requirements').'</h2>'.chr(10);
|
962
|
$out .= '<p>'.$node->system_requirements.'</p>'.chr(10);
|
963
|
}
|
964
|
if($node->interface){
|
965
|
$out .= '<a name="interface" /></a><h2>'.t('Interfaces & Data Standarts').'</h2>'.chr(10);
|
966
|
$out .= '<p>'.$node->interface.'</p>'.chr(10);
|
967
|
}
|
968
|
|
969
|
if($node->screenshot){
|
970
|
$out .= '<img id="screenshot" src="'.base_path().$node->screenshot.'"/>';
|
971
|
}
|
972
|
$out .= '<table>'.chr(10);
|
973
|
$out .= '<tr><td>'.t('Created').':</td><td>'.format_date($node->created).'</td></tr>'.chr(10);
|
974
|
$out .= '<tr><td>'.t('Last Reviewed').':</td><td>'.format_date($node->changed).'</td></tr>'.chr(10);
|
975
|
$out .= '</table>'.chr(10);
|
976
|
$out .= '<a name="comment" />'.chr(10).'<!-- END theme_softwareTracker_page() -->';
|
977
|
return $out;
|
978
|
}
|
979
|
|
980
|
|
981
|
function _page_tite($typeIds, $domainIds){
|
982
|
$title = '';
|
983
|
if($typeIds){
|
984
|
$term = taxonomy_get_term($typeIds[0]);
|
985
|
$title = $term->name.' & ';
|
986
|
} else {
|
987
|
$title = t('All Types').' & ';
|
988
|
}
|
989
|
if($domainIds){
|
990
|
$term = taxonomy_get_term($domainIds[0]);
|
991
|
$title .= $term->name;
|
992
|
} else {
|
993
|
$title .= t('All Categories');
|
994
|
}
|
995
|
return $title;
|
996
|
}
|
997
|
/**
|
998
|
* @param string $list_mode of 'all', 'own', 'unpublished'
|
999
|
* @param string $op 'tadd' or 'tdel'
|
1000
|
* @param string $vocab
|
1001
|
* @param int $tid termid
|
1002
|
*/
|
1003
|
function softwareTracker_filtered_list($list_mode, $vocab= false, $tid = false){
|
1004
|
|
1005
|
//drupal_set_message('$list_mode:'.$list_mode.', $op:'.$op.', $vocab:'.$vocab.', $tid:'.$tid);
|
1006
|
|
1007
|
_softwareTracker_set_search_params($list_mode, $vocab, $tid);
|
1008
|
$sessvals = _softwareTracker_get_session();
|
1009
|
|
1010
|
//drupal_set_message('<pre>'.print_r(_softwareTracker_get_session(), true).'<pre>');
|
1011
|
|
1012
|
drupal_set_title(_page_tite($sessvals['type'], $sessvals['domain']));
|
1013
|
|
1014
|
$out = '';
|
1015
|
|
1016
|
$type_vid = variable_get('softwareTracker_vocab_type', false);
|
1017
|
$domain_vid = variable_get('softwareTracker_vocab_domain', false);
|
1018
|
|
1019
|
if($type_vid && $domain_vid){
|
1020
|
$nodes = softwareTracker_search($list_mode, array($type_vid=>$sessvals['type'], $domain_vid=>$sessvals['domain']));
|
1021
|
$out .= theme('softwareTracker_list', $nodes);
|
1022
|
} else {
|
1023
|
drupal_set_message('vocabularies not properly setup, please edit the '.l('settings', 'admin/settings/softwareTracker'), 'error');
|
1024
|
}
|
1025
|
|
1026
|
// add rss feed to this page
|
1027
|
$typeIds = ($sessvals['type'] ? join(',', $sessvals['type']) : 'all');
|
1028
|
$domainIds = ($sessvals['domain'] ? join(',', $sessvals['domain']) : 'all');
|
1029
|
drupal_add_feed(url('softwareTracker/feed/'.$typeIds.'/'.$domainIds), 'RSS - '. $title);
|
1030
|
//$out = $vocab.', '.$tid.', '.$op.'<br>'.print_r($sessvals, true).$out;
|
1031
|
return $out;
|
1032
|
}
|
1033
|
|
1034
|
/**
|
1035
|
*
|
1036
|
*/
|
1037
|
function softwareTracker_feed($typeId_str = 'all', $domainId_str = 'all', $days = 7){
|
1038
|
|
1039
|
if($typeId_str == 'all'){
|
1040
|
$typeIds = false;
|
1041
|
} else {
|
1042
|
$typeIds = explode(',', $typeId_str);
|
1043
|
}
|
1044
|
if($typeId_str == 'all'){
|
1045
|
$domainIds = false;
|
1046
|
} else {
|
1047
|
$domainIds = explode(',', $domainId_str);
|
1048
|
}
|
1049
|
|
1050
|
$title = _page_tite($typeIds, $domainIds);
|
1051
|
|
1052
|
$type_vid = variable_get('softwareTracker_vocab_type', false);
|
1053
|
$domain_vid = variable_get('softwareTracker_vocab_domain', false);
|
1054
|
|
1055
|
$now = getdate();
|
1056
|
|
1057
|
$channel = array(
|
1058
|
'version' => '2.0',
|
1059
|
'title' => variable_get('site_name', 'Drupal - SoftwareTracker'),
|
1060
|
'link' => url('softwareTracker/feed/'. $typeId_str .'/'. $domainId_str, NULL, NULL, TRUE),
|
1061
|
'description' => 'Changes in '._page_tite($typeIds, $domainIds).' of the last '.$days.' days.',
|
1062
|
'language' => ($locale ? $locale : 'en')
|
1063
|
);
|
1064
|
|
1065
|
$nodes = softwareTracker_search($list_mode, array($type_vid=>$typeIds, $domain_vid=>$domainIds), $days);
|
1066
|
|
1067
|
$items = '';
|
1068
|
foreach($nodes AS $node){
|
1069
|
$link = url("node/$node->nid", NULL, NULL, 1);
|
1070
|
$items .= format_rss_item($node->title, $link, $node->characterization);
|
1071
|
}
|
1072
|
|
1073
|
$output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
1074
|
$output .= "<rss version=\"". $channel["version"] ."\" xml:base=\"". $base_url ."\" ". implode(' ', $namespaces) .">\n";
|
1075
|
$output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
|
1076
|
$output .= "</rss>\n";
|
1077
|
|
1078
|
drupal_set_header('Content-Type: application/rss+xml; charset=utf-8');
|
1079
|
print $output;
|
1080
|
}
|
1081
|
|
1082
|
|
1083
|
|
1084
|
|
1085
|
|
1086
|
function theme_softwareTracker_list($nodes){
|
1087
|
$out = '';
|
1088
|
$entryCnt = 0;
|
1089
|
if(count($nodes) > 0){
|
1090
|
$out .= '<ol>'.chr(10);
|
1091
|
foreach($nodes as $node){
|
1092
|
if(softwareTracker_access('view', $node)){
|
1093
|
$entryCnt++;
|
1094
|
$out .= '<li>'.theme('softwareTracker_teaser', $node).'</li>'.chr(10);
|
1095
|
}
|
1096
|
}
|
1097
|
$out .= '<ol>'.chr(10);
|
1098
|
}
|
1099
|
if($entryCnt == 0){
|
1100
|
$out .= '<h3>'.t('No entries in this section.').'</h2>'.chr(10);
|
1101
|
}
|
1102
|
return $out;
|
1103
|
}
|
1104
|
|
1105
|
|
1106
|
/* ###############################################################
|
1107
|
* TODO put code below in separate module ?
|
1108
|
* ############################################################### */
|
1109
|
|