Project

General

Profile

Download (37.8 KB) Statistics
| Branch: | Tag: | Revision:
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 .= '&nbsp<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 .= '&nbsp<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

    
(6-6/7)