Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
form_email_edit_fns.inc
1 <?php
18 require_once dirname(__FILE__).'/../form/form_edit_fns.inc';
19 require_once SQ_FUDGE_PATH.'/datetime_field/datetime_field.inc';
20 require_once SQ_FUDGE_PATH.'/general/datetime.inc';
21 require_once SQ_FUDGE_PATH.'/db_extras/db_extras.inc';
22 
35 {
36 
37 
43  {
44  $this->Form_Edit_Fns();
45 
46  }//end constructor
47 
48 
49 //-- SUBMISSIONS --//
50 
51 
62  function paintSubmissionDateRange(&$asset, &$o, $prefix)
63  {
64  $parameters = Array(
65  'min' => '2003-01-01 00:00:00',
66  'max' => ts_iso8601(time()),
67  'allow_circa' => '0',
68  'show' => Array('y', 'm', 'd'),
69  'null' => Array(),
70  'style' => Array(
71  'y' => 's',
72  'm' => 's',
73  'd' => 's',
74  ),
75  );
76 
77  $parameters['print_format'] = 'j M Y';
78 
79  $from_value = isset($_POST[$prefix.'_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_fromvalue']['m'],$_POST[$prefix.'_fromvalue']['d'],$_POST[$prefix.'_fromvalue']['y'])) : date('Y-m-d',time()-7*86400).' --:--:--';
80  $to_value = isset($_POST[$prefix.'_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_tovalue']['m'],$_POST[$prefix.'_tovalue']['d'],$_POST[$prefix.'_tovalue']['y'])) : date('Y-m-d').' --:--:--';
81 
82  $from = new Datetime_Field($prefix.'_from', $from_value, $parameters);
83  $to = new Datetime_Field($prefix.'_to', $to_value, $parameters);
84 
85  $from->printField();
86  echo ' '.translate('to').' ';
87  $to->printField();
88 
89  return TRUE;
90 
91  }//end paintSubmissionDateRange()
92 
93 
104  function paintSubmissionCount(&$asset, &$o, $prefix)
105  {
106  $num_per_page = array_get_index($_REQUEST, $prefix.'_per_page', 50);
107  if ($num_per_page < 1) $num_per_page = 50;
108 
109  text_box($prefix.'_per_page', $num_per_page, 3);
110 
111  }//end paintSubmissionCount()
112 
113 
124  function paintSubmissionList(&$asset, &$o, $prefix)
125  {
126  $write_access = $asset->writeAccess('links');
127  $expand_list = isset($_POST[$prefix.'_expand']) ? $_POST[$prefix.'_expand'] : Array();
128  $num_subs = 0;
129 
130  // grab the number of assets per page, defaulting to 50 at a time
131  $num_per_page = array_get_index($_REQUEST, $prefix.'_per_page', 50);
132  if ($num_per_page < 1) $num_per_page = 50;
133 
134  $from_value = isset($_POST[$prefix.'_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_fromvalue']['m'],$_POST[$prefix.'_fromvalue']['d'],$_POST[$prefix.'_fromvalue']['y'])) : date('Y-m-d',time()-7*86400).' --:--:--';
135  $to_value = isset($_POST[$prefix.'_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_tovalue']['m'],$_POST[$prefix.'_tovalue']['d'],$_POST[$prefix.'_tovalue']['y'])) : date('Y-m-d').' --:--:--';
136 
137  $from_value = iso8601_date_component($from_value).' 00:00:00';
138  $to_value = iso8601_date_component($to_value).' 23:59:59';
139 
140  // convert the ISO times to time stamps but manually because we can't be sure
141  // about the h:m:s section of the above times
142  $from_ts = mktime(0,0,0,$from_value[1],$from_value[2],$from_value[0]);
143  $to_ts = mktime(23,59,59,$to_value[1],$to_value[2],$to_value[0]);
144 
145  $sql = 'SELECT
146  a.assetid, a.created_userid, v.custom_val AS submitted
147  FROM
148  ('.SQ_TABLE_RUNNING_PREFIX.'ast a
149  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_typ_inhd i ON a.type_code = i.type_code)
150  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_lnk l ON l.minorid = a.assetid
151  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_attr_val v ON v.assetid = a.assetid
152  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_attr n ON n.attrid = v.attrid';
153 
154  $count_sql = 'SELECT
155  count(*)
156  FROM
157  ('.SQ_TABLE_RUNNING_PREFIX.'ast a
158  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_typ_inhd i ON a.type_code = i.type_code)
159  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_lnk l ON l.minorid = a.assetid
160  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_attr_val v ON v.assetid = a.assetid
161  JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_attr n ON n.attrid = v.attrid';
162 
163  $sub_folder = $asset->getSubmissionsFolder();
164 
165  $db = MatrixDAL::getDb();
166  $where = 'l.majorid IN (:assetid, :subfolder_assetid)
167  AND i.inhd_type_code = :inhd_type_code
168  AND n.name = :name AND v.contextid = :context';
169  if (MatrixDAL::getDbType() == 'oci') {
170  $where .= ' AND TO_CHAR(DBMS_LOB.SUBSTR(v.custom_val, 30, 1)) > :from_date AND TO_CHAR(DBMS_LOB.SUBSTR(v.custom_val, 30, 1)) < :to_date';
171  $order = ' ORDER BY TO_CHAR(DBMS_LOB.SUBSTR(v.custom_val, 30, 1)) DESC';
172  } else {
173  $where .= ' AND v.custom_val BETWEEN :from_date AND :to_date';
174  $order = ' ORDER BY v.custom_val DESC';
175  }//end if
176 
177  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'a');
178  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'i');
179  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'n');
180  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'v');
181  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'l');
182 
183  // grab the number of assets
184 
185  try {
186  $query = MatrixDAL::preparePdoQuery($count_sql.$where);
187  MatrixDAL::bindValueToPdo($query, 'assetid', $asset->id);
188  MatrixDAL::bindValueToPdo($query, 'subfolder_assetid', $sub_folder->id);
189  MatrixDAL::bindValueToPdo($query, 'inhd_type_code', 'form_submission');
190  MatrixDAL::bindValueToPdo($query, 'name', 'submitted');
191  MatrixDAL::bindValueToPdo($query, 'context', $GLOBALS['SQ_SYSTEM']->getContextId());
192  MatrixDAL::bindValueToPdo($query, 'from_date', $from_value);
193  MatrixDAL::bindValueToPdo($query, 'to_date', $to_value);
194  $asset_count = MatrixDAL::executePdoOne($query);
195  } catch (Exception $e) {
196  throw new Exception('Unable to get the number of assets due to database error: '.$e->getMessage());
197  }
198 
199  $num_pages = ceil($asset_count / $num_per_page);
200  $page_num = array_get_index($_POST, $prefix.'_submissions_page', 1);
201  $page_num = max($page_num, 1);
202  $page_num = min($page_num, $num_pages);
203 
204  $submission_offset = ($page_num - 1) * $num_per_page;
205 
206  $sql = $sql.$where.$order;
207  require_once SQ_FUDGE_PATH.'/db_extras/db_extras.inc';
208  $sql = db_extras_modify_limit_clause($sql, MatrixDAL::getDbType(), $num_per_page, $submission_offset);
209 
210  if ($asset_count == 0) {
211  ?><p><i><?php echo translate('cms_form_no_submissions_during_period') ?></i></p><?php
212  } else {
213  if ($num_pages == 1) {
214  $page_tag = translate('page_number', $page_num, $num_pages);
215  } else {
216  $page_tag = translate('page_number_with_pager', $page_num, $num_pages, $prefix.'_submissions_page');
217  }
218  $asset_count_tag = translate('item_range', ($page_num - 1) * $num_per_page + 1, min($asset_count, $page_num * $num_per_page), $asset_count, strtolower(translate('submissions')));
219 
220  $links = Array(
221  'first' => '&lt;&lt;',
222  'previous' => '&lt;',
223  'page' => $page_tag,
224  'next' => '&gt;',
225  'last' => '&gt;&gt;',
226  );
227 
228  if ($page_num > 1) {
229  $links['first'] = '<a title="'.translate('pagination_go_to_first').'" style="text-decoration: none; color: #fff" href="#" onClick="return sq_pager_jump(\''.$prefix.'_submissions_page\', 1)">'.$links['first'].'</a>';
230  $links['previous'] = '<a title="'.translate('pagination_go_to_previous').'" style="text-decoration: none; color: #fff" href="#" onClick="return sq_pager_jump(\''.$prefix.'_submissions_page\', '.($page_num - 1).')">'.$links['previous'].'</a>';
231  } else {
232  $links['first'] = '<span title="'.translate('pagination_cannot_go_further_back').'." style="color: #333">'.$links['first'].'</span>';
233  $links['previous'] = '<span title="'.translate('pagination_cannot_go_further_back').'." style="color: #333">'.$links['previous'].'</span>';
234  }
235 
236  if ($page_num < $num_pages) {
237  $links['last'] = '<a title="'.translate('pagination_go_to_last').'" style="text-decoration: none; color: #fff" href="#" onClick="return sq_pager_jump(\''.$prefix.'_submissions_page\', '.$num_pages.')">'.$links['last'].'</a>';
238  $links['next'] = '<a title="'.translate('pagination_go_to_next').'" style="text-decoration: none; color: #fff" href="#" onClick="return sq_pager_jump(\''.$prefix.'_submissions_page\', '.($page_num + 1).')">'.$links['next'].'</a>';
239  } else {
240  $links['last'] = '<span title="'.translate('pagination_cannot_go_further_forward').'." style="color: #333">'.$links['last'].'</span>';
241  $links['next'] = '<span title="'.translate('pagination_cannot_go_further_forward').'." style="color: #333">'.$links['next'].'</span>';
242  }
243 
244  hidden_field($prefix.'_submissions_page', $page_num); ?>
245 
246  <style type="text/css">
247  td.sq-form-sub {
248  padding-top: 0px;
249  }
250  .sq-form-sub table.sq-backend-table {
251  border-top: 0px;
252  margin: 0 8px 8px 8px;
253  }
254  .sq-form-sub table.sq-backend-table th {
255  font-weight: normal;
256  text-decoration: italic;
257  }
258  table.sq-backend-table tr td.sq-form-sub-header {
259  background-color: #666;
260  color: #fff;
261  font-size: 11px;
262  }
263  </style>
264  <script type="text/javascript"><!--
265  function sq_set_check_all(form, prefix, value) {
266  set_els = form.elements[prefix];
267 
268  if (set_els.length) {
269  for (k = 0; k < set_els.length; k++) {
270  set_els[k].checked = value;
271  }
272  } else {
273  set_els.checked = value;
274  }
275  }
276 
277  function sq_test_check_all(form, prefix, set_el) {
278  test_els = form.elements[prefix];
279  set_el = form.elements[set_el];
280 
281  if (test_els.length) {
282  test = true;
283  for (k = 0; k < test_els.length; k++) {
284  if (!test_els[k].checked) {
285  test = false;
286  break;
287  }
288  }
289  } else {
290  test = test_els.checked;
291  }
292 
293  set_el.checked = test;
294  }
295  //--></script>
296  <table class="sq-backend-table">
297  <tr>
298  <td class="sq-backend-table-header-header" colspan="2"><?php echo implode(' &nbsp; &nbsp; ', $links) ?></td>
299  <td class="sq-backend-table-header-header" colspan="<?php echo ($write_access === TRUE) ? 4 : 3 ?>" style="text-align: right; font-weight: normal"><?php echo $asset_count_tag; ?></span></td>
300  </tr>
301  <!-- <tr>
302  <td class="sq-form-sub-header" colspan="2"><b><?php
303  hidden_field($prefix.'_submission_offset', $submission_offset);
304  if ($submission_offset > 0) {
305  ?><a title="<?php echo translate('cms_form_submissions_go_to_first') ?>" style="text-decoration: none; color: #fff" href="#" onClick="Javascript: set_hidden_field('<?php echo $prefix ?>_submission_offset', '0'); set_hidden_field('process_form', '0'); submit_form(); return false;"><?php
306  } else {
307  ?><span title="<?php echo translate('cms_form_cannot_go_further_back') ?>" style="color: #333"><?php
308  }
309  ?>
310  &lt;&lt;
311  <?php
312  if ($submission_offset > 0) {
313  ?></a><?php
314  } else {
315  ?></span><?php
316  }
317  ?> &nbsp; &nbsp; <?php
318  if ($submission_offset > 0) {
319  ?><a title="<?php echo translate('cms_form_submissions_go_to_previous') ?>" style="text-decoration: none; color: #fff" href="#" onClick="Javascript: set_hidden_field('<?php echo $prefix ?>_submission_offset', '<?php echo $submission_offset - $num_per_page; ?>'); set_hidden_field('process_form', '0'); submit_form(); return false;"><?php
320  } else {
321  ?><span title="<?php echo translate('cms_form_cannot_go_further_back') ?>" style="color: #333"><?php
322  }
323  ?>
324  &lt;
325  <?php
326  if ($submission_offset > 0) {
327  ?></a><?php
328  } else {
329  ?></span><?php
330  }
331  ?>
332  &nbsp; &nbsp; <?php echo translate('page_number', round(($submission_offset + $num_per_page) / $num_per_page), ceil($asset_count / $num_per_page)); ?> &nbsp; &nbsp;
333  <?php
334  if (($submission_offset + $num_per_page) < $asset_count) {
335  ?><a title="<?php echo translate('cms_form_submissions_go_to_next') ?>" style="text-decoration: none; color: #fff" href="#" onClick="Javascript: set_hidden_field('<?php echo $prefix ?>_submission_offset', '<?php echo $submission_offset + $num_per_page; ?>'); set_hidden_field('process_form', '0'); submit_form(); return false;"><?php
336  } else {
337  ?><span title="<?php echo translate('cms_form_cannot_go_further_forward') ?>" style="color: #333"><?php
338  }
339  ?>
340  &gt;
341  <?php
342  if (($submission_offset + $num_per_page) < $asset_count) {
343  ?></a><?php
344  } else {
345  ?></span><?php
346  }
347  ?> &nbsp; &nbsp; <?php
348  if (($submission_offset + $num_per_page) < $asset_count) {
349  ?><a title="<?php echo translate('cms_form_submissions_go_to_last') ?>" style="text-decoration: none; color: #fff" href="#" onClick="Javascript: set_hidden_field('<?php echo $prefix ?>_submission_offset', '<?php echo ($num_pages - 1) * $num_per_page; ?>'); set_hidden_field('process_form', '0'); submit_form(); return false;"><?php
350  } else {
351  ?><span title="<?php echo translate('cms_form_cannot_go_further_forward') ?>" style="color: #333"><?php
352  }
353  ?>
354  &gt;&gt;
355  <?php
356  if (($submission_offset + $num_per_page) < $asset_count) {
357  ?></a><?php
358  } else {
359  ?></span><?php
360  }
361  ?></b>
362  </td>
363  <td class="sq-form-sub-header" colspan="4" align="right"><?php echo translate('cms_form_submissions_during_period', $submission_offset + 1, min($asset_count, $submission_offset + $num_per_page), $asset_count) ?>
364  </td>
365  </tr> -->
366  <tr>
367  <th>
368  <?php echo translate('asset_id') ?>
369  </th>
370  <th>
371  <?php echo translate('submission_time') ?>
372  </th>
373  <th>
374  <?php echo translate('user') ?>
375  </th>
376  <th>
377  <input type="checkbox" name="<?php echo $prefix ?>_expand_all" value="" onclick="sq_set_check_all(this.form, '<?php echo $prefix ?>_expand[]', this.checked);"> <?php echo translate('expand_question') ?>
378  </th>
379  <?php
380  if ($write_access) {
381  ?>
382  <th>
383  <input type="checkbox" name="<?php echo $prefix ?>_delete_all" value="" onclick="sq_set_check_all(this.form, '<?php echo $prefix ?>_delete[]', this.checked);"> <?php echo translate('delete_question') ?>
384  </th>
385  <?php
386  }
387  ?>
388  <th>&nbsp;</th>
389  </tr>
390  <?php
391 
392  try {
393  $query = MatrixDAL::preparePdoQuery($sql);
394  MatrixDAL::bindValueToPdo($query, 'assetid', $asset->id);
395  MatrixDAL::bindValueToPdo($query, 'subfolder_assetid', $sub_folder->id);
396  MatrixDAL::bindValueToPdo($query, 'inhd_type_code', 'form_submission');
397  MatrixDAL::bindValueToPdo($query, 'name', 'submitted');
398  MatrixDAL::bindValueToPdo($query, 'context', $GLOBALS['SQ_SYSTEM']->getContextId());
399  MatrixDAL::bindValueToPdo($query, 'from_date', $from_value);
400  MatrixDAL::bindValueToPdo($query, 'to_date', $to_value);
401  $result = MatrixDAL::executePdoAssoc($query);
402  } catch (Exception $e) {
403  throw new Exception('Unable to get submission list due to database error: '.$e->getMessage());
404  }
405 
406  foreach ($result as $asset_info) {
407  $assetid = $asset_info['assetid'];
408 
409  // time is good, load me up
410  $sub_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid);
411  $sub_user = $asset_info['created_userid'];
412  $sub_time = date('d M Y H:i:s', strtotime($asset_info['submitted']));
413  $sub_expanded = array_search($assetid, $expand_list) !== FALSE;
414  $num_subs++;
415 
416  if ($num_subs > $num_per_page) break;
417  ?>
418  <tr<?php
419  echo ($sub_expanded) ? ' class="alt"' : '';
420  ?>>
421  <td>
422  <?php echo $assetid ?>
423  </td>
424  <td>
425  <?php echo $sub_time ?>
426  </td>
427  <td>
428  <?php
429  $valid_user = FALSE;
430  if (!empty($sub_user)) {
431  $sub_user_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($sub_user);
432  if (!empty($sub_user_asset)) {
433  echo get_asset_tag_line($sub_user);
434  $valid_user = TRUE;
435  }
436  }
437  if (!$valid_user) {
438  ?><i><?php echo translate('cms_form_no_logged_in_user'); ?></i><?php
439  }
440  ?>
441  </td>
442  <td>
443  <input type="checkbox" name="<?php echo $prefix ?>_expand[]" value="<?php echo $assetid ?>" <?php if ($sub_expanded) echo ' checked="checked"'; ?> onclick="sq_test_check_all(this.form, '<?php echo $prefix ?>_expand[]', '<?php echo $prefix ?>_expand_all');">
444  </td>
445  <?php
446  if ($write_access) {
447  ?>
448  <td>
449  <input type="checkbox" name="<?php echo $prefix ?>_delete[]" value="<?php echo $assetid ?>" onclick="sq_test_check_all(this.form, '<?php echo $prefix ?>_delete[]', '<?php echo $prefix ?>_delete_all');">
450  </td>
451  <?php
452  }
453  ?>
454  <td>[ <a href="<?php echo $sub_asset->getBackendHref(); ?>"><?php echo translate('edit') ?></a> ]</td>
455  </tr>
456  <?php
457  // display only if expanded
458  if ($sub_expanded) {
459  ?>
460  <tr>
461  <td colspan="6" class="sq-form-sub">
462  <table class="sq-backend-table">
463  <tr>
464  <?php
465  $i = 0;
466  $elements = $sub_asset->getSummary();
467  if (count($elements) % 2 != 0) {
468  $elements[] = Array('name' => '', 'answer' => '');
469  }
470  foreach ($elements as $element) {
471  $i++;
472  ?>
473  <th width="10%"><?php echo $element['name']; if (!empty($element['name'])) echo ':'; ?></th>
474  <td width="40%"><?php echo $element['answer']; ?></td>
475  <?php
476  if (($i < count($elements)) && ($i % 2 == 0)) {
477  ?>
478  </tr>
479  <tr>
480  <?php
481  }
482  }//end foreach elemnent
483  ?>
484  </tr>
485  </table>
486  </td>
487  </tr>
488  <?php
489  }//end if expanded
490  }//end while submission
491  ?>
492  </table>
493  <script type="text/javascript"><!--
494  sq_test_check_all(document.main_form, '<?php echo $prefix ?>_expand[]', '<?php echo $prefix ?>_expand_all');
495  //--></script>
496  <?php
497  }//end else
498 
499 
500  return TRUE;
501 
502  }//end paintSubmissionList()
503 
504 
515  function processSubmissionList(&$asset, &$o, $prefix)
516  {
517  $delete_list = isset($_POST[$prefix.'_delete']) ? $_POST[$prefix.'_delete'] : Array();
518  if (empty($delete_list)) return FALSE;
519 
520  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
521  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
522 
523  // acquire the links lock on the form
524  if (!$GLOBALS['SQ_SYSTEM']->am->acquireLock($asset->id, 'links')) {
525  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
526  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
527  return FALSE;
528  }
529 
530  foreach ($delete_list as $delete_assetid) {
531  // is the assetid a valid one?
532  if (!assert_valid_assetid($delete_assetid, '', FALSE, FALSE)) {
533  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
534  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
535  return FALSE;
536  }
537 
538  // acquire the links lock on the submission to delete
539  if (!$GLOBALS['SQ_SYSTEM']->am->acquireLock($delete_assetid, 'links')) {
540  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
541  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
542  return FALSE;
543  }
544  $submissions_folder = $asset->getSubmissionsFolder();
545  $submission_link = $GLOBALS['SQ_SYSTEM']->am->getLinkByAsset($submissions_folder->id, $delete_assetid, SQ_LINK_TYPE_3);
546  if (!$submission_link) {
547  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
548  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
549  return FALSE;
550  } else {
551  if (!$submissions_folder->deleteLink($submission_link['linkid'])) {
552  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
553  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
554  return FALSE;
555  }
556  }
557 
558  // release the links lock
559  if (!$GLOBALS['SQ_SYSTEM']->am->releaseLock($delete_assetid, 'links')) {
560  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
561  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
562  return FALSE;
563  }
564  }//end foreach
565 
566  // now release the links lock on the form itself
567  if (!$GLOBALS['SQ_SYSTEM']->am->releaseLock($asset->id, 'links')) {
568  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
569  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
570  return FALSE;
571  }
572 
573  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
574  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
575 
576  return TRUE;
577 
578  }//end processSubmissionList()
579 
580 
591  function paintDownloadDateRange(&$asset, &$o, $prefix)
592  {
593  $parameters = Array(
594  'min' => '2003-01-01 00:00:00',
595  'max' => ts_iso8601(time()),
596  'allow_circa' => '0',
597  'show' => Array('y', 'm', 'd'),
598  'null' => Array(),
599  'style' => Array(
600  'y' => 's',
601  'm' => 's',
602  'd' => 's',
603  ),
604  );
605 
606  $parameters['print_format'] = 'j M Y';
607 
608  $from_value = isset($_POST[$prefix.'_export_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_fromvalue']['m'],$_POST[$prefix.'_export_fromvalue']['d'],$_POST[$prefix.'_export_fromvalue']['y'])) : date('Y-m-d', time()-7*86400).' --:--:--';
609  $to_value = isset($_POST[$prefix.'_export_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_tovalue']['m'],$_POST[$prefix.'_export_tovalue']['d'],$_POST[$prefix.'_export_tovalue']['y'])) : date('Y-m-d').' --:--:--';
610 
611  $from = new Datetime_Field($prefix.'_export_from', $from_value, $parameters);
612  $to = new Datetime_Field($prefix.'_export_to', $to_value, $parameters);
613 
614  $from->printField();
615  echo ' '.translate('to').' ';
616  $to->printField();
617 
618  }//end paintDownloadDateRange()
619 
620 
631  function paintDownloadFormat(&$asset, &$o, $prefix)
632  {
633  $options = Array(
634  '' => '------- '.translate('please_select').' -------',
635  'csv' => translate('cms_form_download_csv'),
636  'csv_nhr' => translate('cms_form_download_csv_nhr'),
637  'xml' => translate('cms_form_download_xml'),
638  );
639 
640  echo combo_box($prefix.'_export_format', $options, FALSE, '');
641  echo hidden_field($prefix.'_export_switch', '0');
642 
643  $delimiter_text = isset($_POST[$prefix.'_delimiter']) ? $_POST[$prefix.'_delimiter'] : ',';
644  echo ' &nbsp; Delimiter &nbsp;';
645  echo text_box($prefix.'_delimiter',$delimiter_text,1,1,TRUE);
646 
647  }//end paintDownloadFormat()
648 
649 
660  function paintDownloadButton(&$asset, &$o, $prefix)
661  {
662  // explanation for onClick for the Download button, there is some trickery involved here >:)
663  // - set export switch to 1 = "ON"
664  // - submit form (automatically sets SQ_FORM_SUBMITTED) - we're still here though, as the
665  // browser will be sent through the CSV/XML file and it will be offered to save - not display
666  // (DEPENDS on browser - CSV should be offered to save, XML could be intercepted by browser!)
667  // - unset SQ_FORM_SUBMITTED so the form can still be submitted via Commit
668  // - set export switch to 0 = "OFF" so Commit doesn't try to save a file either
669  // - return true for the event as per JS standard
670 
671  echo normal_button($prefix.'_export', translate('download_file'), 'this.form.'.$prefix.'_export_switch.value = 1; this.form.submit(); SQ_FORM_SUBMITTED = false; this.form.'.$prefix.'_export_switch.value = 0; return true;');
672 
673  }//end paintDownloadButton()
674 
675 
689  function processDownloadButton(&$asset, &$o, $prefix)
690  {
691  $export_button_pressed = array_get_index($_POST, $prefix.'_export_switch');
692  if (is_null($export_button_pressed)) return TRUE;
693 
694  $export_type = array_get_index($_POST, $prefix.'_export_format', '');
695  $export_delimiter = array_get_index($_POST, $prefix.'_delimiter', '');
696 
697  switch ($export_type) {
698  case 'csv':
699  $this->processExportCSV($asset, $o, $prefix, TRUE, $export_delimiter);
700  break;
701 
702  case 'csv_nhr':
703  $this->processExportCSV($asset, $o, $prefix, FALSE, $export_delimiter);
704  break;
705 
706  case 'xml':
707  $this->processExportXML($asset, $o, $prefix);
708  break;
709  }
710 
711  return TRUE;
712 
713  }//end processDownloadButton()
714 
715 
731  function processExportCSV(&$asset, &$o, $prefix, $header_row=TRUE, $delimiter=',')
732  {
733  // get the from and to values
734  $from_value = isset($_POST[$prefix.'_export_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_fromvalue']['m'],$_POST[$prefix.'_export_fromvalue']['d'],$_POST[$prefix.'_export_fromvalue']['y'])) : '---------- --:--:--';
735  $to_value = isset($_POST[$prefix.'_export_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_tovalue']['m'],$_POST[$prefix.'_export_tovalue']['d'],$_POST[$prefix.'_export_tovalue']['y'])) : '---------- --:--:--';
736 
737  $from_value = explode('-',iso8601_date_component($from_value));
738  $to_value = explode('-',iso8601_date_component($to_value));
739 
740  // convert the ISO times to time stamps but manually because we can't be sure
741  // about the h:m:s section of the above times
742  $from_ts = mktime(0,0,0,$from_value[1],$from_value[2],$from_value[0]);
743  $to_ts = mktime(23,59,59,$to_value[1],$to_value[2],$to_value[0]);
744 
745  $csv = $this->createCSVSubmissionLogs($asset, $from_ts, $to_ts);
746  $csv->setFilename('submission_log.csv');
747  $csv->setDeliminator($delimiter);
748 
749  // by default, headers are set in createCSVSubmissionLogs(). If we do not need it, set it to FALSE
750  if (!$header_row) $csv->setFieldHeaders($header_row); // setFieldHeaders() accept pass-by-reference parameter so we just can not use FALSE literal value alone
751 
752  // export with keyed fields
753  $csv->export(TRUE);
754  exit(0);
755 
756  return TRUE;
757 
758  }//end processExportCSV()
759 
760 
768  public function createCSVSubmissionLogs($form, $from_time, $to_time)
769  {
770  $logs = Array();
771  $headers = Array('__time__' => translate('submission_time'), '__user__' => translate('cms_form_user_submitting'), '__ipaddress__' => translate('cms_form_ipaddress_submitting'));
772  $sub_folder = $form->getSubmissionsFolder();
773  $assetids = Array($form->id, $sub_folder->id);
774  $from_time = ts_iso8601($from_time);
775  $to_time = ts_iso8601($to_time);
776 
777  try {
778  $bind_vars = Array(
779  'assetids' => $assetids,
780  'from_time' => $from_time,
781  'to_time' => $to_time,
782  'name' => 'submitted',
783  'context' => $GLOBALS['SQ_SYSTEM']->getContextId(),
784  );
785  $result = $this->_getSubmissionLog($bind_vars);
786  } catch (Exception $e) {
787  throw new Exception("Unable to get submission log due to database error: ".$e->getMessage());
788  }
789 
790  foreach ($result as $asset_info) {
791  $assetid = $asset_info['assetid'];
792  $type_code = $asset_info['type_code'];
793 
794  $create_time = strtotime($asset_info['submitted']);
795 
796  $sub_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid, $type_code);
797  if (!$sub_asset->attr('complete')) continue;
798 
799  // get the submission ip
800  $ipaddress = $sub_asset->getIP();
801 
802  // get the summary
803  $summary = $sub_asset->getSummary();
804  $logs[$assetid] = Array(
805  '__time__' => date('Y-m-d H:i:s', $create_time),
806  '__user__' => $asset_info['created_userid'],
807  '__ipaddress__' => $ipaddress,
808  );
809  if (empty($summary)) $summary = Array();
810  foreach ($summary as $id => $element) {
811  if (!isset($headers[$id])) {
812  $headers[$id] = $element['name'];
813  }
814 
815  $logs[$assetid][$id] = html_entity_decode($element['answer'], ENT_NOQUOTES, SQ_CONF_DEFAULT_CHARACTER_SET) ;
816  }
817  $logs[$assetid]['__assetid__'] = $assetid;
818 
819  // Finally, add the header row for assetid in
820  if (!isset($headers['__assetid__'])) {
821  $headers['__assetid__'] = translate('assetid');
822  }//end if
823  }//end foreach
824 
825  require_once SQ_FUDGE_PATH.'/csv/csv.inc';
826  $csv = new CSV();
827  $csv->setFieldHeaders($headers);
828  $csv->setValues($logs);
829 
830  return $csv;
831 
832  }//end createCSVSubmissionLogs()
833 
834 
849  function processExportXML(&$asset, &$o, $prefix)
850  {
851  header('Content-Type: application/xml');
852 
853  // defining the file as attachment forces most browsers to offer it for download
854  header('Content-Disposition: attachment; filename=submission_log.xml;');
855 
856  // get the from and to values
857  $from_value = isset($_POST[$prefix.'_export_fromvalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_fromvalue']['m'],$_POST[$prefix.'_export_fromvalue']['d'],$_POST[$prefix.'_export_fromvalue']['y'])) : '---------- --:--:--';
858  $to_value = isset($_POST[$prefix.'_export_tovalue']) ? ts_iso8601(mktime(0,0,0,$_POST[$prefix.'_export_tovalue']['m'],$_POST[$prefix.'_export_tovalue']['d'],$_POST[$prefix.'_export_tovalue']['y'])) : '---------- --:--:--';
859 
860  $from_value = explode('-', iso8601_date_component($from_value));
861  $to_value = explode('-', iso8601_date_component($to_value));
862 
863  // convert the ISO times to time stamps but manually because we can't be sure
864  // about the h:m:s section of the above times
865  $from_ts = mktime(0, 0, 0, $from_value[1], $from_value[2], $from_value[0]);
866  $to_ts = mktime(23, 59, 59, $to_value[1], $to_value[2], $to_value[0]);
867  $from_time = ts_iso8601($from_ts);
868  $to_time = ts_iso8601($to_ts);
869  $sub_folder = $asset->getSubmissionsFolder();
870  $assetids = Array($asset->id, $sub_folder->id);
871 
872  try {
873  $bind_vars = Array(
874  'assetids' => $assetids,
875  'from_time' => $from_time,
876  'to_time' => $to_time,
877  'name' => 'submitted',
878  'context' => $GLOBALS['SQ_SYSTEM']->getContextId(),
879  );
880  $result = $this->_getSubmissionLog($bind_vars);
881  } catch (Exception $e) {
882  throw new Exception("Unable to get submission log due to database error: ".$e->getMessage());
883  }
884 
885  echo "<submissions>\n";
886  foreach ($result as $asset_info) {
887  $assetid = $asset_info['assetid'];
888  $type_code = $asset_info['type_code'];
889 
890  $sub_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid, $type_code);
891  if (!$sub_asset->attr('complete')) continue;
892 
893  if (trim($sub_asset->attr('xml')) == '') continue;
894  echo "\t".$sub_asset->attr('xml')."\n";
895  }
896  echo '</submissions>';
897  exit(0);
898 
899  return TRUE;
900 
901  }//end processExportXML()
902 
903 
913  public function paintSendSubmissionsEmail(Form_Email $asset, Backend_Outputter $o, $prefix)
914  {
915  $write_access = $asset->writeAccess('attributes');
916 
917  $job_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_NOTICE, 'cron_job_send_submission_log', TRUE, 'minor');
918 
919  if (!empty($job_links)) {
920  ?>
921  <table class="sq-backend-table">
922  <tr>
923  <td class="sq-backend-table-header"><?php echo translate('name'); ?></td>
924  <td class="sq-backend-table-header"><?php echo translate('when'); ?></td>
925  <td align="center" class="sq-backend-table-header" style="text-align: center;"><?php echo translate('delete'); ?> ?</td>
926  <td align="center" class="sq-backend-table-header" style="text-align: center;"></td>
927  </tr>
928  <?php
929  for ($k = 0; $k < count($job_links); $k++) {
930  $job = $GLOBALS['SQ_SYSTEM']->am->getAsset($job_links[$k]['majorid'], 'cron_job_send_submission_log');
931  ?>
932  <tr>
933  <td class="sq-backend-table-cell">
934  <?php echo $job->displayName(); ?>
935  </td>
936  <td class="sq-backend-table-cell">
937  <?php echo $job->readableWhen(); ?>
938  </td>
939  <td align="center" class="sq-backend-table-cell">
940  <?php
941  if ($write_access && $job->canDelete()) {
942  check_box($prefix.'_remove_job[]', $job->id);
943  } else {
944  check_box($prefix.'_remove_job[]', $job->id, FALSE, '', 'disabled');
945  }
946  ?>
947  </td>
948  <td>[ <a href="<?php echo $job->getBackendHref(); ?>"><?php echo translate('edit') ?></a> ]</td>
949  </tr>
950  <?php
951  }//end for
952  ?>
953  </table>
954  <?php
955 
956  } else {
957  echo "<i>".translate('cron_job_send_submission_log_no_jobs')."</i><br/><br/>";
958  }
959 
960  // Add new job checkbox
961  if ($write_access) {
962  label(translate('cron_job_send_submission_log_add_new_job'), $prefix.'_new_job');
963  echo '&nbsp;';
964  text_box($prefix.'_new_job_name', '', 25);
965  $GLOBALS['SQ_SYSTEM']->am->includeAsset('cron_job_send_submission_log');
966  $cron_job = new Cron_Job_Send_Submission_Log();
967  $edit_fns = $cron_job->getEditFns();
968  $null_asset = NULL;
969  $edit_fns->paintScheduleInterface($null_asset, $o, $prefix);
970  }
971 
972  return $write_access;
973 
974  }//end paintSendSubmissionsEmail()
975 
976 
986  public function processSendSubmissionsEmail(Form_Email $asset, Backend_Outputter $o, $prefix)
987  {
988  $write_access = $asset->writeAccess('attributes');
989 
990  if ($write_access) {
991 
992  $cron_mgr = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cron_manager');
993  $GLOBALS['SQ_SYSTEM']->am->includeAsset('cron_job_send_submission_log');
994 
995  // Delete selected jobs
996  if (isset($_POST[$prefix.'_remove_job'])) {
998  if (!empty($jobs)) {
999 
1000  if ($GLOBALS['SQ_SYSTEM']->am->acquireLock($cron_mgr->id, 'links')) {
1001  for ($i = 0; $i < count($jobs); $i++) {
1002  if (in_array($jobs[$i]->id, $_POST[$prefix.'_remove_job'])) {
1003  $cron_mgr->removeJob($jobs[$i]);
1004  }// end if
1005  }// end for
1006  $GLOBALS['SQ_SYSTEM']->am->releaseLock($cron_mgr->id, 'links');
1007  } else {
1008  trigger_localised_error('SYS0232', E_USER_NOTICE);
1009 
1010  }// end if
1011 
1012  }// end if
1013  }//end if
1014 
1015  // Create new cron job
1016  $new_job_name = isset($_POST[$prefix.'_new_job_name']) ? trim($_POST[$prefix.'_new_job_name']) : '';
1017  if (!empty($new_job_name)) {
1018 
1019  $default_time = 'TI='.time().',7,86400';
1020  $new_job = new Cron_Job_Send_Submission_Log();
1021  $new_job->setAttrValue('display_name', $new_job_name);
1022  $new_job->setAttrValue('type', 'repeating');
1023  $new_job->setAttrValue('long', TRUE);
1024  $edit_fns = $new_job->getEditFns();
1025  if (!$edit_fns->processScheduleInterface($new_job, $o, $prefix)) {
1026  return FALSE;
1027  }
1028 
1029  if ($new_job->setAssetToUpdate($asset)) {
1030  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
1031  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
1032  if ($cron_mgr->addJob($new_job, $GLOBALS['SQ_SYSTEM']->user)) {
1033  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
1034  } else {
1035  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
1036  }
1037  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
1038  }
1039 
1040  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($cron_mgr);
1041  }//end if
1042  }//end if
1043 
1044  return $write_access;
1045 
1046  }//end processSendSubmissionsEmail()
1047 
1048 
1057  function _getSubmissionLog($bind_vars)
1058  {
1059  $result = Array();
1060 
1061  // No assetids passed in ... no results for you!
1062  if (isset($bind_vars['assetids']) && empty($bind_vars['assetids'])) {
1063  return $result;
1064  }//end if
1065 
1066  try {
1067  if (MatrixDAL::getDbType() === 'oci') {
1068  $sql = "SELECT a.assetid, a.type_code, v.custom_val AS submitted, a.created_userid
1069  FROM sq_ast a
1070  INNER JOIN sq_ast_typ_inhd t ON a.type_code=t.type_code
1071  INNER JOIN sq_ast_lnk l ON l.minorid=a.assetid
1072  INNER JOIN sq_ast_attr_val v ON v.assetid=a.assetid
1073  INNER JOIN sq_ast_attr n ON n.attrid=v.attrid";
1074  $where = " WHERE";
1075  $assetids = array_get_index($bind_vars, 'assetids', Array());
1076  if (!empty($assetids)) {
1077  foreach ($assetids as $index => $assetid) {
1078  $assetids[$index] = MatrixDAL::quote($assetid);
1079  }//end foreach
1080  $where .= " l.majorid IN (".implode(',', $assetids).") AND";
1081  }//end if
1082  $where .= " t.inhd_type_code='form_submission'
1083  AND n.name=:name AND v.contextid=:context
1084  AND TO_CHAR(DBMS_LOB.SUBSTR(v.custom_val, 30, 1)) > :from_time
1085  AND TO_CHAR(DBMS_LOB.SUBSTR(v.custom_val, 30, 1)) < :to_time";
1086  $query = MatrixDAL::preparePdoQuery($sql.$where);
1087  MatrixDAL::bindValueToPdo($query, 'name', array_get_index($bind_vars, 'name', ''));
1088  MatrixDAL::bindValueToPdo($query, 'context', array_get_index($bind_vars, 'context', ''));
1089  MatrixDAL::bindValueToPdo($query, 'from_time', array_get_index($bind_vars, 'from_time', date('Y-m-d').' 00:00:00'));
1090  MatrixDAL::bindValueToPdo($query, 'to_time', array_get_index($bind_vars, 'to_time', date('Y-m-d').' 23:59:59'));
1091  $result = MatrixDAL::executePdoAssoc($query);
1092  } else {
1093  $result = MatrixDAL::executeAssoc('cms_package', 'getSubmissionLog', $bind_vars);
1094  }//end if
1095  } catch (Exception $e) {
1096  $result = Array();
1097  throw new Exception("Unable to get submission log due to database error: ".$e->getMessage());
1098  }
1099 
1100  return $result;
1101 
1102  }//end _getSubmissionLog()
1103 
1104 
1113  function &_generateSubmissionList(&$tree_root)
1114  {
1115  $children = Array();
1116 
1117  $kids =& $tree_root->children;
1118 
1119  for (reset($kids); NULL !== ($k = key($kids)); next($kids)) {
1120  $this_child =& $kids[$k];
1121  $child_id = $this_child->getAttribute('id');
1122  $child_name = $this_child->getAttribute('name');
1123  switch ($this_child->name) {
1124  case 'section':
1125  break;
1126 
1127  case 'text_q':
1128  $child_value = $this_child->content;
1129  break;
1130 
1131  case 'datetime_q':
1132  $child_value = date('d M Y H:i:s', iso8601_ts($this_child->content));
1133  $circa = $this_child->getAttribute('circa');
1134  if ($circa) $child_value = 'circa '.$child_value;
1135  break;
1136 
1137  case 'select_q':
1138  $select_options =& $this_child->children;
1139  $child_value = Array(); // store child as an array
1140 
1141  for (reset($select_options); NULL !== ($k = key($select_options)); next($select_options)) {
1142  $this_option =& $select_options[$k];
1143  $child_value[] = $this_option->content;
1144  }
1145  $child_value = implode(', ', $child_value);
1146  break;
1147  }
1148 
1149  if ($this_child->name != 'section') {
1150  $children[] = Array('id' => $child_id, 'name' => $child_name, 'content' => $child_value);
1151  }
1152  }//end for
1153 
1154  return $children;
1155 
1156  }//end _generateSubmissionList()
1157 
1158 
1159 //-- RECEIPT FIELD --//
1160 
1161 
1172  function paintReceiptField(&$asset, &$o, $prefix)
1173  {
1174  $write_access = $asset->writeAccess('attributes');
1175 
1176  $assetid = $asset->attr('receipt_field');
1177  if ($write_access) {
1178  asset_finder($prefix.'_rec_field', $assetid, Array('form_question_type_email_address' => 'I'));
1179  } else {
1180  if (!empty($assetid)) {
1181  echo get_asset_tag_line($assetid);
1182  } else {
1183  echo '<em>'.translate('none').'</em>';
1184  }
1185  }
1186 
1187  return $write_access;
1188 
1189  }//end paintReceiptField()
1190 
1191 
1202  function processReceiptField(&$asset, &$o, $prefix)
1203  {
1204  if (!isset($_POST[$prefix.'_rec_field'])) return FALSE;
1205  $assetid = $_POST[$prefix.'_rec_field']['assetid'];
1206 
1207  // add check that this is in the same form
1208 
1209  // if we already have this as the not found asset, don't set it again
1210  if ($assetid == $asset->attr('receipt_field')) {
1211  return FALSE;
1212  }
1213  if (!$asset->setAttrValue('receipt_field', $assetid)) {
1214  return FALSE;
1215  }
1216 
1217  return TRUE;
1218 
1219  }//end processReceiptField()
1220 
1221 
1222 //-- SEND TO A FRIEND --//
1223 
1224 
1235  function paintSTAFField(&$asset, &$o, $prefix)
1236  {
1237  $write_access = $asset->writeAccess('attributes');
1238 
1239  $assetid = $asset->attr('staf_field');
1240  if ($write_access) {
1241  asset_finder($prefix.'_staf_field', $assetid, Array('form_question_type_text' => 'D'));
1242  } else {
1243  if (!empty($assetid)) {
1244  echo get_asset_tag_line($assetid);
1245  } else {
1246  echo '<em>'.translate('none').'</em>';
1247  }
1248  }
1249 
1250  return $write_access;
1251 
1252  }//end paintSTAFField()
1253 
1254 
1265  function processSTAFField(&$asset, &$o, $prefix)
1266  {
1267  if (!isset($_POST[$prefix.'_staf_field'])) {
1268  return FALSE;
1269  }
1270  $assetid = $_POST[$prefix.'_staf_field']['assetid'];
1271 
1272  // todo: add check that this is in the same form
1273 
1274  // if we already have this as the not found asset, don't set it again
1275  if ($assetid == $asset->attr('staf_field')) {
1276  return FALSE;
1277  }
1278  if (!$asset->setAttrValue('staf_field', $assetid)) {
1279  return FALSE;
1280  }
1281 
1282  return TRUE;
1283 
1284  }//end processSTAFField()
1285 
1286 
1287 //-- SELECTIVE E-MAILS --//
1288 
1289 
1300  function paintAddSelectiveEmailRule(&$asset, &$o, $prefix)
1301  {
1302  if (!$asset->writeAccess('attributes')) return FALSE;
1303  check_box($prefix.'_new_se_rule', '1', FALSE);
1304  echo ' New Rule';
1305 
1306  return TRUE;
1307 
1308  }//end paintAddSelectiveEmailRule()
1309 
1310 
1321  function processAddSelectiveEmailRule(&$asset, &$o, $prefix)
1322  {
1323  if (!isset($_REQUEST[$prefix.'_new_se_rule'])) {
1324  return FALSE;
1325  }
1326  $all_se = $asset->attr('selective_emails');
1327 
1328  // pull out a new index for this question
1329  if (empty($all_se)) {
1330  $new_id = 0;
1331  } else {
1332  $new_id = max(array_keys($all_se)) + 1;
1333  }
1334 
1335  // fill out the defaults
1336  $all_se[$new_id] = Array(
1337  'assetid' => '',
1338  'rules' => Array(),
1339  'require' => 'all',
1340  'send' => 'recipient',
1341  'address' => '',
1342  );
1343 
1344  // set the post/request variables so the later functions know to show the new rule
1345  $_REQUEST[$prefix.'_se_active_ruleid'] = $new_id;
1346 
1347  $_POST[$prefix.'_require'] = 'all';
1348  $_POST[$prefix.'_send'] = 'recipient';
1349  $_POST[$prefix.'_address'] = '';
1350 
1351  if (!$asset->setAttrValue('selective_emails', $all_se)) {
1352  return FALSE;
1353  }
1354 
1355  return $asset->saveAttributes();
1356 
1357  }//end processAddSelectiveEmailRule()
1358 
1359 
1370  function paintCurrentSelectiveEmails(&$asset, &$o, $prefix)
1371  {
1372  $admin_access = $asset->adminAccess('attributes');
1373 
1374  $am = $GLOBALS['SQ_SYSTEM']->am;
1375 
1376  $ruleid = isset($_REQUEST[$prefix.'_se_active_ruleid']) ? $_REQUEST[$prefix.'_se_active_ruleid'] : -1;
1377 
1378  if (isset($_REQUEST[$prefix.'_se_active_ruleid'])) {
1379  $o->addHiddenField($prefix.'_se_active_ruleid', $_REQUEST[$prefix.'_se_active_ruleid']);
1380  }
1381 
1382  $all_se = $asset->attr('selective_emails');
1383 
1384  if (empty($all_se)) {
1385  echo translate('cms_form_no_selective_email_rules');
1386  return FALSE;
1387  }
1388 
1389  ?>
1390  <table class="sq-backend-table">
1391  <tr>
1392  <?php
1393  if ($admin_access) {
1394  ?><td align="center" width="30" class="sq-backend-table-header" style="font-weight: bold;"><?php echo translate('edit') ?></td><?php
1395  }
1396  ?><td class="sq-backend-table-header">
1397  <?php echo translate('rule') ?>
1398  </td>
1399  <td align="center" width="50" class="sq-backend-table-header" style="font-weight: bold;"><?php echo translate('valid_question') ?></td>
1400  <?php
1401  if ($admin_access) {
1402  ?><td align="center" width="70" class="sq-backend-table-header" style="font-weight: bold;"><?php echo translate('delete_question') ?></td>
1403  <?php
1404  }
1405  ?>
1406  </tr>
1407  <?php
1408  for (reset($all_se); NULL !== ($k = key($all_se)); next($all_se)) {
1409  $info =& $all_se[$k];
1410  $rule_prefix = $prefix.'_r'.$k;
1411  $valid = TRUE;
1412  ?>
1413  <tr<?php if ($ruleid == $k) echo ' class="alt"'; ?>>
1414  <?php
1415  if ($admin_access) {
1416  ?>
1417  <td valign="top" align="center" width="30" class="sq-backend-table-cell"><a href="<?php echo $o->getCurrentLocation(); ?>&<?php echo $prefix?>_se_active_ruleid=<?php echo $k ?>"><img src="<?php echo sq_web_path('lib'); ?>/web/images/icons/edit_mode.png" width="15" height="15" border="0" /></a></td>
1418  <?php
1419  }
1420  ?>
1421  <td valign="top" class="sq-backend-table-cell">
1422  <?php
1423  if (empty($info['rules'])) {
1424  ?>
1425  <span><?php echo translate('cms_form_rule_no_parts') ?></span><br/>
1426  <?php
1427  $valid = FALSE;
1428  } else {
1429  $rules =& $info['rules'];
1430 
1431  $rule_logic = ($info['require'] == 'all') ? strtoupper(translate('and')) : strtoupper(translate('or'));
1432  $descriptions = Array();
1433  $deleted_q = FALSE;
1434 
1435  $i = 0;
1436  for (reset($rules); NULL !== ($rule_key = key($rules)); next($rules)) {
1437  $rule =& $rules[$rule_key];
1438  $type_code = 'form_question_rule_type_'.$rule['name'];
1439  $q_asset = $am->getAsset($rule['assetid']);
1440 
1441  // deleted question = invalid rule!
1442  if (!$q_asset) {
1443  $deleted_q = TRUE;
1444  $valid = FALSE;
1445  break;
1446  }
1447 
1448  $GLOBALS['SQ_SYSTEM']->am->includeAsset($type_code);
1449  $rule_asset = new $type_code();
1450  $descriptions[] = $rule_asset->ruleDescription($q_asset, $rule);
1451 
1452  $i++;
1453  }//end for
1454 
1455  if ($deleted_q) {
1456  echo translate('cms_form_se_rule_deleted_questions');
1457  } else {
1458  echo implode('<br/><b>'.$rule_logic.'</b>', $descriptions);
1459  }
1460  echo '<br/>';
1461 
1462  }//end else rules not empty
1463 
1464  echo 'Send a <b>';
1465  if ($info['send'] == 'staf') {
1466  echo translate('cms_form_staf');
1467  } else if ($info['send'] == 'recipient') {
1468  echo translate('cms_form_recipient');
1469  } else if ($info['send'] == 'receipt') {
1470  echo translate('cms_form_receipt');
1471  } else {
1472  echo translate('cms_form_unknown_email_type');
1473  $valid = FALSE;
1474  }
1475 
1476  echo '</b> email to <b>';
1477  if (empty($info['address'])) {
1478  $valid = FALSE;
1479  echo translate('cms_form_no_email_address');
1480  } else {
1481  echo $info['address'];
1482  }
1483  echo '</b>';
1484  ?>
1485  </td>
1486  <td valign="top" align="center" width="70" class="sq-backend-table-cell"><img src="<?php echo sq_web_path('lib'); ?>/web/images/<?php echo $valid ? 'tick' : 'cross'; ?>.gif" width="15" height="15" /></td>
1487  <?php
1488  if ($admin_access) {
1489  ?><td valign="top" align="center" width="50" class="sq-backend-table-cell"><?php check_box($prefix.'_deletes[]', $k); ?></td><?php
1490  }
1491  ?>
1492  </tr>
1493  <?php
1494  }//end for all selective emails
1495  ?>
1496  </table>
1497  <?php
1498 
1499  return TRUE;
1500 
1501  }//end paintCurrentSelectiveEmails()
1502 
1503 
1514  function processCurrentSelectiveEmails(&$asset, &$o, $prefix)
1515  {
1516  if (!isset($_POST[$prefix.'_deletes'])) return TRUE;
1517 
1518  $all_se = $asset->attr('selective_emails');
1519  $delete_ruleids = $_POST[$prefix.'_deletes'];
1520 
1521  // delete our selective e-mail rules
1522  foreach ($delete_ruleids as $ruleid) {
1523  unset($all_se[$ruleid]);
1524  if (isset($_REQUEST[$prefix.'_se_active_ruleid'])) {
1525  if ($ruleid == $_REQUEST[$prefix.'_se_active_ruleid']) {
1526  unset($_REQUEST[$prefix.'_se_active_ruleid']);
1527  }
1528  }
1529  }
1530 
1531  $asset->setAttrValue('selective_emails', $all_se);
1532 
1533  return $asset->saveAttributes();
1534 
1535  }//end processCurrentSelectiveEmails()
1536 
1537 
1548  function paintActiveQuestion(&$asset, &$o, $prefix)
1549  {
1550  if (!$asset->writeAccess('attributes')) return FALSE;
1551 
1552  if (isset($_REQUEST[$prefix.'_se_active_ruleid'])) {
1553  $current_assetid = isset($_POST[$prefix.'_se_new_qid']['assetid']) ? $_POST[$prefix.'_se_new_qid']['assetid'] : 0;
1554  asset_finder($prefix.'_se_new_qid', $current_assetid, Array('form_question' => 'D'));
1555  return TRUE;
1556  } else {
1557  return FALSE;
1558  }
1559 
1560  }//end paintActiveQuestion()
1561 
1562 
1573  function processActiveQuestion(&$asset, &$o, $prefix)
1574  {
1575  return TRUE;
1576 
1577  }//end processActiveQuestion()
1578 
1579 
1590  function paintAddRulePart(&$asset, &$o, $prefix)
1591  {
1592  if (!$asset->adminAccess('attributes')) return FALSE;
1593  if (!isset($_REQUEST[$prefix.'_se_active_ruleid'])) {
1594  return FALSE;
1595  }
1596 
1597  // we cleared the asset finder for adding a new rule part
1598  if (isset($_POST[$prefix.'_se_new_qid']) && $_POST[$prefix.'_se_new_qid']['assetid'] == 0) {
1599  unset($_POST[$prefix.'_se_new_qid']['assetid']);
1600  }
1601 
1602  if (!isset($_POST[$prefix.'_se_new_qid']['assetid'])) {
1603  echo translate('cms_form_select_question_before_part');
1604  return FALSE;
1605  } else {
1606  $active_question = $GLOBALS['SQ_SYSTEM']->am->getAsset($_POST[$prefix.'_se_new_qid']['assetid']);
1607 
1608  $rule_codes = $active_question->getAllowedRules();
1609  $type_codes = Array();
1610  foreach ($rule_codes as $rule_code) {
1611  $type_code = 'form_question_rule_type_'.$rule_code;
1612  $GLOBALS['SQ_SYSTEM']->am->includeAsset($type_code);
1613  $se_rule = eval('return '.$type_code.'::isSelectiveEmailRule();');
1614  if ($se_rule) $type_codes[] = $type_code;
1615  }
1616 
1617  $desc = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($type_codes, 'description');
1618  combo_box($prefix.'_new_rule', array_merge(Array(' ' => '------ '.translate('please_select').' ------'), $desc), FALSE, '');
1619 
1620  return TRUE;
1621  }
1622 
1623  }//end paintAddRulePart()
1624 
1625 
1636  function processAddRulePart(&$asset, &$o, $prefix)
1637  {
1638  if (!$asset->adminAccess('attributes')) return FALSE;
1639 
1640  // rule id is not set || required "new rule part" fields not set = FAIL
1641  if (!isset($_REQUEST[$prefix.'_se_active_ruleid']) ||
1642  !isset($_REQUEST[$prefix.'_new_rule']) || empty($_POST[$prefix.'_se_new_qid']['assetid'])) {
1643  return FALSE;
1644 
1645  } else {
1646  $ruleid = $_REQUEST[$prefix.'_se_active_ruleid'];
1647  $qid = $_POST[$prefix.'_se_new_qid']['assetid'];
1648  $active_question = $GLOBALS['SQ_SYSTEM']->am->getAsset($qid);
1649 
1650  $type_code = $_POST[$prefix.'_new_rule'];
1651  $rule_code = substr($type_code,24);
1652  if (!trim($rule_code)) return FALSE;
1653 
1654  $all_se = $asset->attr('selective_emails');
1655 
1656  $rules =& $all_se[$ruleid]['rules'];
1657 
1658  $GLOBALS['SQ_SYSTEM']->am->includeAsset($type_code);
1659  $operators = array_keys(eval('return '.$type_code.'::getOperators();'));
1660 
1661  $rules[] = Array(
1662  'assetid' => $qid,
1663  'name' => $rule_code,
1664  'operator' => $operators[0],
1665  'value' => '',
1666  'comparison_question_id' => 0,
1667  );
1668 
1669 
1670  $asset->setAttrValue('selective_emails', $all_se);
1671  return $asset->saveAttributes();
1672  }
1673 
1674  }//end processAddRulePart()
1675 
1676 
1687  function paintRuleParts(&$asset, &$o, $prefix)
1688  {
1689  if (!$asset->writeAccess('attributes')) {
1690  $o->openField('Note');
1691  echo translate('cms_form_unlock_to_select_se_rule');
1692  $o->closeField();
1693  return FALSE;
1694  }
1695 
1696  if (!isset($_REQUEST[$prefix.'_se_active_ruleid'])) {
1697  $o->openField('Note');
1698  echo translate('cms_form_select_to_edit_se_rule');
1699  $o->closeField();
1700  return FALSE;
1701  }
1702 
1703  $ruleid = $_REQUEST[$prefix.'_se_active_ruleid'];
1704 
1705  $write_access = $asset->writeAccess('attributes');
1706 
1707  $am = $GLOBALS['SQ_SYSTEM']->am;
1708  $all_se = $asset->attr('selective_emails');
1709  $rules = $all_se[$ruleid]['rules'];
1710  $descs = Array();
1711 
1712  if (empty($rules)) {
1713  $o->openField('Note');
1714  echo translate('cms_form_se_rule_empty');
1715  $o->closeField();
1716  return FALSE;
1717  }
1718 
1719  for (reset($rules); NULL !== ($k = key($rules)); next($rules)) {
1720  $rule =& $rules[$k];
1721  // let the rule paint itself here!!
1722  $type_code = 'form_question_rule_type_'.$rule['name'];
1723  $GLOBALS['SQ_SYSTEM']->am->includeAsset($type_code);
1724  $rule_asset = new $type_code();
1725  $edit_fns = $rule_asset->getEditFns();
1726 
1727  if (!isset($descs[$type_code])) {
1728  $asset_info = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo(Array($type_code), 'description');
1729  $descs[$type_code] = $asset_info[$type_code];
1730  }
1731 
1732  $o->openSection($descs[$type_code]);
1733 
1734  $o->openField(translate('applies_to'));
1735  $q_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($rule['assetid']);
1736  if ($q_asset) {
1737  echo get_asset_tag_line($q_asset->id);
1738  } else {
1739  echo '<i class="sq-backend-warning">'.translate('cms_form_deleted_question_cannot_edit', $rule['assetid']).'</i>';
1740  }
1741  $o->closeField();
1742 
1743  if ($q_asset) {
1744  $edit_fns->paintRule($rule_asset, $o, $prefix.'_rule_'.$k, $rule, $write_access, $q_asset);
1745  }
1746 
1747  if ($write_access) {
1748  $o->openField('Delete ?');
1749  check_box($prefix.'_rule_'.$k.'[delete]');
1750  $o->closeField();
1751  }
1752 
1753  $o->closeSection();
1754 
1755  }//end for all rules
1756 
1757  return $write_access;
1758 
1759  }//end paintRuleParts()
1760 
1761 
1772  function processRuleParts(&$asset, &$o, $prefix)
1773  {
1774  $all_se = $asset->attr('selective_emails');
1775  if (!isset($_REQUEST[$prefix.'_se_active_ruleid'])) {
1776  return FALSE;
1777  }
1778 
1779  $ruleid = $_REQUEST[$prefix.'_se_active_ruleid'];
1780  if (!isset($all_se[$ruleid])) return FALSE;
1781 
1782  $rules =& $all_se[$ruleid]['rules'];
1783 
1784  $prefix = $asset->getPrefix();
1785 
1786  // delete rules first
1787  if (empty($rules)) $rules = Array();
1788  foreach (array_keys($rules) as $k) {
1789  $rule_prefix = $prefix.'_rule_'.$k;
1790  if (!isset($_POST[$rule_prefix])) continue;
1791 
1792  if (array_get_index($_POST[$rule_prefix], 'delete', 0)) {
1793  unset($rules[$k]);
1794  }
1795  }
1796 
1797  // modify what's left
1798  for (reset($rules); NULL !== ($k = key($rules)); next($rules)) {
1799  $rule =& $rules[$k];
1800  // let the rule paint itself here!!
1801  $type_code = 'form_question_rule_type_'.$rule['name'];
1802  $GLOBALS['SQ_SYSTEM']->am->includeAsset($type_code);
1803  $rule_asset = new $type_code();
1804  $edit_fns = $rule_asset->getEditFns();
1805 
1806  $edit_fns->processRule($rule_asset, $o, $prefix.'_rule_'.$k, $rule);
1807  }
1808 
1809  $asset->setAttrValue('selective_emails', $all_se);
1810  return $asset->saveAttributes();
1811 
1812  }//end processRuleParts()
1813 
1814 
1827  function paintActiveSend(&$asset, &$o, $prefix)
1828  {
1829  if (!$asset->adminAccess('attributes')) return FALSE;
1830  if (!isset($_REQUEST[$prefix.'_se_active_ruleid'])) {
1831  return FALSE;
1832  }
1833 
1834  $ruleid = $_REQUEST[$prefix.'_se_active_ruleid'];
1835  $all_se = $asset->attr('selective_emails');
1836 
1837  // we are displaying these as substitutions into the next translation
1838  ob_start();
1839  combo_box($prefix.'_require', Array('all' => 'ALL', 'any' => 'ANY'), FALSE, Array($all_se[$ruleid]['require']));
1840  $require_box = ob_get_contents();
1841  ob_end_clean();
1842 
1843  ob_start();
1844  combo_box($prefix.'_send', Array('recipient' => 'Recipient E-mail', 'receipt' => 'Receipt', 'staf' => 'Send To A Friend E-mail'), FALSE, Array($all_se[$ruleid]['send']));
1845  $email_type_box = ob_get_contents();
1846  ob_end_clean();
1847 
1848  ob_start();
1849  // requested in bug#1437 - changed input to a text area
1850  text_area($prefix.'_address', $all_se[$ruleid]['address'], 30, 5);
1851  $address_box = ob_get_contents();
1852  ob_end_clean();
1853 
1854  echo translate('cms_form_match_email_line', $require_box, $email_type_box, $address_box);
1855 
1856 
1857  return TRUE;
1858 
1859  }//end paintActiveSend()
1860 
1861 
1872  function processActiveSend(&$asset, &$o, $prefix)
1873  {
1874  if (!$asset->adminAccess('attributes')) return FALSE;
1875  if (!isset($_REQUEST[$prefix.'_se_active_ruleid']) || !isset($_POST[$prefix.'_address'])) {
1876  return FALSE;
1877  }
1878 
1879  $ruleid = $_REQUEST[$prefix.'_se_active_ruleid'];
1880  $all_se = $asset->attr('selective_emails');
1881 
1882  $all_se[$ruleid]['require'] = $_POST[$prefix.'_require'];
1883  $all_se[$ruleid]['send'] = $_POST[$prefix.'_send'];
1884  $all_se[$ruleid]['address'] = $_POST[$prefix.'_address'];
1885 
1886  $asset->setAttrValue('selective_emails', $all_se);
1887  return $asset->saveAttributes();
1888 
1889  }//end processActiveSend()
1890 
1891 
1902  function paintKeywordReplacementText(&$asset, &$o, $prefix)
1903  {
1904  ?>
1905  <p>In addition to the simple formatting options shown underneath each email, you can use the same keyword replacements as is available for the Thank You bodycopy. Click here for a <a href="#" onClick="javascript: var win = window.open('<?php echo sq_web_path('data')?>/asset_types/form/popups/thank_you_keywords.php?assetid=<?php echo $asset->id ?>', 'keywords', 'toolbar=0,menubar=0,location=0,status=0,scrollbars=1,resizable=1,width=580,height=520')">list of keywords available for use in emails</a>.<br/></p>
1906 
1907  <?php
1908  return TRUE;
1909 
1910  }//end paintKeywordReplacementText()
1911 
1912 
1925  function processKeywordReplacementText(&$asset, &$o, $prefix)
1926  {
1927  return FALSE;
1928 
1929  }//end processKeywordReplacementText()
1930 
1931 
1941  function hasAttributeWriteAccess(&$asset, &$o) {
1942  return $asset->writeAccess('attributes');
1943 
1944  }//end hasAttributeWriteAccess()
1945 
1946 
1947  //-- FORM ACTIONS --//
1948 
1949 
1959  public function paintAllActions(Form_Email $asset, Backend_Outputter $o, $prefix)
1960  {
1961  $write_access = $asset->writeAccess('attributes');
1962  $actions = $asset->attr('actions');
1963 
1964  // Get selected action, which may have changed last commit
1965  if ($write_access) {
1966  $selected_action = array_get_index($_REQUEST, $prefix.'_new_selected_action', NULL);
1967  if (!is_numeric($selected_action)) {
1968  $selected_action = array_get_index($_POST, $prefix.'_selected_action', NULL);
1969  }
1970  } else {
1971  $selected_action = NULL;
1972  }
1973 
1974  $o->openField('');
1975 
1976  hidden_field($prefix.'_new_selected_action', '');
1977 
1978  if (!empty($actions)) {
1979  ?><table class="sq-backend-table">
1980  <colgroup>
1981  <col width="60" align="center" />
1982  <col width="150" />
1983  <col/>
1984  <col width="60" align="center" />
1985  <col width="60" align="center" />
1986  </colgroup>
1987  <thead>
1988  <th><p>Edit</p></th>
1989  <th><p>Action Name / Type</p></th>
1990  <th><p>Summary</p></th>
1991  <th><p>Valid ?</p></th>
1992  <th><p>Active ?</p></th>
1993  <th><p>Delete ?</p></th>
1994  </thead><tbody><?php
1995 
1996  foreach ($actions as $key => $action) {
1997  $is_selected_action = (!is_null($selected_action) && ((string)$selected_action === (string)$key));
1998  ?><tr<?php
1999  if ($is_selected_action) {
2000  echo ' class="alt"';
2001  }
2002  ?>><?php
2003  $action_type = $action['type_code'];
2004  $settings = $action['settings'];
2005  $type_name = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($action_type, 'name');
2006 
2007  $GLOBALS['SQ_SYSTEM']->am->includeAsset($action_type);
2008 
2009  if ($write_access && !$is_selected_action) {
2010  ?><td class="sq-backend-table-cell"><p><a href="#" onclick="document.getElementById('<?php echo $prefix ?>_new_selected_action').value = <?php echo $key ?>; document.main_form.submit(); return false;"><img src="<?php echo sq_web_path('lib'); ?>/web/images/icons/edit_mode.png" width="15" height="15" border="0" /></a></p></td><?php
2011  } else {
2012  ?><td class="sq-backend-table-cell">&nbsp;</td><?php
2013  }
2014  ?><td class="sq-backend-table-cell"><p><strong><?php echo $action['name'] ?></strong><br/>(<?php echo $type_name ?>)</p></td><?php
2015  ?><td class="sq-backend-table-cell"><?php echo call_user_func(Array($action_type, 'paintSummary'), $asset, $settings, $o, $prefix) ?></td><?php
2016  ?><td class="sq-backend-table-cell"><p><img src="<?php echo sq_web_path('lib'); ?>/web/images/<?php echo call_user_func(Array($action_type, 'isValid'), $asset, $settings) ? 'tick' : 'cross' ?>.gif" width="15" height="15" border="0" /></p></td><?php
2017  if ($write_access) {
2018  ?><td class="sq-backend-table-cell"><p><?php check_box($prefix.'_rules[active]['.$key.']', '1', $action['active']) ?></p></td><?php
2019  ?><td class="sq-backend-table-cell"><p><?php check_box($prefix.'_rules[delete]['.$key.']', '1', FALSE) ?></p></td><?php
2020  } else {
2021  ?><td class="sq-backend-table-cell"><p><img src="<?php echo sq_web_path('lib'); ?>/web/images/<?php echo $action['active'] ? 'tick' : 'cross' ?>.gif" width="15" height="15" border="0" /></p></td><?php
2022  ?><td class="sq-backend-table-cell">&nbsp;</td><?php
2023  }
2024  ?></tr><?php
2025  }
2026  ?></tbody></table><?php
2027  } else {
2028  ?><p>There are no actions currently defined for this form.</p><?php
2029  }
2030 
2031  $o->closeField();
2032  $o->sectionNote('Only actions that are <strong>valid</strong> and <strong>active</strong> will be executed when a form is submitted. An action can be activated or deactivated with the <strong>Active ?</strong> check box.');
2033 
2034  return $write_access;
2035 
2036  }//end paintAllActions()
2037 
2038 
2048  public function processAllActions(Form_Email $asset, Backend_Outputter $o, $prefix)
2049  {
2050  $write_access = $asset->writeAccess('attributes');
2051 
2052  // If we have selected "edit action", then we don't want this to run,
2053  // because we only want active/delete changes to take effect upon
2054  // hitting the commit button.
2055  $edit_action = array_get_index($_REQUEST, $prefix.'_new_selected_action', NULL);
2056  if (!empty($edit_action)) {
2057  return $write_access;
2058  }
2059 
2060  if ($write_access) {
2061  $actions = $asset->attr('actions');
2062 
2063  $rule_changes = array_get_index($_POST, $prefix.'_rules', Array());
2064 
2065  if(!empty($actions)) {
2066  foreach ($actions as $key => $action) {
2067  if (!isset($rule_changes['active'][$key])) {
2068  $rule_changes['active'][$key] = Array();
2069  }
2070  }
2071  } else {
2072  if (!isset($rule_changes['active'])) {
2073  $rule_changes['active'] = Array();
2074  }
2075  }
2076 
2077  if (!isset($rule_changes['delete'])) {
2078  $rule_changes['delete'] = Array();
2079  }
2080 
2081  foreach ($rule_changes['active'] as $key => $value) {
2082  $actions[$key]['active'] = (boolean)$value;
2083  }
2084  foreach ($rule_changes['delete'] as $key => $value) {
2085  unset($actions[$key]);
2086  }
2087 
2088  $asset->setAttrValue('actions', $actions);
2089  if (!$asset->saveAttributes()) return FALSE;
2090  }
2091 
2092  return $write_access;
2093 
2094  }//end processAllActions()
2095 
2096 
2106  public function paintNewAction(Form_Email $asset, Backend_Outputter $o, $prefix)
2107  {
2108  $write_access = $asset->writeAccess('attributes');
2109 
2110  $types = $GLOBALS['SQ_SYSTEM']->am->getTypeDescendants('form_action');
2111  $names = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($types, 'name');
2112 
2113  $o->openField('');
2114  if ($write_access) {
2115  ?><p><?php
2116  check_box($prefix.'_new', '1', FALSE, 'this.form.'.$prefix.'_new_type.disabled = !this.checked; return true;');
2117  ?><label for="<?php echo $prefix ?>_new">Create a new action of type:</label> <?php
2118  $names = Array('' => 'Select action type...') + $names;
2119  combo_box($prefix.'_new_type', $names, FALSE, '', 0, 'disabled="disabled"');
2120  ?></p><?php
2121  } else {
2122  ?><p>This screen must be locked before you can create a new action.</p><?php
2123  }
2124 
2125  // If we have a new action, are we
2126  $o->closeField();
2127 
2128  $o->sectionNote('If you create a new action, the new action will be displayed immediately for you to edit. If you already have an action open to edit, the changes to that action will be saved when you commit before the new action is created.');
2129 
2130  return $write_access;
2131 
2132  }//end paintNewAction()
2133 
2134 
2144  public function processNewAction(Form_Email $asset, Backend_Outputter $o, $prefix)
2145  {
2146  $write_access = $asset->writeAccess('attributes');
2147 
2148  if ($write_access) {
2149  // First check that we are creating a new rule.
2150  $new_action = (int)array_get_index($_POST, $prefix.'_new', '0');
2151 
2152  if ($new_action) {
2153  // Paranoia, paranoia...
2154  // Check whether the type we've been passed is a valid type,
2155  // to protect possible stuffed POSTDATA (including a blank)
2156  $action_type = array_get_index($_POST, $prefix.'_new_type', '');
2157  if (!empty($action_type)) {
2158  if ($GLOBALS['SQ_SYSTEM']->am->installed($action_type)) {
2159  // Also check whether it's a valid form action
2160  $type_parents = $GLOBALS['SQ_SYSTEM']->am->getTypeAncestors($action_type);
2161  if (in_array('form_action', $type_parents)) {
2162  // okay, we seem to be in the clear
2163  $type_name = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($action_type, 'name');
2164  $actions = $asset->attr('actions');
2165 
2166  if (!empty($actions)) {
2167  $new_key = max(array_keys($actions)) + 1;
2168  } else {
2169  $new_key = 0;
2170  }
2171 
2172  $actions[$new_key] = Array(
2173  'name' => $this->_makeValidActionName($asset, $type_name),
2174  'type_code' => $action_type,
2175  'settings' => NULL,
2176  'active' => TRUE,
2177  );
2178  $asset->setAttrValue('actions', $actions);
2179 
2180  // Set new selected action
2181  $_POST[$prefix.'_new_selected_action'] = $new_key;
2182 
2183  if (!$asset->saveAttributes()) return FALSE;
2184  } else {
2185  trigger_error('Cannot create new action; asset type "'.$action_type.'" is not a form action', E_USER_WARNING);
2186  return FALSE;
2187  }
2188  } else {
2189  trigger_error('Cannot create new action; "'.$action_type.'" is not a valid asset type', E_USER_WARNING);
2190  return FALSE;
2191  }
2192  }
2193  }
2194 
2195  }
2196 
2197  return $write_access;
2198 
2199  }//end processNewAction()
2200 
2201 
2211  public function paintSelectedAction(Form_Email $asset, Backend_Outputter $o, $prefix)
2212  {
2213  $write_access = $asset->writeAccess('attributes');
2214  $selected_action = array_get_index($_REQUEST, $prefix.'_new_selected_action', NULL);
2215  if (!is_numeric($selected_action)) {
2216  $selected_action = array_get_index($_POST, $prefix.'_selected_action', NULL);
2217  }
2218 
2219  if ($write_access) {
2220  if (!is_null($selected_action)) {
2221  $actions = $asset->attr('actions');
2222 
2223  // Get the current action and process - but not if we've
2224  // already been deleted further up!
2225  if (!isset($actions[$selected_action])) {
2226  $o->openField('');
2227  ?><p>No action is currently selected for editing. To edit an action, please select from the "Existing Actions" list above.</p><?php
2228  $o->closeField();
2229  return FALSE;
2230  }
2231 
2232  $action = $actions[$selected_action];
2233 
2234  $type_name = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($action['type_code'], 'name');
2235 
2236  $o->openField('Action Name');
2237 
2238  text_box($prefix.'_selected_name', $action['name'], 30);
2239  $o->note('An optional name to identify this particular action. If cleared, the action\'s type ("'.$type_name.'" in this case) will be used, numerically indexed if necessary.');
2240 
2241  $o->closeField();
2242  $o->openField('Settings');
2243 
2244  hidden_field($prefix.'_selected_action', $selected_action);
2245  $GLOBALS['SQ_SYSTEM']->am->includeAsset($action['type_code']);
2246  call_user_func(Array($action['type_code'], 'paintInlineInterface'), $asset, $action['settings'], $o, $prefix);
2247 
2248  $o->closeField();
2249 
2250  } else {
2251  $o->openField('');
2252  ?><p>No action is currently selected for editing. To edit an action, please select from the "Existing Actions" list above.</p><?php
2253  $o->closeField();
2254 
2255  }//end if there is a selected action
2256  } else {
2257  $o->openField('');
2258  ?><p>This screen must be locked before you can edit an action.</p><?php
2259  $o->closeField();
2260  }//end if write_access
2261 
2262  return $write_access;
2263 
2264  }//end paintSelectedAction()
2265 
2266 
2276  public function processSelectedAction(Form_Email $asset, Backend_Outputter $o, $prefix)
2277  {
2278  $write_access = $asset->writeAccess('attributes');
2279  $actions = $asset->attr('actions');
2280  $result = FALSE;
2281 
2282  // If an "edit action" has been clicked, then we've lost the changes
2283  // to the current rule.
2284  $edit_action = array_get_index($_REQUEST, $prefix.'_new_selected_action', NULL);
2285  if (is_numeric($edit_action)) {
2286  return FALSE;
2287  }
2288 
2289  // If not, then get the current action and process - but not if we've
2290  // already been deleted!
2291  $selected_action = array_get_index($_POST, $prefix.'_selected_action', NULL);
2292  if (!isset($actions[$selected_action])) {
2293  return FALSE;
2294  }
2295 
2296  if ($write_access) {
2297  if (!is_null($selected_action)) {
2298  $new_name = array_get_index($_POST, $prefix.'_selected_name', NULL);
2299  $action = $actions[$selected_action];
2300 
2301  $new_name = array_get_index($_POST, $prefix.'_selected_name', NULL);
2302  if ($new_name != $action['name']) {
2303  if (empty($new_name)) {
2304  $new_name = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($action['type_code'], 'name');
2305  }
2306  $actions[$selected_action]['name'] = $this->_makeValidActionName($asset, $new_name);
2307  }
2308 
2309  $GLOBALS['SQ_SYSTEM']->am->includeAsset($action['type_code']);
2310  $settings = $action['settings'];
2311 
2312  // Bug Fix #3145
2313  // call_user_func doesn't work with pass-by-reference in PHP5, so using call_user_func_array instead
2314  $result = call_user_func_array(Array($action['type_code'], 'processInlineInterface'), Array($asset, &$settings, $o, $prefix));
2315  if ($result) {
2316  $actions[$selected_action]['settings'] = $settings;
2317  $asset->setAttrValue('actions', $actions);
2318  if (!$asset->saveAttributes()) return FALSE;
2319  }
2320  } else {
2321  return FALSE;
2322  }
2323  }
2324 
2325  return ($result && $write_access);
2326 
2327  }//end processSelectedAction()
2328 
2329 
2342  protected function _makeValidActionName(Form_Email $asset, $base_name)
2343  {
2344  $actions = $asset->attr('actions');
2345 
2346  $name = $base_name;
2347  $i = 1;
2348 
2349  do {
2350  $found = FALSE;
2351 
2352  foreach ($actions as $action) {
2353  if ($action['name'] == $name) {
2354  $found = TRUE;
2355 
2356  // Incrememt the base name
2357  $i++;
2358  $name = $base_name.' '.$i;
2359  break;
2360  }
2361  }
2362 
2363  } while ($found);
2364 
2365  return $name;
2366 
2367  }//end _makeValidActionName()
2368 
2369 
2370 }//end class
2371 ?>