forena.admin.inc 74.1 KB
Newer Older
1
<?php
metzlerd's avatar
metzlerd committed
2
// $Id$
metzlerd's avatar
metzlerd committed
3
4
/**
 * @file
metzlerd's avatar
metzlerd committed
5
 * Report administration forms and functions.
metzlerd's avatar
metzlerd committed
6
 */
metzlerd's avatar
metzlerd committed
7
require_once('forena.common.inc');
8

9
10
11
12
13
/**
 * Display reports to edit for admins in the structure menu
 * Enter description here ...
 */
function forena_admin_reports() {
14
  GLOBAL $language;
15
  $data = array();
16
  $links[] = array('href' => 'reports/add', 'title' => 'Create New Report' );
17
  $content = drupal_get_form('forena_sync_form');
18
19
  $output = drupal_render($content);
  $output .= theme('links',
20
21
22
23
    array(
      'links' => $links,
      'attributes' => array('class' => 'action-links'),
    )
metzlerd's avatar
metzlerd committed
24
  );
25
  // Add Data tables if it exists.
26

27
28
29
30
31
  drupal_add_css(drupal_get_path('module', 'forena') . '/forena.css');
  if (file_exists('sites/all/libraries/dataTables/media/js/jquery.dataTables.min.js')) {
    drupal_add_js(drupal_get_path('module', 'forena') . '/forena.admin.js');
    drupal_add_js('sites/all/libraries/dataTables/media/js/jquery.dataTables.min.js');
  }
32
33
  $headers = array(t('category'), t('title'), t('name'), t('operation'));
  $result = Frx::File()->allReports();
34
  foreach ($result as $row) {
35
    $rpt = str_replace('/', '.', $row->name);
metzlerd's avatar
metzlerd committed
36
37
38
    $edit = l(t('Edit'), 'reports/' . $rpt . '/edit');
    $clone = l(t('Clone'), 'reports/add/' . $rpt);
    $delete = l(t('Delete'), 'reports/' . $rpt . '/delete', array('query' => array('destination' => 'admin/structure/reports')));
39
40
    $title = l(t($row->cache['title']), 'reports/' . $rpt);
    $data[] = array($row->cache['category'], $title, $row->name, $edit . ' ' . $clone . ' ' . $delete);
41
  }
42
  $output .= '<div id="forena-reports-list">';
43
  $output .= theme_table(array('header' => $headers, 'rows' => $data, 'attributes' => array('class' => array( 'dataTable-paged')), 'caption' => '', 'sticky' => TRUE, 'colgroups' => array(), 'empty' => ''));
44
  $output .= '</div>';
45
46
47
  return $output;
}

48
/**
metzlerd's avatar
metzlerd committed
49
 * Remove the report from the database and file system.
50
51
 * @param string $report_name
 */
metzlerd's avatar
metzlerd committed
52
function forena_delete_report($report_name, $delete_file = TRUE) {
53
  $report_path = forena_report_path();
54
55
56
  $language = 'en';


metzlerd's avatar
metzlerd committed
57
  $filepath = $report_path . '/' . $report_name . '.frx';
58
59
  $info = Frx::File()->pathinfo($filepath);
  $do = Frx::File()->delete($filepath);
60
  if (module_exists('locale')) {
61
    @list($tlang, $tname) = explode('/', $report_name, 2);
62
    if (array_key_exists($tlang, language_list())) {
63
64
      $report_name = $tname;
      $language = $tlang;
65
66
    }
  }
metzlerd's avatar
metzlerd committed
67
  if ($do) {
68
    db_delete('forena_reports')
metzlerd's avatar
metzlerd committed
69
70
71
    ->condition('report_name', $report_name)
    ->condition('language', $language)
    ->execute();
metzlerd's avatar
metzlerd committed
72
73
  }
  else {
metzlerd's avatar
metzlerd committed
74
    drupal_set_message(t('Unable to delete file %s', array('%s' => $info['basename'])), 'error');
75
76
77
  }
}

metzlerd's avatar
metzlerd committed
78

79
80


81
function forena_filter_element($fmt, $name) {
metzlerd's avatar
metzlerd committed
82
83
84
85
  global $user;
  $element['format'] =  array(
    '#type' => 'fieldset',
    '#collapsible' => TRUE,
86
    '#collapsed' => $fmt!='',
metzlerd's avatar
metzlerd committed
87
88
    '#title' => t('Input formats'),
  );
89
  if (!$fmt) $fmt='full_html';
metzlerd's avatar
metzlerd committed
90
  // Get a list of formats that the current user has access to.
metzlerd's avatar
metzlerd committed
91
92
93
94
95
  $formats = filter_formats($user);
  foreach ($formats as $format) {
    $options[$format->format] = $format->name;
    $element['format']['guidelines'][$format->format] = array(
      '#theme' => 'filter_guidelines',
96
      '#required' => TRUE,
metzlerd's avatar
metzlerd committed
97
98
99
100
101
      '#format' => $format,
    );
  }
  $element['format']['guidelines']['#weight']=12;

102
  $element['format'][$name] = array(
metzlerd's avatar
metzlerd committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
    '#type' => 'select',
    '#title' => t('Text format'),
    '#options' => $options,
    '#default_value' => $fmt,
    '#access' => count($formats) > 1,
    '#weight' => 10,
    '#attributes' => array('class' => array('filter-list')),
  );

  $element['format']['help'] = array(
    '#type' => 'container',
    '#theme' => 'filter_tips_more_info',
    '#attributes' => array('class' => array('filter-help')),
    '#weight' => 11,
  );
metzlerd's avatar
metzlerd committed
118
  return $element['format'];
metzlerd's avatar
metzlerd committed
119
}
120

metzlerd's avatar
metzlerd committed
121
122


123
/**
124
125
126
 * Report syncronization form
 * @param $formid
 * @param $form_state
127
 */
128
function forena_sync_form($formid, &$form_state) {
129
130
131
132
133
134
135

  $form['sync_overwrite'] = array(
    '#type' => 'checkbox',
    '#title' => t('Revert all delivered reports to orignial'),
    '#description' => t('All customizations to module delivered reports will be lost.')
  );

136
137
138
139
140
  $form['sync'] = array(
    '#type' => 'submit',
    '#value' => t('Clear Cache'),
    '#submit' => array('forena_settings_sync_submit'),
  );
141
142

  return $form;
143
144
145
146
147
148
149
150

}

/**
 * Forena admin settings form
 *
 */
function forena_settings() {
151
  $skins = variable_get('forena_skins', array());
152
153
154

  $report_path = forena_report_path();

155

156
157
158
  $form['forena_report_repos'] = array(
    '#type' => 'textfield',
    '#title' => t('Report Repository'),
metzlerd's avatar
metzlerd committed
159
160
161
162
163
164
    '#description' => t('Indicate the directory that you want to use for your reports.  In order for you to ' .
                        'to be able to save reports, this directory should be writable by the web user. Relative' .
                        'paths should be entered relative to the base path of your drupal installation.'),
    '#default_value' => $report_path,
  );

165
166
167
  $form['forena_last_report_path'] = array(
    '#type' => 'value',
    '#value' => forena_report_path(),
metzlerd's avatar
metzlerd committed
168
169
  );

170

171
  $form['forena_input_format'] = forena_filter_element(variable_get('forena_input_format', filter_default_format()), 'forena_input_format');
172
  $form['forena_default_form'] = array(
173
    '#type' => 'select',
174
    '#title' => t('Default report skin'),
175
    '#options' => $skins,
176
    '#description' => t('Specify the default skin to be used.   New skins can be created by creating .skinfo files in your reports directory.'
metzlerd's avatar
metzlerd committed
177
    . ' Skins are basically css and javascript libraries added to your report.'),
metzlerd's avatar
metzlerd committed
178
    '#default_value' => variable_get('forena_default_form', ''),
metzlerd's avatar
metzlerd committed
179
    );
metzlerd's avatar
metzlerd committed
180

metzlerd's avatar
metzlerd committed
181
182
183
    $form =  system_settings_form($form);
    $form['#submit'][] = 'forena_settings_submit';
    return $form;
metzlerd's avatar
metzlerd committed
184

185
186
}
/**
187
 * Added submit handler to create directories and clear menu cache
188
189
190
191
 *
 * @param unknown_type $form
 * @param unknown_type $form_state
 */
metzlerd's avatar
metzlerd committed
192
193
function forena_settings_submit($form, &$form_state) {
  $values = $form_state['values'];
194
  $path = $values['forena_report_repos'];
metzlerd's avatar
metzlerd committed
195
  $src_dir = drupal_get_path('module', 'forena') . '/repos/reports';
196
  if ($path != $values['forena_last_report_path']) {
197
198
    if (!file_exists($path)) {
      try {
199

200
201
202
203
        if (file_exists($path)) {
          drupal_set_message(t('Created directory %s', array($path))) ;
        }
        mkdir($path);
204

205
206
207
208
209
      } catch (Exception $e) {
        forena_error(t('Unable to create report directory'), $e->getMessage());
        return;
      }
    }
metzlerd's avatar
metzlerd committed
210
  }
211
212
  forena_sync_reports();
}
metzlerd's avatar
metzlerd committed
213

214
function forena_settings_sync_submit($form, &$form_state) {
215
  forena_sync_reports($form_state['values']['sync_overwrite']);
216
  drupal_set_message(t('Report cache cleared'));
217
}
218

219
function forena_format_form($formid, $form_state, $report_name) {
metzlerd's avatar
metzlerd committed
220
  $desc = Frx::Menu()->parseURL($report_name);
221
  $name = $desc['name'];
222

223
224
225
  $filename = $desc['filename'];
  $format = isset($desc['format']) ? $desc['format'] : '';
  if ($desc['exists']) {
226
    $r = Frx::Editor($name);
227
228
229
230
231
    drupal_set_title($r->title);
    $form = array();
    $frx_options = $r->getOptions();
    $report_form = @$frx_options['form'];

232
    $doclist = Frx::Menu()->doc_formats;
233
234
    $skins[''] = t('Use Default');
    $skins = array_merge(variable_get('forena_skins', array()), $skins);
235

metzlerd's avatar
metzlerd committed
236
237
238
239
    $form['report_name'] = array(
       '#type' => 'value',
       '#value' => $name,
    );
240

metzlerd's avatar
metzlerd committed
241
    $form['form'] = array(
242
      '#type' => 'select',
243
      '#title' => t('Skin'),
244
      '#options' => $skins,
metzlerd's avatar
metzlerd committed
245
      '#default_value' => $report_form,
metzlerd's avatar
metzlerd committed
246
      '#description' => t('The page style of your report.  The {skin}.skinfo file specifies css and js file in your report.')
metzlerd's avatar
metzlerd committed
247
    );
248

metzlerd's avatar
metzlerd committed
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    //begin checking doc generation options
    if ($r) $nodes = $r->simplexml->head->xpath('frx:docgen/frx:doc');
    if ($doclist) {
      $form['docgen'] = array(
       '#tree' => TRUE,
       '#type' => 'fieldset',
       '#title' => t('Document Options'),
       '#description' => t('These are document transformation options. Options selected will display as links in your report view.')
      );

      //build the options and default list
      $options = array();
      $default = array();
      foreach ($doclist as $value) {
        $options[$value] = strtoupper($value);
        $doc =  isset($r) ? $r->simplexml->head->xpath('frx:docgen/frx:doc[@type="' . $value . '"]') : '';
metzlerd's avatar
metzlerd committed
265
        if ($doc && array_search($value, $doclist)!==FALSE) {
metzlerd's avatar
metzlerd committed
266
          $default[$value] = $value;
267
        }
metzlerd's avatar
metzlerd committed
268
      }
269

metzlerd's avatar
metzlerd committed
270
271
272
273
274
275
276
      //display checkboxes
      $form['docgen']['docs'] = array(
        '#type' => 'checkboxes',
        '#description' => t('If no options are selected, the system will display all of the above as available for this report.'),
        '#options' => $options,
        '#default_value' => $default
      );
277

278
279
280
281
282
      $form['update'] = array(
        '#type' => 'submit',
        '#value' => 'Update',
      );

metzlerd's avatar
metzlerd committed
283
284
285
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Save',
286
        '#submit' => array('forena_format_form_submit', 'forena_save_submit'),
metzlerd's avatar
metzlerd committed
287
      );
288
289
290
291
292

      $form['cancel'] = array(
        '#type' => 'submit',
        '#value' => 'Cancel',
        '#submit' => array('forena_save_cancel'),
metzlerd's avatar
metzlerd committed
293
294
      );

metzlerd's avatar
metzlerd committed
295
    }
296
297
298
299
300
  }
  return $form;
}

function forena_format_form_submit($form, &$form_state) {
metzlerd's avatar
metzlerd committed
301
  $values = $form_state['values'];
302
303
  $name = $values['report_name'];

304
  $r = Frx::Editor();
305
306
307
308
309
310
311
312
  $options = array(
    'form' => $values['form']);
  $r->setOptions($options);


  // Doc gen settings.
  if (isset($form['docgen'])) {
    $docgen = array();
metzlerd's avatar
metzlerd committed
313
    if ($selected = array_filter(@$values['docgen']['docs'])) {
314
      if ($selected) foreach ($selected as $key => $value) {
metzlerd's avatar
metzlerd committed
315
        if ($value) $docgen[] = array('type' => $key);
316
317
318
319
320
      }
    }
    $r->setDocgen($docgen);
  }

321
  $r->update();
322
323

}
324

metzlerd's avatar
metzlerd committed
325
function forena_general_form($form, &$form_state, $report_name) {
metzlerd's avatar
metzlerd committed
326
  $name_in = $report_name;
metzlerd's avatar
metzlerd committed
327
  $desc = Frx::Menu()->parseURL($report_name);
metzlerd's avatar
metzlerd committed
328
329
330
  $name = $desc['name'];
  $filename = $desc['filename'];
  $format = @$desc['format'];
metzlerd's avatar
metzlerd committed
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
  $save_name = $name;
  //set the name to empty string for new reports
  $r = Frx::Editor($name);
  $title = (string)$r->title;
  drupal_set_title(filter_xss($r->title));
  $frx_options = $r->getOptions();
  $hidden = @$frx_options['hidden']=='1' ? 1 : 0;
  $report_form = @$frx_options['form'];
  $category = $r->getCategory();
  $menu = $r->getMenu();
  $cache = $r->getCache();
  $form['report_name'] = array(
    '#type' => 'value',
    '#value' => $name,
  );
metzlerd's avatar
metzlerd committed
346

metzlerd's avatar
metzlerd committed
347
348
349
350
351
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#default_value' => $title,
  );
352

metzlerd's avatar
metzlerd committed
353
354
355
356
  $form['visibility'] = array(
    '#type' => 'fieldset',
    '#title' => t('Visibility'),
  );
357

metzlerd's avatar
metzlerd committed
358
359
360
361
362
363
364
  $form['visibility']['category'] = array(
    '#type' => 'textfield',
    '#title' => t('Category'),
    '#default_value' => $category,
    '#autocomplete_path' => 'forena/categories/autocomplete',
    '#description' => t('The heading your report will be grouped under on the report list.'),
  );
metzlerd's avatar
metzlerd committed
365

metzlerd's avatar
metzlerd committed
366
367
368
369
370
371
  $form['visibility']['hidden'] = array(
    '#type' => 'checkbox',
    '#title' => t('Hidden'),
    '#default_value' => $hidden,
    '#description' => t('Hide your report from showing up on the report list.'),
  );
metzlerd's avatar
metzlerd committed
372

metzlerd's avatar
metzlerd committed
373
374
375
376
377
378
379
  $form['menu'] = array(
    '#type' => 'fieldset',
    '#title' => t('Menu'),
    '#tree' => TRUE,
    '#collapsible' => TRUE,
    '#collapsed' => empty($menu),
  );
380

metzlerd's avatar
metzlerd committed
381
382
383
384
385
386
  $form['menu']['path'] = array(
    '#type' => 'textfield',
    '#title' => t('Menu Path'),
    '#description' => t('Indicate site reletive path to menu.  Parameters may be embedded in the url using a :parm syntax (e.g. states/:state)'),
    '#default_value' => @$menu['path'],
  );
387

metzlerd's avatar
metzlerd committed
388
389
390
391
392
393
  $form['menu']['args'] = array(
    '#type' => 'textfield',
    '#title' => t('Additional Arguments'),
    '#description' => t('Indicate additonal parameters that should be extracted after the menu path using a :parm syntax (e.g. :parma/:parmb)'),
    '#default_value' => @$menu['args'],
  );
394

metzlerd's avatar
metzlerd committed
395
396
397
398
399
400
  $form['menu']['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Menu Title'),
    '#description' => t('Title of menu item.  Leave blank to use the report title as the menu title.'),
    '#default_value' => @$menu['title'],
  );
401

metzlerd's avatar
metzlerd committed
402
403
404
405
406
407
  $menu_options = array(
    'normal-item' => t('Normal'),
    'local-task' => t('Tab'),
    'default-local-taks' => t('Default Tab'),
    'callback' => t('Callback'),
  );
408

metzlerd's avatar
metzlerd committed
409
410
411
412
413
414
  $form['menu']['type'] = array(
    '#type' => 'select',
    '#title' => 'Type of menu to create',
    '#options' => $menu_options,
    '#default_value' => @$menu['type'],
  );
415

metzlerd's avatar
metzlerd committed
416
417
418
419
420
421
422
  $form['cache'] = array(
    '#type' => 'fieldset',
    '#title' => t('Cache'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#tree' => TRUE,
  );
423

metzlerd's avatar
metzlerd committed
424
425
426
427
428
429
  $form['cache']['duration'] = array(
    '#type' => 'textfield',
    '#title' => t('Duration'),
    '#description' => t('Specify a php strtotime relative date duration, (e.g. +1 hour, +2 days)'),
    '#default_value' => @$cache['duration'],
  );
430

metzlerd's avatar
metzlerd committed
431
432
433
434
435
  $form['cache']['per_user'] = array(
    '#type' => 'checkbox',
    '#title' => t('Per User'),
    '#default_value' => @$cache['per_user'],
  );
436

metzlerd's avatar
metzlerd committed
437
438
439
440
441
  $form['cache']['per_doctype'] = array(
    '#type' => 'checkbox',
    '#title' => t('Per Document Type'),
    '#default_value' => @$cache['per_doctype'],
  );
442

metzlerd's avatar
metzlerd committed
443
444
445
446
  $form['update'] = array(
    '#type' => 'submit',
    '#value' => 'Update',
  );
447

metzlerd's avatar
metzlerd committed
448
449
450
451
452
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Save',
    '#submit' => array('forena_general_form_submit', 'forena_save_submit'),
  );
453

metzlerd's avatar
metzlerd committed
454
455
456
457
458
  $form['cancel'] = array(
    '#type' => 'submit',
    '#value' => 'Cancel',
    '#submit' => array('forena_save_cancel'),
  );
459

metzlerd's avatar
metzlerd committed
460
  return $form;
461
}
462

metzlerd's avatar
metzlerd committed
463
function forena_general_form_validate($form, &$form_state) {
464
  $values = $form_state['values'];
metzlerd's avatar
metzlerd committed
465
466
467
468
469
  if ($values['menu']['path']) {
    if (!valid_url(str_replace(':', '', $values['menu']['path']), FALSE)) {
      form_set_error('menu][path', t('Invalid Path'));
    }
  }
470
471
472
473
474
475
476
477
  if ($values['cache']['duration']) {
    try {
      $time = @new DateTime($values['cache']['duration']);
    }
    catch (Exception $e) {
    }
    if (!$time) form_set_error('cache][duration' , t('Invalid Cache Duration'));
  }
478
}
479

metzlerd's avatar
metzlerd committed
480
function forena_general_form_submit($form, &$form_state) {
481
482
  $values = $form_state['values'];
  $report_name = $values['report_name'];
483
  $r = Frx::Editor();
metzlerd's avatar
metzlerd committed
484

485
486
487
488
489
490
491
492
  // Title and category
  $r->setTitle($values['title']);
  $r->setCategory($values['category']);
  // Form options
  $options = array(
    'hidden' => $values['hidden'],
  );
  $r->setOptions($options);
metzlerd's avatar
metzlerd committed
493
494
495
496
497
  $menu = $r->getMenu();
  if ($values['menu']!= $menu) {
    $r->setMenu($values['menu']);
    $rebuild_menu = TRUE;
  }
498

499
500
501
502
503
  $cache = $r->cache;
  if ($values['cache']!=$cache) {
    $r->setCache($values['cache']);
  }

metzlerd's avatar
metzlerd committed
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
  $r->update();
}

/**
 * Form function for the edit report form
 * @param $form_state
 * @return the form
 */
function forena_layout_form($form, &$form_state, $report_name) {
  $desc = Frx::Menu()->parseURL($report_name);
  $name = $desc['name'];
  $r = Frx::Editor($name);
  drupal_set_title(filter_xss($r->title));
  // Need to get all option attributes
  $frx_options = $r->getOptions();
  $report_form = @$frx_options['form'];
  $attributes = $r->get_attributes_by_id();
  $body = $r->simplexml->body->asXML();
  $css = @(string)$r->simplexml->head->style;

  //array of xml attributes that are required to have a value
  $required = array('id' => TRUE, 'label' => TRUE);

  $form['report_name'] = array(
    '#type' => 'value',
    '#value' => $name,
  );

  $form['attributes'] = array(
    '#type' => 'value',
    '#value' => $attributes,
  );


  $form['body'] = array(
    '#type' => 'text_format',
    '#title' => t('Body'),
    '#default_value' => $body,
    '#rows' => 25,
  '#format' => variable_get('forena_input_format', filter_default_format())
  );

  $form['style'] = array(
    '#type' => 'fieldset',
    '#title' => t('CSS Styles'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );

  $form['style']['css'] = array(
    '#type' => 'textarea',
    '#default_value' => $css,
    '#description' => t('Specify small css snipets that can be used in the reports.'),
    '#rows' => 10,
    '#cols' => 80,
  );

  $form['buttons']['update'] = array(
    '#type' => 'submit',
    '#value' => 'Update',
    '#submit' => array('forena_layout_form_submit'),
  );

  $form['buttons']['save'] = array(
    '#type' => 'submit',
    '#value' => 'Save',
    '#submit' => array('forena_layout_form_submit', 'forena_save_submit'),
  );

  $form['buttons']['cancel'] = array(
    '#type' => 'submit',
    '#value' => 'Cancel',
    '#submit' => array('forena_save_cancel'),
  );  return $form;

  if (user_access('delete report')) {
    $form['buttons']['delete'] = array(
      '#type' => 'submit',
      '#value' => 'Delete',
      '#submit' => array('forena_edit_delete_submit'),
    );
  }
  return $form;
}

function forena_layout_form_validate($form, &$form_state) {
  $values = $form_state['values'];
  $body = $values['body']['value'];
  $doc_prefix = '<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY nbsp "&#160;">
    ]>';
  if ($body) {
    $body_doc = new DOMDocument('1.0', 'UTF-8');
    $body_xml =  $doc_prefix . '<html xmlns:frx="urn:FrxReports">' . $body . '</html>';
    if (@$body_doc->loadXML($body_xml) === FALSE) {
      form_set_error('body', t('Invalid XHTML Document. Check for unclosed tags or stray &'));
    }
  }

}

/**
 * builds a string of the xml document,
 * submits it to forena_save_report.
 */
function forena_layout_form_submit($form, &$form_state) {
  $nodes = array();
  $rebuild_menu = FALSE;
  $values = $form_state['values'];
  $report_name = $values['report_name'];
  $r = Frx::Editor();


618
619
  // Body
  $r->setBody($values['body']['value']);
620
621
  // CSS
  $r->setStyle($values['css']);
622
  // If there are no frx attributes in the body then replace them with the old values.
623
  $frx_nodes = $r->simplexml->xpath('body//*[@frx:*]');
624
625
626
627
  if (!$frx_nodes) {
    $r->save_attributes_by_id($values['attributes']);
  }

628
  $r->update();
metzlerd's avatar
metzlerd committed
629
  // If we changed the menu we need to rebuild it.
630

631
632
633
}


634
635
636
637
638
/**
 * Handle delete buttons from edit forms.
 * @return unknown_type
 */
function forena_edit_delete_submit($form, &$form_state) {
metzlerd's avatar
metzlerd committed
639
  $link = 'reports/' . $form_state['values']['name_in'] ;
640
641
642
643
644
645
646
647
648
649
650
651
652
653
  $destination = '';
  if (isset($_REQUEST['destination'])) {
    $destination = drupal_get_destination();
    unset($_REQUEST['destination']);
  }
  $form_state['redirect'] = array('path' => $link . '/delete', 'query' => array('destination' => $destination));
}


function forena_add_report_form($formid, $form_state, $report_name='') {
  $name = '';
  $filename = '';
  $format = '';
  if ($report_name) {
metzlerd's avatar
metzlerd committed
654
    $desc = Frx::Menu()->parseURL($report_name);
655
    $name = $desc['name'];
656
657
658
    $filename = $desc['filename'];
    $format = @$desc['format'];
  }
659
660
661
662
  $form = array();
  global $language;
  //determine if this is an add new report request

663
  $r = Frx::Editor($name);
664
665
666
667
668
669
670
671
672
  $title = (string)$r->title;
  if (module_exists('locale')) {
    @list($tlang,  $tsave_name) = explode('/', $name, 2);
    // FInd out if the starting name of the report is an installed language.
    if (array_key_exists($tlang, language_list() )) {
      $lang = $tlang;
      $save_name = $tsave_name;
    }
    else {
metzlerd's avatar
metzlerd committed
673
      $lang = 'en';
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
    }
  }
  // Need to get all option attributes
  $frx_options = $r->getOptions();
  $hidden = @$frx_options['hidden']=='1' ? 1 : 0;
  $report_form = @$frx_options['form'];
  $attributes = $r->get_attributes_by_id();
  $category = $r->getCategory();
  $body = $r->simplexml->body->asXML();


  //array of xml attributes that are required to have a value
  $required = array('id' => TRUE, 'label' => TRUE);
  //list of supported document formats
  $doclist = variable_get('forena_doc_formats', array());

  $form['save_report_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Report Name'),
    '#description' => t('Enter only letters, numbers, and special characters:  - _ /
                         <br/>White space is not permitted.
                         Create a directory using the format: (directory name) / (report name). Save multiple reports to the same directory
                         by referencing the same name.'),
    '#required' => TRUE,
  );


  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#default_value' => $title,
metzlerd's avatar
metzlerd committed
705
    '#required' => TRUE,
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
  );

  $form['category'] = array(
    '#type' => 'textfield',
    '#title' => t('Category'),
    '#default_value' => $category,
    '#autocomplete_path' => 'forena/categories/autocomplete',
    '#description' => t('The heading your report will be grouped under on the report list.'),
  );

  $form['hidden'] = array(
    '#type' => 'checkbox',
    '#title' => t('Hidden'),
    '#default_value' => $hidden,
    '#description' => t('Hide your report from showing up on the report list.'),
  );

  $form['report_name'] = array(
    '#title' => t('Create from report'),
    '#type' => 'textfield',
726
    '#autocomplete_path' => 'forena/reports/autocomplete',
727
728
729
730
731
732
733
    '#default_value' => $name,
  );

  $form['save'] = array(
    '#type' => 'submit',
    '#value' => 'Create',
  );
734
735
736
737
738
  return $form;

}

function forena_add_report_form_validate($form, &$form_state) {
739
  $values = $form_state['values'];
740
  $regexp = "/^[A-Za-z0-9\/\_\-]*$/";
741
  $save_report_name = $values['save_report_name'];
metzlerd's avatar
metzlerd committed
742

743
744
  //comparing the report names to see if they have changed.
  //If they have, making sure the new name does not already exist.
745
746
747
  $filename = $save_report_name . '.frx';
  if (Frx::File()->exists($filename, FALSE)) {
    form_set_error('save_report_name', t('The report ' . $save_report_name . ' already exists. Please enter another name.'));
metzlerd's avatar
metzlerd committed
748
  }
749
}
750

751
function forena_add_report_form_submit($form, &$form_state) {
752
  $values = $form_state['values'];
753
  $report_name = $values['save_report_name'];
metzlerd's avatar
metzlerd committed
754
  $desc = Frx::Menu()->parseURL($report_name);
755
  $report_name = $desc['name'];
756

757
758
759
760
761
762
763
  if ($values['report_name']) {
    $r = Frx::Editor($values['report_name']);
    $r->report_name = $values['save_report_name'];
  }
  else {
    $r = Frx::Editor($values['save_report_name']);
  }
764
765
766
767
768
769
  // Title and category
  $r->setTitle($values['title']);
  $r->setCategory($values['category']);
  // Form options
  $options = array(
    'hidden' => $values['hidden'],
770
  );
771
772
  $r->setOptions($options);

773
  //determine redirection.
774
  $filename = $desc['filename'];
metzlerd's avatar
metzlerd committed
775

776
777
778
779
780
781
782
  $r->update();
  //if this is a new report then redirect to data blocks
  if ($values['report_name']) {
    $edit = '/edit';
  }
  else {
    $edit = '/edit/data/add';
metzlerd's avatar
metzlerd committed
783
  }
784
785
  $form_state['redirect']= $desc['i_link'] . $edit;

786
787
}
function forena_create_trans_form($formid, $form_state, $report_name) {
788
789
790
  $name = '';
  $filename = '';
  $format = '';
metzlerd's avatar
metzlerd committed
791
  $desc = Frx::Menu()->parseURL($report_name);
792
793
794
795
  $name = $desc['name'];
  $filename = $desc['filename'];
  $base_name = $desc['base_name'];
  $format = @$desc['format'];
796
797
  $form = array();
  global $language;
798
  $languages = language_list();
799
800
  //determine if this is an add new report request

801
  $r = Frx::Editor($name);
802
803
804
  $title = (string)$r->title;
  $lang = @$_GET['language'];
  if ($lang) {
metzlerd's avatar
metzlerd committed
805
    $language = $languages[$lang];
806
807
808
809
810
811
812
813
814
  }
  $form['base_name'] = array(
    '#type' => 'value',
    '#value' => $base_name
  );
  $form['report_name'] = array(
    '#type' => 'value',
    '#value' => $name,
  );
815

metzlerd's avatar
metzlerd committed
816
  foreach ($languages as $key => $obj) {
817
    $languages[$key] = $obj->native;
818
  }
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
  $form['report_lang'] = array(
    '#type' => 'value',
    '#value' => $lang,
  );
  $def_lang = $lang ? $lang : 'en';
  $form['save_report_language'] = array(
    '#type' => 'select',
    '#title' => t('Language'),
    '#options' => $languages,
    '#default_value' => $def_lang,
  );


  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#default_value' => $title,
metzlerd's avatar
metzlerd committed
836
    '#required' => TRUE,
837
838
839
840
841
842
843
844
845
  );


  $form['save'] = array(
    '#type' => 'submit',
    '#value' => 'Create',
  );
  return $form;

846
847
848
849
}

function forena_create_trans_form_submit($form, &$form_state) {
  $values = $form_state['values'];
850
  $base_name = $values['base_name'];
metzlerd's avatar
metzlerd committed
851
  $new_name = $values['save_report_language'] . '/' . $base_name;
852

metzlerd's avatar
metzlerd committed
853
  $desc = Frx::Menu()->parseURL($new_name);
854
855
  $filename = $desc['filename'];
  $report_name = $desc['name'];
856

857
  $r = Frx::Editor($values['report_name']);
858
859
860

  // Title and category
  $r->setTitle($values['title']);
metzlerd's avatar
metzlerd committed
861

metzlerd's avatar
metzlerd committed
862
  //determine redirection.
863

864
  if (Frx::File()->exists($filename, FALSE)) {
metzlerd's avatar
metzlerd committed
865
    drupal_set_message(t('Report %s already exists', array('%s' => $new_name)), 'error');
866
    return;
metzlerd's avatar
metzlerd committed
867
  }
metzlerd's avatar
metzlerd committed
868

869
870
871
872
  $r->update();
  drupal_set_message(t('Translation,  %s has been created. Switch languages to translate.', array('%s' => $values['title'])));
  //if this is a new report then redirect to data blocks
  $form_state['redirect']= array( $desc['i_link'] . '/edit/layout');
873
}
874

875
876


877
878
879
880
/*
 * administer the settings for document format options
 */
function forena_doc_formats_settings() {
881
  // Invoke doc_type hook to see which document types are there.
882
  $supported_doctypes = Frx::documentTypes();
883

884
885
  $form['forena_doc_formats'] = array(
    '#type' => 'checkboxes',
886
    '#title' => t('Allowed Document Formats'),
887
888
889
890
    '#default_value' => variable_get('forena_doc_formats', $supported_doctypes),
    '#description' => t('check your desired document format'),
    '#options' => $supported_doctypes,
  );
891
892
893
894

  $form['forena_doc_defaults'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Default Document Formats'),
895
    '#default_value' => variable_get('forena_doc_defaults', array()),
896
897
898
899
    '#description' => t('check your desired document format'),
    '#options' => $supported_doctypes,
  );

900
901
902
  $form['forena_email_override'] = array(
    '#type' => 'checkbox',
    '#title' => 'Run email merges in test mode' ,
metzlerd's avatar
metzlerd committed
903
    '#default_value' => variable_get('forena_email_override', FALSE),
904
905
    '#description' => t('When this box is checked emails are sent to the currently logged in user.  Useful for testing environments.'),
  );
906
  $form['forena_email_input_format'] = forena_filter_element(variable_get('forena_email_input_format', 'full_text'), 'forena_email_input_format');
907
  $form['forena_email_input_format']['#title'] = t('Email Input Format');
908

909
910
  return system_settings_form($form);
}
911

912
913
914
915
/*
 * administer the settings for document format options
 */
function forena_data_settings() {
916
  $repos = Frx::RepoMan()->repositories;
917
  $r_list = array();
metzlerd's avatar
metzlerd committed
918
919
  $headers = array(t('Name'), t('Description'), t('Path'), t('Operation'));
  foreach ($repos as $name => $r) {
920
    $r_list[] = array(
metzlerd's avatar
metzlerd committed
921
922
923
924
    $name,
    $r['title'],
    $r['path'],
    l(t('configure'), 'admin/config/content/forena/data/configure/' . $name)
925
926
927
928
    );

  }

metzlerd's avatar
metzlerd committed
929
930
  $output = '<ul class="action-links"><li>' . l(t('Add data source'), 'admin/config/content/forena/data/add') . '</li></ul>';
  $output .= theme_table(array('header' => $headers, 'rows' => $r_list, 'attributes' => array(), 'caption' => '', 'sticky' => TRUE, 'colgroups' => array(), 'empty' => ''));
931
932
933
934
  return $output;
}

function forena_data_settings_edit($form, &$form_state, $source=-1) {
935
  global $databases;
936
937
938
939
940
941
942
943
944
  $adding = ($source === -1);
  if (!@$form_state['storage']) {
    if ($adding) {
      $form_state['storage'] = array(
        'name' => '',
        'title' => '',
        'path' => '',
        'config' => array(
          'source' => 'user',
davidmetzler's avatar
davidmetzler committed
945
          'data provider' => 'FrxDrupal',
946
          'database' => 'default',
947
948
          'access callback' => 'user_access',
          'user callback' => 'forena_current_user_id'
metzlerd's avatar
metzlerd committed
949
950
          ),
          );
951
952
    }
    else {
953
954
      Frx::RepoMan()->repository($source);
      $repos = Frx::RepoMan()->repositories;
955
      $r = $repos[$source];
davidmetzler's avatar
davidmetzler committed
956
      // Remove teh object from the data.
957
      unset($r['data']);
958
959
960
      $form_state['storage'] = array(
        'name' => $source,
        'title' => $r['title'],
davidmetzler's avatar
davidmetzler committed
961
        'path' => @$r['path'],
962
        'config' => $r,
963
964
965
966
967
968
      );

    }
  }
  $data = $form_state['storage'];
  $config = $data['config'];
davidmetzler's avatar
davidmetzler committed
969

davidmetzler's avatar
davidmetzler committed
970
  $locked = !($adding || (@$config['source'] == 'user'));
971
972
973
974
975
976
977
978
979
  $values = @$form_state['values'];

  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#description' => t('Machine readable name.  Used in referencing all data used by this source. must should not contain any special characters or spaces.'),
    '#disabled' => !$adding,
    '#default_value' => $data['name'],
    '#required' => TRUE,
metzlerd's avatar
metzlerd committed
980
  );
981
982
983
984

  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
davidmetzler's avatar
davidmetzler committed
985
    '#required' => TRUE,
986
987
988
989
990
991
992
993
994
995
996
    '#description' => t('Human readable name that describes the data source.  This primarily occurs in error messages where the data source cannot be accessed.'),
    '#default_value' => $data['title'],
  );

  $form['enabled'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enabled'),
    '#description' => t('Disabling will cause all queries to return no data.'),
    '#default_value' => @$data['enabled']!==0,
  );

davidmetzler's avatar
davidmetzler committed
997
998
999
1000
1001
1002
1003
  $form['debug'] = array(
    '#type' => 'checkbox',
    '#title' => t('Debug'),
    '#description' => t('Write information to the screen and logs for each query executed.'),
    '#default_value' => @$config['debug'],
  );

1004
1005
1006
  $form['path'] = array(
    '#type' => 'textfield',
    '#title' => t('Path'),
davidmetzler's avatar
davidmetzler committed
1007
    '#required' => TRUE,
1008
    '#disabled' => $locked,
1009
1010
1011
1012
    '#description' => t('Directory containing data block files.'),
    '#default_value' => @$data['path'],
  );

davidmetzler's avatar
davidmetzler committed
1013
1014
1015
1016
1017
1018
1019
1020
1021
  $user_options = array(
    '' => 'None',
    'forena_current_user_id' => 'UID',
    'forena_current_user_name' => 'User name',
  );

  $form['user_callback'] = array(
    '#type' => 'select',
    '#title' =>  'Current user',
1022
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
1023
1024
    '#description' => t('Can be refererenced as :current_user in each data block.'),
    '#options' => $user_options,
1025
    '#default_value' => @$config['user callback'],
davidmetzler's avatar
davidmetzler committed
1026
1027
1028
1029
    '#disabled' => $locked,
  );


1030
1031
  // Access method list
  $access = array(
davidmetzler's avatar
davidmetzler committed
1032
    'callback' => t('Use drupal permissions'),
metzlerd's avatar
metzlerd committed
1033
    'block' => t('Match values provided by a data block.'),
1034
1035
1036
1037
1038
  );

  $form['access_method'] = array(
    '#type' => 'select',
    '#options' => $access,
1039
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
1040
1041
    '#title' => t('Data security method'),
    '#default_value' => empty($config['access block']) ? 'callback' : 'block',
metzlerd's avatar
metzlerd committed
1042
    '#description' => t('Specify how the ACCESS defined for a data block is to be interpreted.'),
1043
1044
1045
    '#ajax' => array(
      'callback' => 'forena_access_info_callback',
      'wrapper' => 'access-details',
metzlerd's avatar
metzlerd committed
1046
  ),
1047
1048
1049
1050
1051
1052
  );

  $form['access_details'] = array(
    '#type' => 'fieldset',
    '#prefix' => '<div id="access-details">',
    '#suffix' => '</div>',
davidmetzler's avatar
davidmetzler committed
1053
    '#title' => t('Details'),
1054
1055
1056
  ) ;

  switch (!empty($values['access_method']) ? $values['access_method'] : $form['access_method']['#default_value']) {
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
    case 'block':
      $form['access_details']['access_block'] = array(
        '#type' => 'textfield',
        '#title' => 'Data block providing permissions list',
        '#disabled' => $locked,
        '#autocomplete_path' => 'forena/data_block/autocomplete',
        '#description' => t('The datablock to be used to interpret permissions.  This should return a single column of permissions based on the current user.   May be provided by another repository.'),
        '#default_value' => @$config['access block'],
      );
      break;
    default:
      $form['access_details']['access_callback'] = array(
        '#type' => 'item',
        '#title' => 'Access callback',
        '#disabled' => $locked,
        '#markup' => @$config['access callback'],
      );
1074
1075
1076
1077
1078
1079
1080
1081
  }



  // Driver list
  $drivers = array(
    'FrxDrupal' => t('Drupal'),
    'FrxOracle' => t('Oracle Database'),
metzlerd's avatar
metzlerd committed
1082
    'FrxPDO' => t('PDO other than Drupal'),
1083
1084
1085
1086
1087
    'FrxPostgres' => t('Postgres Database'),
    'FrxMSSQL' => t('MSSQL Database'),
    'FrxFiles' => t('XML Files'),
  );

davidmetzler's avatar
davidmetzler committed
1088
  $form['data_provider'] = array(
1089
1090
1091
1092
1093
    '#type' => 'select',
    '#title' => t('Driver'),
    '#description' => t('Forena data connection type'),
    '#options' => $drivers,
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
1094
    '#default_value' => $config['data provider'],
1095
1096
1097
    '#ajax' => array(
      'callback' => 'forena_connection_info_callback',
      'wrapper' => 'conn-div',
metzlerd's avatar
metzlerd committed
1098
  ),
1099
1100
1101
1102
  );

  $form['connection'] = array(
    '#type' => 'fieldset',
davidmetzler's avatar
davidmetzler committed
1103
    '#tree' => TRUE,
1104
1105
1106
1107
    '#title' => 'Connection info',
   '#prefix' =>  '<div id="conn-div">',
   '#suffix' => '</div>',
  );
davidmetzler's avatar
davidmetzler committed
1108
  $data_provider = (!empty($form_state['values']['data_provider']) ? $form_state['values']['data_provider'] : $config['data provider']);
1109

davidmetzler's avatar
davidmetzler committed
1110
1111
1112
1113
1114
  // Common controls used in mulitple providers.
  $uri = array(
    '#type' => 'textfield',
    '#title' => t('uri'),
    '#descripton' => t('Connection string: see appropriate php documentation for more details.'),
1115
    '#default_value' => @$config['uri'],
davidmetzler's avatar
davidmetzler committed
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
    '#required' => TRUE,
    '#disabled' => $locked,
  );

  $user = array(
    '#type' => 'textfield',
    '#title' => t('User'),
    '#default_value' => @$config['user'],
  );
  $password= array(
    '#type' => 'password',
    '#title' => t('Password'),
    '#default_value' => @$config['password'],
metzlerd's avatar
metzlerd committed
1129
  );
davidmetzler's avatar
davidmetzler committed
1130

davidmetzler's avatar
davidmetzler committed
1131
  switch ($data_provider) {
davidmetzler's avatar
davidmetzler committed
1132
    case 'FrxDrupal':
1133
1134
1135
1136
      $db_list = array_combine(array_keys($databases), array_keys($databases));
      $form['connection']['database'] = array(
        '#type' => 'select',
        '#title' => t('Database'),
1137
        '#disabled' => $locked,
1138
1139
        '#default_value' => @$config['database'],
        '#options' => $db_list,
davidmetzler's avatar
davidmetzler committed
1140
1141
1142
1143
        '#markup' => 'Determined by Drupal settings.php file',
      );
      break;
    case 'FrxMSSQL':
1144
1145
1146
      $form['connection']['uri'] = $uri;
      $form['connection']['user'] = $user;
      $form['connection']['new_password'] = $password;
1147
1148
1149
1150