forena.admin.inc 74.3 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_save_submit'),
metzlerd's avatar
metzlerd committed
287
288
      );
    }
289
290
291
292
293
  }
  return $form;
}

function forena_format_form_submit($form, &$form_state) {
metzlerd's avatar
metzlerd committed
294
  $values = $form_state['values'];
295
296
  $name = $values['report_name'];

297
  $r = Frx::Editor();
298
299
300
301
302
303
304
305
  $options = array(
    'form' => $values['form']);
  $r->setOptions($options);


  // Doc gen settings.
  if (isset($form['docgen'])) {
    $docgen = array();
metzlerd's avatar
metzlerd committed
306
    if ($selected = array_filter(@$values['docgen']['docs'])) {
307
      if ($selected) foreach ($selected as $key => $value) {
metzlerd's avatar
metzlerd committed
308
        if ($value) $docgen[] = array('type' => $key);
309
310
311
312
313
      }
    }
    $r->setDocgen($docgen);
  }

314
  $r->save();
315
316

}
317

318
319
320
321
322
/**
 * Form function for the edit report form
 * @param $form_state
 * @return the form
 */
323
function forena_layout_form($form, $form_state, $report_name) {
metzlerd's avatar
metzlerd committed
324
  $name_in = $report_name;
metzlerd's avatar
metzlerd committed
325
  $desc = Frx::Menu()->parseURL($report_name);
metzlerd's avatar
metzlerd committed
326
  $name = $desc['name'];
327
  global $language;
metzlerd's avatar
metzlerd committed
328
  //determine if this is an add new report request
329

metzlerd's avatar
metzlerd committed
330
331
  $filename = $desc['filename'];
  $format = @$desc['format'];
332
333
334
335
336
337
338
339
340
341
342
    $save_name = $name;
    //set the name to empty string for new reports
    $r = Frx::Editor($name);

    $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;
metzlerd's avatar
metzlerd committed
343
      }
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
      else {
        $lang = 'en';
      }
    }
    drupal_set_title(filter_xss($r->title));
    // 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();
    $menu = $r->getMenu();
    $cache = $r->getCache();
    $body = $r->simplexml->body->asXML();
    $css = @(string)$r->simplexml->head->style;
metzlerd's avatar
metzlerd committed
359

360
    $form = array();
361

362
363
    //array of xml attributes that are required to have a value
    $required = array('id' => TRUE, 'label' => TRUE);
metzlerd's avatar
metzlerd committed
364

365
366
367
368
    $form['report_name'] = array(
      '#type' => 'value',
      '#value' => $name,
    );
369

370
371
372
373
    $form['name_in'] = array(
      '#type' => 'value',
      '#value' => $name_in,
    );
374

375
376
377
378
    $form['attributes'] = array(
      '#type' => 'value',
      '#value' => $attributes,
    );
metzlerd's avatar
metzlerd committed
379

380
381
382
383
384
    $form['title'] = array(
      '#type' => 'textfield',
      '#title' => t('Title'),
      '#default_value' => $title,
    );
385

386
387
388
389
390
391
392
393
394
395
396
    $form['body'] = array(
      '#type' => 'text_format',
      '#title' => t('Body'),
      '#default_value' => $body,
      '#rows' => 25,
    '#format' => variable_get('forena_input_format', filter_default_format())
    );
    $form['visibility'] = array(
      '#type' => 'fieldset',
      '#title' => t('Visibility'),
    );
metzlerd's avatar
metzlerd committed
397

398
399
400
401
402
403
404
    $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
405

406
407
408
409
410
411
    $form['visibility']['hidden'] = array(
      '#type' => 'checkbox',
      '#title' => t('Hidden'),
      '#default_value' => $hidden,
      '#description' => t('Hide your report from showing up on the report list.'),
    );
412

413
414
415
416
417
418
419
    $form['menu'] = array(
      '#type' => 'fieldset',
      '#title' => t('Menu'),
      '#tree' => TRUE,
      '#collapsible' => TRUE,
      '#collapsed' => empty($menu),
    );
420

421
422
423
424
425
426
    $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'],
    );
metzlerd's avatar
metzlerd committed
427

428
429
430
431
432
433
    $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'],
    );
metzlerd's avatar
metzlerd committed
434

435
436
437
438
439
440
    $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'],
    );
441

442
443
444
445
446
447
    $menu_options = array(
      'normal-item' => t('Normal'),
      'local-task' => t('Tab'),
      'default-local-taks' => t('Default Tab'),
      'callback' => t('Callback'),
    );
448

449
450
451
452
453
454
    $form['menu']['type'] = array(
      '#type' => 'select',
      '#title' => 'Type of menu to create',
      '#options' => $menu_options,
      '#default_value' => @$menu['type'],
    );
455

456
457
458
459
460
461
    $form['style'] = array(
      '#type' => 'fieldset',
      '#title' => t('CSS Styles'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
    );
462

463
464
465
466
467
468
469
    $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,
    );
470

471
472
473
474
475
476
477
    $form['cache'] = array(
      '#type' => 'fieldset',
      '#title' => t('Cache'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#tree' => TRUE,
    );
478

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
    $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'],
    );

    $form['cache']['per_user'] = array(
      '#type' => 'checkbox',
      '#title' => t('Per User'),
      '#default_value' => @$cache['per_user'],
    );

    $form['cache']['per_doctype'] = array(
      '#type' => 'checkbox',
      '#title' => t('Per Document Type'),
      '#default_value' => @$cache['per_doctype'],
    );

    $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_save_submit'),
    );

    if (user_access('delete report')) {
      $form['buttons']['delete'] = array(
512
        '#type' => 'submit',
513
514
        '#value' => 'Delete',
        '#submit' => array('forena_edit_delete_submit'),
515
516
      );
    }
517
518
    return $form;

519
}
520

521
function forena_layout_form_validate($form, &$form_state) {
metzlerd's avatar
metzlerd committed
522
  $values = $form_state['values'];
523
524
525
526
527
528
  $body = $values['body']['value'];
  $doc_prefix = '<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE root [
    <!ENTITY nbsp "&#160;">
    ]>';
  if ($body) {
metzlerd's avatar
metzlerd committed
529
    $body_doc = new DOMDocument('1.0', 'UTF-8');
530
531
    $body_xml =  $doc_prefix . '<html xmlns:frx="urn:FrxReports">' . $body . '</html>';
    if (@$body_doc->loadXML($body_xml) === FALSE) {
metzlerd's avatar
metzlerd committed
532
      form_set_error('body', t('Invalid XHTML Document. Check for unclosed tags or stray &'));
533
534
    }
  }
metzlerd's avatar
metzlerd committed
535
536
537
538
539
  if ($values['menu']['path']) {
    if (!valid_url(str_replace(':', '', $values['menu']['path']), FALSE)) {
      form_set_error('menu][path', t('Invalid Path'));
    }
  }
540
541
542
543
544
545
546
547
  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'));
  }
548
}
549
550
551
552
553
554
555

/**
 * builds a string of the xml document,
 * submits it to forena_save_report.
 */
function forena_layout_form_submit($form, &$form_state) {
  $nodes = array();
metzlerd's avatar
metzlerd committed
556
  $rebuild_menu = FALSE;
557
558
  $values = $form_state['values'];
  $report_name = $values['report_name'];
559
  $r = Frx::Editor();
560
561
562
563
564
565
566
567
  // 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
568
569
570
571
572
  $menu = $r->getMenu();
  if ($values['menu']!= $menu) {
    $r->setMenu($values['menu']);
    $rebuild_menu = TRUE;
  }
573

574
575
576
577
578
  $cache = $r->cache;
  if ($values['cache']!=$cache) {
    $r->setCache($values['cache']);
  }

579
580
  // Body
  $r->setBody($values['body']['value']);
581
582
  // CSS
  $r->setStyle($values['css']);
583
  // If there are no frx attributes in the body then replace them with the old values.
584
  $frx_nodes = $r->simplexml->xpath('body//*[@frx:*]');
585
586
587
588
589
  if (!$frx_nodes) {
    $r->save_attributes_by_id($values['attributes']);
  }

  if (forena_save_report($report_name, $r->asXML(), TRUE) == 1) {
metzlerd's avatar
metzlerd committed
590
    drupal_set_message(t('Your report, %s has been saved.', array('%s' => $report_name)));
591
  }
metzlerd's avatar
metzlerd committed
592
593
594
595
  // If we changed the menu we need to rebuild it.
  if ($rebuild_menu) {
    menu_rebuild();
  }
596
597
598
}


599
600
601
602
603
/**
 * Handle delete buttons from edit forms.
 * @return unknown_type
 */
function forena_edit_delete_submit($form, &$form_state) {
metzlerd's avatar
metzlerd committed
604
  $link = 'reports/' . $form_state['values']['name_in'] ;
605
606
607
608
609
610
611
612
613
614
615
616
617
618
  $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
619
    $desc = Frx::Menu()->parseURL($report_name);
620
    $name = $desc['name'];
621
622
623
    $filename = $desc['filename'];
    $format = @$desc['format'];
  }
624
625
626
627
  $form = array();
  global $language;
  //determine if this is an add new report request

628
  $r = Frx::Editor($name);
629
630
631
632
633
634
635
636
637
  $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
638
      $lang = 'en';
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
    }
  }
  // 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
670
    '#required' => TRUE,
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  );

  $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',
691
    '#autocomplete_path' => 'forena/reports/autocomplete',
692
693
694
695
696
697
698
    '#default_value' => $name,
  );

  $form['save'] = array(
    '#type' => 'submit',
    '#value' => 'Create',
  );
699
700
701
702
703
  return $form;

}

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

708
709
  //comparing the report names to see if they have changed.
  //If they have, making sure the new name does not already exist.
710
711
712
  $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
713
  }
714
}
715

716
function forena_add_report_form_submit($form, &$form_state) {
717
  $values = $form_state['values'];
718
  $report_name = $values['save_report_name'];
metzlerd's avatar
metzlerd committed
719
  $desc = Frx::Menu()->parseURL($report_name);
720
  $report_name = $desc['name'];
721

722
723
724
725
726
727
728
  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']);
  }
729
730
731
732
733
734
  // Title and category
  $r->setTitle($values['title']);
  $r->setCategory($values['category']);
  // Form options
  $options = array(
    'hidden' => $values['hidden'],
735
  );
736
737
  $r->setOptions($options);

738
  //determine redirection.
739
  $filename = $desc['filename'];
metzlerd's avatar
metzlerd committed
740

741
742
743
744
745
746
747
  $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
748
  }
749
750
  $form_state['redirect']= $desc['i_link'] . $edit;

751
752
}
function forena_create_trans_form($formid, $form_state, $report_name) {
753
754
755
  $name = '';
  $filename = '';
  $format = '';
metzlerd's avatar
metzlerd committed
756
  $desc = Frx::Menu()->parseURL($report_name);
757
758
759
760
  $name = $desc['name'];
  $filename = $desc['filename'];
  $base_name = $desc['base_name'];
  $format = @$desc['format'];
761
762
  $form = array();
  global $language;
763
  $languages = language_list();
764
765
  //determine if this is an add new report request

766
  $r = Frx::Editor($name);
767
768
769
  $title = (string)$r->title;
  $lang = @$_GET['language'];
  if ($lang) {
metzlerd's avatar
metzlerd committed
770
    $language = $languages[$lang];
771
772
773
774
775
776
777
778
779
  }
  $form['base_name'] = array(
    '#type' => 'value',
    '#value' => $base_name
  );
  $form['report_name'] = array(
    '#type' => 'value',
    '#value' => $name,
  );
780

metzlerd's avatar
metzlerd committed
781
  foreach ($languages as $key => $obj) {
782
    $languages[$key] = $obj->native;
783
  }
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
  $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
801
    '#required' => TRUE,
802
803
804
805
806
807
808
809
810
  );


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

811
812
813
814
}

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

metzlerd's avatar
metzlerd committed
818
  $desc = Frx::Menu()->parseURL($new_name);
819
820
  $filename = $desc['filename'];
  $report_name = $desc['name'];
821

822
  $r = Frx::Editor($values['report_name']);
823
824
825

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

metzlerd's avatar
metzlerd committed
827
  //determine redirection.
828

829
  if (Frx::File()->exists($filename, FALSE)) {
metzlerd's avatar
metzlerd committed
830
    drupal_set_message(t('Report %s already exists', array('%s' => $new_name)), 'error');
831
    return;
metzlerd's avatar
metzlerd committed
832
  }
metzlerd's avatar
metzlerd committed
833

834
835
836
837
  $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');
838
}
839

840
841


842
843
844
845
/*
 * administer the settings for document format options
 */
function forena_doc_formats_settings() {
846
  // Invoke doc_type hook to see which document types are there.
847
  $supported_doctypes = Frx::documentTypes();
848

849
850
  $form['forena_doc_formats'] = array(
    '#type' => 'checkboxes',
851
    '#title' => t('Allowed Document Formats'),
852
853
854
855
    '#default_value' => variable_get('forena_doc_formats', $supported_doctypes),
    '#description' => t('check your desired document format'),
    '#options' => $supported_doctypes,
  );
856
857
858
859

  $form['forena_doc_defaults'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Default Document Formats'),
860
    '#default_value' => variable_get('forena_doc_defaults', array()),
861
862
863
864
    '#description' => t('check your desired document format'),
    '#options' => $supported_doctypes,
  );

865
866
867
  $form['forena_email_override'] = array(
    '#type' => 'checkbox',
    '#title' => 'Run email merges in test mode' ,
metzlerd's avatar
metzlerd committed
868
    '#default_value' => variable_get('forena_email_override', FALSE),
869
870
    '#description' => t('When this box is checked emails are sent to the currently logged in user.  Useful for testing environments.'),
  );
871
  $form['forena_email_input_format'] = forena_filter_element(variable_get('forena_email_input_format', 'full_text'), 'forena_email_input_format');
872
  $form['forena_email_input_format']['#title'] = t('Email Input Format');
873

874
875
  return system_settings_form($form);
}
876

877
878
879
880
/*
 * administer the settings for document format options
 */
function forena_data_settings() {
881
  $repos = Frx::RepoMan()->repositories;
882
  $r_list = array();
metzlerd's avatar
metzlerd committed
883
884
  $headers = array(t('Name'), t('Description'), t('Path'), t('Operation'));
  foreach ($repos as $name => $r) {
885
    $r_list[] = array(
metzlerd's avatar
metzlerd committed
886
887
888
889
    $name,
    $r['title'],
    $r['path'],
    l(t('configure'), 'admin/config/content/forena/data/configure/' . $name)
890
891
892
893
    );

  }

metzlerd's avatar
metzlerd committed
894
895
  $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' => ''));
896
897
898
899
  return $output;
}

function forena_data_settings_edit($form, &$form_state, $source=-1) {
900
  global $databases;
901
902
903
904
905
906
907
908
909
  $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
910
          'data provider' => 'FrxDrupal',
911
          'database' => 'default',
912
913
          'access callback' => 'user_access',
          'user callback' => 'forena_current_user_id'
metzlerd's avatar
metzlerd committed
914
915
          ),
          );
916
917
    }
    else {
918
919
      Frx::RepoMan()->repository($source);
      $repos = Frx::RepoMan()->repositories;
920
      $r = $repos[$source];
davidmetzler's avatar
davidmetzler committed
921
      // Remove teh object from the data.
922
      unset($r['data']);
923
924
925
      $form_state['storage'] = array(
        'name' => $source,
        'title' => $r['title'],
davidmetzler's avatar
davidmetzler committed
926
        'path' => @$r['path'],
927
        'config' => $r,
928
929
930
931
932
933
      );

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

davidmetzler's avatar
davidmetzler committed
935
  $locked = !($adding || (@$config['source'] == 'user'));
936
937
938
939
940
941
942
943
944
  $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
945
  );
946
947
948
949

  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
davidmetzler's avatar
davidmetzler committed
950
    '#required' => TRUE,
951
952
953
954
955
956
957
958
959
960
961
    '#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
962
963
964
965
966
967
968
  $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'],
  );

969
970
971
  $form['path'] = array(
    '#type' => 'textfield',
    '#title' => t('Path'),
davidmetzler's avatar
davidmetzler committed
972
    '#required' => TRUE,
973
    '#disabled' => $locked,
974
975
976
977
    '#description' => t('Directory containing data block files.'),
    '#default_value' => @$data['path'],
  );

davidmetzler's avatar
davidmetzler committed
978
979
980
981
982
983
984
985
986
  $user_options = array(
    '' => 'None',
    'forena_current_user_id' => 'UID',
    'forena_current_user_name' => 'User name',
  );

  $form['user_callback'] = array(
    '#type' => 'select',
    '#title' =>  'Current user',
987
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
988
989
    '#description' => t('Can be refererenced as :current_user in each data block.'),
    '#options' => $user_options,
990
    '#default_value' => @$config['user callback'],
davidmetzler's avatar
davidmetzler committed
991
992
993
994
    '#disabled' => $locked,
  );


995
996
  // Access method list
  $access = array(
davidmetzler's avatar
davidmetzler committed
997
    'callback' => t('Use drupal permissions'),
metzlerd's avatar
metzlerd committed
998
    'block' => t('Match values provided by a data block.'),
999
1000
1001
1002
1003
  );

  $form['access_method'] = array(
    '#type' => 'select',
    '#options' => $access,
1004
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
1005
1006
    '#title' => t('Data security method'),
    '#default_value' => empty($config['access block']) ? 'callback' : 'block',
metzlerd's avatar
metzlerd committed
1007
    '#description' => t('Specify how the ACCESS defined for a data block is to be interpreted.'),
1008
1009
1010
    '#ajax' => array(
      'callback' => 'forena_access_info_callback',
      'wrapper' => 'access-details',
metzlerd's avatar
metzlerd committed
1011
  ),
1012
1013
1014
1015
1016
1017
  );

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

  switch (!empty($values['access_method']) ? $values['access_method'] : $form['access_method']['#default_value']) {
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
    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'],
      );
1039
1040
1041
1042
1043
1044
1045
1046
  }



  // Driver list
  $drivers = array(
    'FrxDrupal' => t('Drupal'),
    'FrxOracle' => t('Oracle Database'),
metzlerd's avatar
metzlerd committed
1047
    'FrxPDO' => t('PDO other than Drupal'),
1048
1049
1050
1051
1052
    'FrxPostgres' => t('Postgres Database'),
    'FrxMSSQL' => t('MSSQL Database'),
    'FrxFiles' => t('XML Files'),
  );

davidmetzler's avatar
davidmetzler committed
1053
  $form['data_provider'] = array(
1054
1055
1056
1057
1058
    '#type' => 'select',
    '#title' => t('Driver'),
    '#description' => t('Forena data connection type'),
    '#options' => $drivers,
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
1059
    '#default_value' => $config['data provider'],
1060
1061
1062
    '#ajax' => array(
      'callback' => 'forena_connection_info_callback',
      'wrapper' => 'conn-div',
metzlerd's avatar
metzlerd committed
1063
  ),
1064
1065
1066
1067
  );

  $form['connection'] = array(
    '#type' => 'fieldset',
davidmetzler's avatar
davidmetzler committed
1068
    '#tree' => TRUE,
1069
1070
1071
1072
    '#title' => 'Connection info',
   '#prefix' =>  '<div id="conn-div">',
   '#suffix' => '</div>',
  );
davidmetzler's avatar
davidmetzler committed
1073
  $data_provider = (!empty($form_state['values']['data_provider']) ? $form_state['values']['data_provider'] : $config['data provider']);
1074

davidmetzler's avatar
davidmetzler committed
1075
1076
1077
1078
1079
  // Common controls used in mulitple providers.
  $uri = array(
    '#type' => 'textfield',
    '#title' => t('uri'),
    '#descripton' => t('Connection string: see appropriate php documentation for more details.'),
1080
    '#default_value' => @$config['uri'],
davidmetzler's avatar
davidmetzler committed
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
    '#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
1094
  );
davidmetzler's avatar
davidmetzler committed
1095

davidmetzler's avatar
davidmetzler committed
1096
  switch ($data_provider) {
davidmetzler's avatar
davidmetzler committed
1097
    case 'FrxDrupal':
1098
1099
1100
1101
      $db_list = array_combine(array_keys($databases), array_keys($databases));
      $form['connection']['database'] = array(
        '#type' => 'select',
        '#title' => t('Database'),
1102
        '#disabled' => $locked,
1103
1104
        '#default_value' => @$config['database'],
        '#options' => $db_list,
davidmetzler's avatar