forena.admin.inc 74.9 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
34
  $headers = array(t('title'), t('name'), t('category'), t('operation'));
  $result = db_query('SELECT * FROM {forena_reports} where language=:language ORDER BY category,title', array(':language' => $language->language));
  foreach ($result as $row) {
35
    $rpt = str_replace('/', '.', $row->report_name);
metzlerd's avatar
metzlerd committed
36
37
38
39
40
    $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')));
    $title = l(t($row->title), 'reports/' . $rpt);
    $data[] = array($title, $row->report_name, $row->category, $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) {
metzlerd's avatar
metzlerd committed
464
465
466
467
468
  if ($values['menu']['path']) {
    if (!valid_url(str_replace(':', '', $values['menu']['path']), FALSE)) {
      form_set_error('menu][path', t('Invalid Path'));
    }
  }
469
470
471
472
473
474
475
476
  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'));
  }
477
}
478

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

484
485
486
487
488
489
490
491
  // 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
492
493
494
495
496
  $menu = $r->getMenu();
  if ($values['menu']!= $menu) {
    $r->setMenu($values['menu']);
    $rebuild_menu = TRUE;
  }
497

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

metzlerd's avatar
metzlerd committed
503
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
  $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();


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

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

630
631
632
}


633
634
635
636
637
/**
 * Handle delete buttons from edit forms.
 * @return unknown_type
 */
function forena_edit_delete_submit($form, &$form_state) {
metzlerd's avatar
metzlerd committed
638
  $link = 'reports/' . $form_state['values']['name_in'] ;
639
640
641
642
643
644
645
646
647
648
649
650
651
652
  $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
653
    $desc = Frx::Menu()->parseURL($report_name);
654
    $name = $desc['name'];
655
656
657
    $filename = $desc['filename'];
    $format = @$desc['format'];
  }
658
659
660
661
  $form = array();
  global $language;
  //determine if this is an add new report request

662
  $r = Frx::Editor($name);
663
664
665
666
667
668
669
670
671
  $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
672
      $lang = 'en';
673
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
    }
  }
  // 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
704
    '#required' => TRUE,
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
  );

  $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',
725
    '#autocomplete_path' => 'forena/reports/autocomplete',
726
727
728
729
730
731
732
    '#default_value' => $name,
  );

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

}

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

742
743
  //comparing the report names to see if they have changed.
  //If they have, making sure the new name does not already exist.
744
745
746
  $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
747
  }
748
}
749

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

756
757
758
759
760
761
762
  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']);
  }
763
764
765
766
767
768
  // Title and category
  $r->setTitle($values['title']);
  $r->setCategory($values['category']);
  // Form options
  $options = array(
    'hidden' => $values['hidden'],
769
  );
770
771
  $r->setOptions($options);

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

775
776
777
778
779
780
781
  $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
782
  }
783
784
  $form_state['redirect']= $desc['i_link'] . $edit;

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

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

metzlerd's avatar
metzlerd committed
815
  foreach ($languages as $key => $obj) {
816
    $languages[$key] = $obj->native;
817
  }
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
  $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
835
    '#required' => TRUE,
836
837
838
839
840
841
842
843
844
  );


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

845
846
847
848
}

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

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

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

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

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

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

868
869
870
871
  $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');
872
}
873

874
875


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

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

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

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

908
909
  return system_settings_form($form);
}
910

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

  }

metzlerd's avatar
metzlerd committed
928
929
  $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' => ''));
930
931
932
933
  return $output;
}

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

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

davidmetzler's avatar
davidmetzler committed
969
  $locked = !($adding || (@$config['source'] == 'user'));
970
971
972
973
974
975
976
977
978
  $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
979
  );
980
981
982
983

  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
davidmetzler's avatar
davidmetzler committed
984
    '#required' => TRUE,
985
986
987
988
989
990
991
992
993
994
995
    '#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
996
997
998
999
1000
1001
1002
  $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'],
  );

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

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

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


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

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

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

  switch (!empty($values['access_method']) ? $values['access_method'] : $form['access_method']['#default_value']) {
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
    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'],
      );
1073
1074
1075
1076
1077
1078
1079
1080
  }



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

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

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

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

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