forena.admin.inc 54.6 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
  $output = '';
17
  $content = drupal_get_form('forena_sync_form');
18
  $sync_form = drupal_render($content);
19
  $links[] = array('href' => 'reports/add', 'title' => 'Create New Report' );
20
  $output .= theme('links',
21
22
23
24
    array(
      'links' => $links,
      'attributes' => array('class' => 'action-links'),
    )
metzlerd's avatar
metzlerd committed
25
  );
26
  // Add Data tables if it exists.
27
28
  $headers = array(t('category'), t('title'), t('name'), t('operation'));
  $result = Frx::File()->allReports();
29
  foreach ($result as $row) {
30
    $rpt = str_replace('/', '.', $row->name);
31
32
33
34
35
36
    if ($row->include) {
      $edit = l(t('Override'), 'reports/' . $rpt . '/edit');
    }
    else {
      $edit = l(t('Edit'), 'reports/' . $rpt . '/edit');
    }
metzlerd's avatar
metzlerd committed
37
    $clone = l(t('Clone'), 'reports/add/' . $rpt);
38
39
40
41
42
43
44
45
46
47
48
    // Determine the nature of the report delete link.
    if ($row->override) {
      $delete = l(t('Revert'), 'reports/' . $rpt . '/delete', array('query' => array('destination' => 'admin/structure/forena')));
    }
    else if (!$row->include) {
      $delete = l(t('Delete'), 'reports/' . $rpt . '/delete', array('query' => array('destination' => 'admin/structure/forena')));
    }
    else {
      $delete = '';
    }

49
50
    $title = l(t($row->cache['title']), 'reports/' . $rpt);
    $data[] = array($row->cache['category'], $title, $row->name, $edit . ' ' . $clone . ' ' . $delete);
51
  }
52
  $output .= '<div id="forena-reports-list">';
53
  $output .= theme('forena_data_table', array('header' => $headers, 'rows' => $data));
54
  $output .= '</div>';
55
  $output .= $sync_form;
56
57
58
  return $output;
}

59
/**
metzlerd's avatar
metzlerd committed
60
 * Remove the report from the database and file system.
61
62
 * @param string $report_name
 */
63
function forena_delete_report($report_name) {
64

65
  $filepath = $report_name . '.frx';
66
  $do = Frx::File()->delete($filepath);
67
68
}

metzlerd's avatar
metzlerd committed
69

70
71


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

93
  $element['format'][$name] = array(
metzlerd's avatar
metzlerd committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    '#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
109
  return $element['format'];
metzlerd's avatar
metzlerd committed
110
}
111

metzlerd's avatar
metzlerd committed
112
113


114
/**
115
116
117
 * Report syncronization form
 * @param $formid
 * @param $form_state
118
 */
119
function forena_sync_form($formid, &$form_state) {
120
121
122
123

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

128
129
  $form['sync'] = array(
    '#type' => 'submit',
130
    '#value' => t('Revert'),
131
132
    '#submit' => array('forena_settings_sync_submit'),
  );
133
134

  return $form;
135
136
137
138
139
140
141
142

}

/**
 * Forena admin settings form
 *
 */
function forena_settings() {
143
  $skins = Frx::File()->skins();
144
145
146

  $report_path = forena_report_path();

147

148
149
150
  $form['forena_report_repos'] = array(
    '#type' => 'textfield',
    '#title' => t('Report Repository'),
metzlerd's avatar
metzlerd committed
151
152
153
154
155
156
    '#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,
  );

157
158
  $form['forena_last_report_path'] = array(
    '#type' => 'value',
159
    '#value' => variable_get('forena_report_repos', '')
metzlerd's avatar
metzlerd committed
160
161
  );

162
163
164
165
166
167
168
169
170
171
172
173
174
  if (module_exists('forena_query')) {
      $form['forena_query_data_path'] = array(
        '#type' => 'textfield',
        '#title' => t('Custom Data Block Repository'),
        '#description' => t('Indicate the directory that you want to use to save custom created data blocks using
            the forena query builder tool.  These will override any module delivered data blocks.  This needs to
            be a directory that is writable by the web user but should not be browsable by the web.  It defaults to
            '),
        '#default_value' => Frx::DataFile()->dir,
      );

      $form['forena_last_query_data_path'] = array(
          '#type' => 'value',
175
          '#value' =>  variable_get('forena_query_data_path', '')
176
177
178
      );

  }
179

180
  $form['forena_input_format'] = forena_filter_element(variable_get('forena_input_format', filter_default_format()), 'forena_input_format');
181
  $form['forena_default_form'] = array(
182
    '#type' => 'select',
183
    '#title' => t('Default report skin'),
184
    '#options' => $skins,
185
    '#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
186
    . ' Skins are basically css and javascript libraries added to your report.'),
metzlerd's avatar
metzlerd committed
187
    '#default_value' => variable_get('forena_default_form', ''),
metzlerd's avatar
metzlerd committed
188
    );
metzlerd's avatar
metzlerd committed
189

metzlerd's avatar
metzlerd committed
190
191
    $form =  system_settings_form($form);
    return $form;
metzlerd's avatar
metzlerd committed
192

193
}
194
195

function forena_settings_validate($form, &$form_state) {
metzlerd's avatar
metzlerd committed
196
  $values = $form_state['values'];
197
  $path = $values['forena_report_repos'];
198
  if ($path != $values['forena_last_report_path']) {
199
200
201
    if (!file_exists($path)) {
      try {
        if (file_exists($path)) {
202
          drupal_set_message(t('Created directory %s', array('%s' => $path))) ;
203
204
        }
        mkdir($path);
205

206
207
208
209
      } catch (Exception $e) {
        forena_error(t('Unable to create report directory'), $e->getMessage());
      }
    }
metzlerd's avatar
metzlerd committed
210
  }
211
212
213
214
215
216
217
218
219
220
221
  if (!file_exists($path) || !is_writable($path)) {
    form_set_error('forena_report_repos', 'Report Directory must be writable by the web user');
  }
  if ($values['forena_query_data_path']) {
    $path = $values['forena_query_data_path'];
    if ($path != $values['forena_last_query_data_path']) {
      if (!file_exists($path)) {
        try {

          mkdir($path);
          if (file_exists($path)) {
222
            drupal_set_message(t('Created directory %s', array('%s' => $path))) ;
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
          }

        } catch (Exception $e) {
          forena_error(t('Unable to create data directory'), $e->getMessage());
        }
      }
    }
    if (!file_exists($path) || !is_writable($path)) {
      form_set_error('forena_query_data_path', 'Data Directory must be writable by the web user');
    }
  }


}


/**
 * Added submit handler to create directories and clear menu cache
 *
 * @param unknown_type $form
 * @param unknown_type $form_state
 */
function forena_settings_submit($form, &$form_state) {
246
}
metzlerd's avatar
metzlerd committed
247

248
function forena_settings_sync_submit($form, &$form_state) {
249
  forena_sync_reports($form_state['values']['sync_overwrite']);
250
}
251

252
function forena_format_form($formid, $form_state, $report_name) {
metzlerd's avatar
metzlerd committed
253
  $desc = Frx::Menu()->parseURL($report_name);
254
  $name = $desc['name'];
255

256
257
258
  $filename = $desc['filename'];
  $format = isset($desc['format']) ? $desc['format'] : '';
  if ($desc['exists']) {
259
    $r = Frx::Editor($name);
260
261
262
263
264
    drupal_set_title($r->title);
    $form = array();
    $frx_options = $r->getOptions();
    $report_form = @$frx_options['form'];

265
    $doclist = Frx::Menu()->doc_formats;
266
267
    $skins[''] = t('Use Default');
    $skins = array_merge(variable_get('forena_skins', array()), $skins);
268

metzlerd's avatar
metzlerd committed
269
270
271
272
    $form['report_name'] = array(
       '#type' => 'value',
       '#value' => $name,
    );
273

metzlerd's avatar
metzlerd committed
274
    $form['form'] = array(
275
      '#type' => 'select',
276
      '#title' => t('Skin'),
277
      '#options' => $skins,
metzlerd's avatar
metzlerd committed
278
      '#default_value' => $report_form,
metzlerd's avatar
metzlerd committed
279
      '#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
280
    );
281

metzlerd's avatar
metzlerd committed
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    //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
298
        if ($doc && array_search($value, $doclist)!==FALSE) {
metzlerd's avatar
metzlerd committed
299
          $default[$value] = $value;
300
        }
metzlerd's avatar
metzlerd committed
301
      }
302

metzlerd's avatar
metzlerd committed
303
304
305
306
307
308
309
      //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
      );
310

311
312
313
314
315
      $form['update'] = array(
        '#type' => 'submit',
        '#value' => 'Update',
      );

metzlerd's avatar
metzlerd committed
316
317
318
      $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Save',
319
        '#submit' => array('forena_format_form_submit', 'forena_save_submit'),
metzlerd's avatar
metzlerd committed
320
      );
321
322
323
324
325

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

metzlerd's avatar
metzlerd committed
328
    }
329
330
331
332
333
  }
  return $form;
}

function forena_format_form_submit($form, &$form_state) {
metzlerd's avatar
metzlerd committed
334
  $values = $form_state['values'];
335
336
  $name = $values['report_name'];

337
  $r = Frx::Editor();
338
339
340
341
342
343
344
345
  $options = array(
    'form' => $values['form']);
  $r->setOptions($options);


  // Doc gen settings.
  if (isset($form['docgen'])) {
    $docgen = array();
metzlerd's avatar
metzlerd committed
346
    if ($selected = array_filter(@$values['docgen']['docs'])) {
347
      if ($selected) foreach ($selected as $key => $value) {
metzlerd's avatar
metzlerd committed
348
        if ($value) $docgen[] = array('type' => $key);
349
350
351
352
353
      }
    }
    $r->setDocgen($docgen);
  }

354
  $r->update();
355
356

}
357

metzlerd's avatar
metzlerd committed
358
function forena_general_form($form, &$form_state, $report_name) {
metzlerd's avatar
metzlerd committed
359
  $name_in = $report_name;
metzlerd's avatar
metzlerd committed
360
  $desc = Frx::Menu()->parseURL($report_name);
metzlerd's avatar
metzlerd committed
361
362
363
  $name = $desc['name'];
  $filename = $desc['filename'];
  $format = @$desc['format'];
metzlerd's avatar
metzlerd committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  $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
379

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

metzlerd's avatar
metzlerd committed
386
387
388
389
  $form['visibility'] = array(
    '#type' => 'fieldset',
    '#title' => t('Visibility'),
  );
390

metzlerd's avatar
metzlerd committed
391
392
393
394
395
396
397
  $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
398

metzlerd's avatar
metzlerd committed
399
400
401
402
403
404
  $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
405

metzlerd's avatar
metzlerd committed
406
407
408
409
410
411
412
  $form['menu'] = array(
    '#type' => 'fieldset',
    '#title' => t('Menu'),
    '#tree' => TRUE,
    '#collapsible' => TRUE,
    '#collapsed' => empty($menu),
  );
413

metzlerd's avatar
metzlerd committed
414
415
416
417
418
419
  $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'],
  );
420

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

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

metzlerd's avatar
metzlerd committed
435
436
437
438
439
440
  $menu_options = array(
    'normal-item' => t('Normal'),
    'local-task' => t('Tab'),
    'default-local-taks' => t('Default Tab'),
    'callback' => t('Callback'),
  );
441

metzlerd's avatar
metzlerd committed
442
443
444
445
446
447
  $form['menu']['type'] = array(
    '#type' => 'select',
    '#title' => 'Type of menu to create',
    '#options' => $menu_options,
    '#default_value' => @$menu['type'],
  );
448

metzlerd's avatar
metzlerd committed
449
450
451
452
453
454
455
  $form['cache'] = array(
    '#type' => 'fieldset',
    '#title' => t('Cache'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#tree' => TRUE,
  );
456

metzlerd's avatar
metzlerd committed
457
458
459
460
461
462
  $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'],
  );
463

metzlerd's avatar
metzlerd committed
464
465
466
467
468
  $form['cache']['per_user'] = array(
    '#type' => 'checkbox',
    '#title' => t('Per User'),
    '#default_value' => @$cache['per_user'],
  );
469

metzlerd's avatar
metzlerd committed
470
471
472
473
474
  $form['cache']['per_doctype'] = array(
    '#type' => 'checkbox',
    '#title' => t('Per Document Type'),
    '#default_value' => @$cache['per_doctype'],
  );
475

metzlerd's avatar
metzlerd committed
476
477
478
479
  $form['update'] = array(
    '#type' => 'submit',
    '#value' => 'Update',
  );
480

metzlerd's avatar
metzlerd committed
481
482
483
484
485
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Save',
    '#submit' => array('forena_general_form_submit', 'forena_save_submit'),
  );
486

metzlerd's avatar
metzlerd committed
487
488
489
490
491
  $form['cancel'] = array(
    '#type' => 'submit',
    '#value' => 'Cancel',
    '#submit' => array('forena_save_cancel'),
  );
492

metzlerd's avatar
metzlerd committed
493
  return $form;
494
}
495

metzlerd's avatar
metzlerd committed
496
function forena_general_form_validate($form, &$form_state) {
497
  $values = $form_state['values'];
metzlerd's avatar
metzlerd committed
498
499
500
501
502
  if ($values['menu']['path']) {
    if (!valid_url(str_replace(':', '', $values['menu']['path']), FALSE)) {
      form_set_error('menu][path', t('Invalid Path'));
    }
  }
503
504
505
506
507
508
509
510
  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'));
  }
511
}
512

metzlerd's avatar
metzlerd committed
513
function forena_general_form_submit($form, &$form_state) {
514
515
  $values = $form_state['values'];
  $report_name = $values['report_name'];
516
  $r = Frx::Editor();
metzlerd's avatar
metzlerd committed
517

518
519
520
521
522
523
524
525
  // 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
526
527
528
529
530
  $menu = $r->getMenu();
  if ($values['menu']!= $menu) {
    $r->setMenu($values['menu']);
    $rebuild_menu = TRUE;
  }
531

532
533
534
535
536
  $cache = $r->cache;
  if ($values['cache']!=$cache) {
    $r->setCache($values['cache']);
  }

metzlerd's avatar
metzlerd committed
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
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
  $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();


651
652
  // Body
  $r->setBody($values['body']['value']);
653
654
  // CSS
  $r->setStyle($values['css']);
655
  // If there are no frx attributes in the body then replace them with the old values.
656
  $frx_nodes = $r->simplexml->xpath('body//*[@frx:*]');
657
658
659
660
  if (!$frx_nodes) {
    $r->save_attributes_by_id($values['attributes']);
  }

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

664
665
666
}


667
668
669
670
671
/**
 * Handle delete buttons from edit forms.
 * @return unknown_type
 */
function forena_edit_delete_submit($form, &$form_state) {
metzlerd's avatar
metzlerd committed
672
  $link = 'reports/' . $form_state['values']['name_in'] ;
673
674
675
676
677
678
679
680
681
  $destination = '';
  if (isset($_REQUEST['destination'])) {
    $destination = drupal_get_destination();
    unset($_REQUEST['destination']);
  }
  $form_state['redirect'] = array('path' => $link . '/delete', 'query' => array('destination' => $destination));
}


682
function forena_create_trans_form($formid, $form_state, $report_name) {
683
684
685
  $name = '';
  $filename = '';
  $format = '';
metzlerd's avatar
metzlerd committed
686
  $desc = Frx::Menu()->parseURL($report_name);
687
688
689
690
  $name = $desc['name'];
  $filename = $desc['filename'];
  $base_name = $desc['base_name'];
  $format = @$desc['format'];
691
692
  $form = array();
  global $language;
693
  $languages = language_list();
694
695
  //determine if this is an add new report request

696
  $r = Frx::Editor($name);
697
698
699
  $title = (string)$r->title;
  $lang = @$_GET['language'];
  if ($lang) {
metzlerd's avatar
metzlerd committed
700
    $language = $languages[$lang];
701
702
703
704
705
706
707
708
709
  }
  $form['base_name'] = array(
    '#type' => 'value',
    '#value' => $base_name
  );
  $form['report_name'] = array(
    '#type' => 'value',
    '#value' => $name,
  );
710

metzlerd's avatar
metzlerd committed
711
  foreach ($languages as $key => $obj) {
712
    $languages[$key] = $obj->native;
713
  }
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
  $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
731
    '#required' => TRUE,
732
733
734
735
736
737
738
739
740
  );


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

741
742
743
744
}

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

metzlerd's avatar
metzlerd committed
748
  $desc = Frx::Menu()->parseURL($new_name);
749
750
  $filename = $desc['filename'];
  $report_name = $desc['name'];
751

David Metzler's avatar
David Metzler committed
752
  $r = Frx::Editor($base_name);
753
754
755

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

metzlerd's avatar
metzlerd committed
757
  //determine redirection.
758

759
  if (Frx::File()->exists($filename, FALSE)) {
metzlerd's avatar
metzlerd committed
760
    drupal_set_message(t('Report %s already exists', array('%s' => $new_name)), 'error');
761
    return;
metzlerd's avatar
metzlerd committed
762
  }
David Metzler's avatar
David Metzler committed
763
764
765
766
767
  else {
    $r->rename($new_name);
    drupal_set_message(t('Translation,  %s has been created. Switch languages to translate.', array('%s' => $values['title'])));
    $form_state['redirect']= array( $desc['i_link'] . '/edit/layout');
  }
metzlerd's avatar
metzlerd committed
768

769
  //if this is a new report then redirect to data blocks
770
}
771

772
773


774
775
776
777
/*
 * administer the settings for document format options
 */
function forena_doc_formats_settings() {
778
  // Invoke doc_type hook to see which document types are there.
779
  $supported_doctypes = Frx::documentTypes();
780

781
782
  $form['forena_doc_formats'] = array(
    '#type' => 'checkboxes',
783
    '#title' => t('Allowed Document Formats'),
784
785
786
787
    '#default_value' => variable_get('forena_doc_formats', $supported_doctypes),
    '#description' => t('check your desired document format'),
    '#options' => $supported_doctypes,
  );
788
789
790
791

  $form['forena_doc_defaults'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Default Document Formats'),
792
    '#default_value' => variable_get('forena_doc_defaults', array()),
793
794
795
796
    '#description' => t('check your desired document format'),
    '#options' => $supported_doctypes,
  );

797
798
799
  $form['forena_email_override'] = array(
    '#type' => 'checkbox',
    '#title' => 'Run email merges in test mode' ,
metzlerd's avatar
metzlerd committed
800
    '#default_value' => variable_get('forena_email_override', FALSE),
801
802
    '#description' => t('When this box is checked emails are sent to the currently logged in user.  Useful for testing environments.'),
  );
803
  $form['forena_email_input_format'] = forena_filter_element(variable_get('forena_email_input_format', 'full_text'), 'forena_email_input_format');
804
  $form['forena_email_input_format']['#title'] = t('Email Input Format');
805

806
807
  return system_settings_form($form);
}
808

809
810
811
812
/*
 * administer the settings for document format options
 */
function forena_data_settings() {
813
  $repos = Frx::RepoMan()->repositories;
814
  $r_list = array();
metzlerd's avatar
metzlerd committed
815
816
  $headers = array(t('Name'), t('Description'), t('Path'), t('Operation'));
  foreach ($repos as $name => $r) {
817
    $r_list[] = array(
metzlerd's avatar
metzlerd committed
818
819
820
821
    $name,
    $r['title'],
    $r['path'],
    l(t('configure'), 'admin/config/content/forena/data/configure/' . $name)
822
823
824
825
    );

  }

metzlerd's avatar
metzlerd committed
826
827
  $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' => ''));
828
829
830
831
  return $output;
}

function forena_data_settings_edit($form, &$form_state, $source=-1) {
832
  global $databases;
833
834
835
836
837
838
839
840
841
  $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
842
          'data provider' => 'FrxDrupal',
843
          'database' => 'default',
844
845
          'access callback' => 'user_access',
          'user callback' => 'forena_current_user_id'
metzlerd's avatar
metzlerd committed
846
847
          ),
          );
848
849
    }
    else {
850
851
      Frx::RepoMan()->repository($source);
      $repos = Frx::RepoMan()->repositories;
852
      $r = $repos[$source];
davidmetzler's avatar
davidmetzler committed
853
      // Remove teh object from the data.
854
      unset($r['data']);
855
856
857
      $form_state['storage'] = array(
        'name' => $source,
        'title' => $r['title'],
davidmetzler's avatar
davidmetzler committed
858
        'path' => @$r['path'],
859
        'config' => $r,
860
861
862
863
864
865
      );

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

davidmetzler's avatar
davidmetzler committed
867
  $locked = !($adding || (@$config['source'] == 'user'));
868
869
870
871
872
873
874
875
876
  $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
877
  );
878
879
880
881

  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
davidmetzler's avatar
davidmetzler committed
882
    '#required' => TRUE,
883
884
885
886
887
888
889
890
891
892
893
    '#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
894
895
896
897
898
899
900
  $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'],
  );

901
902
903
  $form['path'] = array(
    '#type' => 'textfield',
    '#title' => t('Path'),
davidmetzler's avatar
davidmetzler committed
904
    '#required' => TRUE,
905
    '#disabled' => $locked,
906
907
908
909
    '#description' => t('Directory containing data block files.'),
    '#default_value' => @$data['path'],
  );

davidmetzler's avatar
davidmetzler committed
910
911
912
913
914
915
916
917
918
  $user_options = array(
    '' => 'None',
    'forena_current_user_id' => 'UID',
    'forena_current_user_name' => 'User name',
  );

  $form['user_callback'] = array(
    '#type' => 'select',
    '#title' =>  'Current user',
919
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
920
921
    '#description' => t('Can be refererenced as :current_user in each data block.'),
    '#options' => $user_options,
922
    '#default_value' => @$config['user callback'],
davidmetzler's avatar
davidmetzler committed
923
924
925
926
    '#disabled' => $locked,
  );


927
928
  // Access method list
  $access = array(
davidmetzler's avatar
davidmetzler committed
929
    'callback' => t('Use drupal permissions'),
metzlerd's avatar
metzlerd committed
930
    'block' => t('Match values provided by a data block.'),
931
932
933
934
935
  );

  $form['access_method'] = array(
    '#type' => 'select',
    '#options' => $access,
936
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
937
938
    '#title' => t('Data security method'),
    '#default_value' => empty($config['access block']) ? 'callback' : 'block',
metzlerd's avatar
metzlerd committed
939
    '#description' => t('Specify how the ACCESS defined for a data block is to be interpreted.'),
940
941
942
    '#ajax' => array(
      'callback' => 'forena_access_info_callback',
      'wrapper' => 'access-details',
metzlerd's avatar
metzlerd committed
943
  ),
944
945
946
947
948
949
  );

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

  switch (!empty($values['access_method']) ? $values['access_method'] : $form['access_method']['#default_value']) {
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
    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'],
      );
971
972
973
974
975
976
977
978
  }



  // Driver list
  $drivers = array(
    'FrxDrupal' => t('Drupal'),
    'FrxOracle' => t('Oracle Database'),
metzlerd's avatar
metzlerd committed
979
    'FrxPDO' => t('PDO other than Drupal'),
980
981
982
983
984
    'FrxPostgres' => t('Postgres Database'),
    'FrxMSSQL' => t('MSSQL Database'),
    'FrxFiles' => t('XML Files'),
  );

davidmetzler's avatar
davidmetzler committed
985
  $form['data_provider'] = array(
986
987
988
989
990
    '#type' => 'select',
    '#title' => t('Driver'),
    '#description' => t('Forena data connection type'),
    '#options' => $drivers,
    '#disabled' => $locked,
davidmetzler's avatar
davidmetzler committed
991
    '#default_value' => $config['data provider'],
992
993
994
    '#ajax' => array(
      'callback' => 'forena_connection_info_callback',
      'wrapper' => 'conn-div',
metzlerd's avatar
metzlerd committed
995
  ),
996
997
998
999
  );

  $form['connection'] = array(
    '#type' => 'fieldset',
davidmetzler's avatar
davidmetzler committed
1000
    '#tree' => TRUE,
1001
1002
1003
1004
    '#title' => 'Connection info',
   '#prefix' =>  '<div id="conn-div">',
   '#suffix' => '</div>',
  );
davidmetzler's avatar
davidmetzler committed
1005
  $data_provider = (!empty($form_state['values']['data_provider']) ? $form_state['values']['data_provider'] : $config['data provider']);
1006

davidmetzler's avatar
davidmetzler committed
1007
1008
1009
1010
1011
  // Common controls used in mulitple providers.
  $uri = array(
    '#type' => 'textfield',
    '#title' => t('uri'),
    '#descripton' => t('Connection string: see appropriate php documentation for more details.'),
1012
    '#default_value' => @$config['uri'],
davidmetzler's avatar
davidmetzler committed
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
    '#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
1026
  );
davidmetzler's avatar
davidmetzler committed
1027

davidmetzler's avatar
davidmetzler committed
1028
  switch ($data_provider) {
davidmetzler's avatar
davidmetzler committed
1029
    case 'FrxDrupal':
1030
1031
1032
1033
      $db_list = array_combine(array_keys($databases), array_keys($databases));
      $form['connection']['database'] = array(
        '#type' => 'select',
        '#title' => t('Database'),
1034
        '#disabled' => $locked,
1035
1036
        '#default_value' => @$config['database'],
        '#options' => $db_list,
davidmetzler's avatar
davidmetzler committed
1037
1038
1039
1040
        '#markup' => 'Determined by Drupal settings.php file',
      );
      break;
    case 'FrxMSSQL':
1041
1042
1043
      $form['connection']['uri'] = $uri;
      $form['connection']['user'] = $user;
      $form['connection']['new_password'] = $password;
1044
1045
1046
1047
1048
1049
1050
      $form['connection']['database'] = array(
        '#type' => 'textfield',
        '#disabled' => $locked,
        '#title' => t('Database'),
        '#default_value' => $config['database'],
        '#required' => TRUE,
      );
davidmetzler's avatar
davidmetzler committed
1051
1052
1053
1054
1055
1056
1057
      $form['connection']['mssql_xml'] = array(
        '#type' => 'checkbox',
        '#disabled' => $locked,
        '#title' => t('Microsoft SQL native XML'),
        '#description' => t('Use for XML auto queries to generate XML.'),
        '#default_value' => $config['mssql_xml'],
      );
metzlerd's avatar
metzlerd committed
1058
      break;
davidmetzler's avatar
davidmetzler committed
1059
    case 'FrxOracle':
1060
      $form['connection']['uri'] = $uri;
davidmetzler's avatar
davidmetzler committed
1061
1062
      $form['connection']['user'] = $user;
      $form['connection']['new_password'] = $password;
1063
1064
1065
1066
1067
1068
1069
1070
      $form['connection']['character_set'] = array(
        '#type' => 'textfield',
        '#title' => t('Character Set'),
        '#disabled' => $locked,
        '#description' => t('Leave blank for default character set'),
        '#default_value' => @$config['character_set'],

      );
davidmetzler's avatar
davidmetzler committed
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
      $form['connection']['oracle_xml'] = array(
        '#type' => 'checkbox',
        '#title' => t('Oracle native XML'),
        '#disabled' => $locked,
        '#description' => t('Use the function provided with Forena to generate XML.  Requires installing a function into the database'),
        '#default_value' => $config['oracle_xml'],
      );
      break;
    case 'FrxPDO':
      $form['connection']['uri'] = $uri;
metzlerd's avatar
metzlerd committed
1081
1082
1083
      $form['connection']['user'] = $user;
      $form['connection']['new_password'] = $password;
      break;
davidmetzler's avatar
davidmetzler committed
1084
    case 'FrxPostgres':
1085
1086
      $form['connection']['uri'] = $uri;
      $form['connection']['new_password'] = $password;
davidmetzler's avatar
davidmetzler committed
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
      $form['connection']['postgres_xml'] = array(
        '#type' => 'checkbox',
        '#title' => t('Postgres native XML'),
        '#disabled' => $locked,
        '#default_value' => @$config['postgres_xml'],
        '#description' => t('Use Postgres native XML support.  Requires Posgres 8.3 or better'),
      );

    default:
      $form['connection']['uri'] = $uri;
1097
1098
1099
1100
1101
  }

  $form['save'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
1102
    '#submit' => array('forena_data_settings_save'),
davidmetzler's avatar
davidmetzler committed
1103
1104
  );

1105

davidmetzler's avatar
davidmetzler committed
1106
1107
1108
1109
  $form['delete'] = array(
    "#type" => 'submit',
    '#value' => t('Delete'),
    '#submit' => array('forena_data_settings_delete'),
1110
1111
1112
1113
1114
  );

  return $form;
}

1115
1116


davidmetzler's avatar
davidmetzler committed
1117
1118
1119
1120
1121
/**
 * Submit handler to cause save events to happen.
 * Enter description here ...
 */
function forena_data_settings_save($form, &$form_state) {
1122
1123
  $values = $form_state['values'];
  $name = $values['name'];
davidmetzler's avatar
davidmetzler committed
1124
  $config = $form_state['storage']['config'];
davidmetzler's avatar
davidmetzler committed
1125
1126
1127
  $config['path'] = @$values['path'];
  $config['data provider'] = $values['data_provider'];
  $config['user callback'] = $values['user_callback'];
davidmetzler's avatar
davidmetzler committed
1128
1129
  $config['debug'] = $values['debug'];
  if (@$values['connection']['new_password']) {
1130
    $values['connection']['password'] = $values['connection']['new_password'];
davidmetzler's avatar
davidmetzler committed
1131
1132
  }
  if (isset($values['connection']['new_password'])) unset($values['connection']['new_password']);
1133
  if (is_array(@$values['connection'])) $config = array_merge($config, @$values['connection']);
metzlerd's avatar
metzlerd committed
1134
  if ($values['access_method']=='callback') {
1135
    $config['access callback'] = empty($values['access_callback']) ? 'user_access' : $values['access_callback'];
metzlerd's avatar
metzlerd committed
1136
    if (isset($config['access block'])) unset($config['access block']);
davidmetzler's avatar
davidmetzler committed
1137
1138
  }
  else {
1139
    $config['access block'] = $values['access_block'];
davidmetzler's avatar
davidmetzler committed
1140
1141
  }
  $config_str = serialize($config);
davidmetzler's avatar
davidmetzler committed
1142
  $result = db_query('SELECT * FROM {forena_repositories} WHERE repository = :name', array(':name' => $name));
davidmetzler's avatar
davidmetzler committed
1143
1144

  if ($result) drupal_set_message(t('Data connection settings saved'));
davidmetzler's avatar
davidmetzler committed
1145
1146
  if ($repos = $result->fetchObject()) {
    db_update('forena_repositories')