Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
trigger_action_set_future_status.inc
1 <?php
17 require_once SQ_CORE_PACKAGE_PATH.'/system/triggers/trigger_action/trigger_action.inc';
18 require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
19 
34 {
35 
36 
57  public static function execute($settings, &$state)
58  {
59  // check settings, status
60  if (empty($settings['status'])) {
61  // if no settings, fail
62  return FALSE;
63  }
64 
65  if (empty($state['asset'])) {
66  // grab the asset if assetid is given, but not the asset.
67  if (empty($state['assetid'])) {
68  return FALSE;
69  } else {
70  $state['asset'] = $GLOBALS['SQ_SYSTEM']->am->getAsset($state['assetid']);
71  }
72  }
73 
74  $custom_message = array_get_index($settings, 'custom_error_msg', '');
75  $custom_error_level = (isset($settings['treat_as_fatal']) && $settings['treat_as_fatal']) ? E_USER_ERROR : E_USER_WARNING;
76 
77  $cron_mgr = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cron_manager');
78  if (is_null($cron_mgr)) return FALSE;
79 
80  $GLOBALS['SQ_SYSTEM']->am->includeAsset('cron_job_future_status');
81 
82  $fs = new Cron_Job_Future_Status();
83  $fs->setAttrValue('status', $settings['status']);
84  $fs->setAttrValue('dependants_only', !$settings['cascade']);
85 
86  if ($settings['when_type'] == 'by_attr_value') {
87  // need to try to consult an attribute value
88  if (empty($settings['when_attr_name'])) return FALSE; // incomplete config
89  if (!($state['asset'] instanceof $settings['when_asset_type'])) {
90  return FALSE; // wrong asset type
91  }
92  $val = @$state['asset']->attr($settings['when_attr_name']);
93  if (empty($val)) return FALSE; // empty date time attr
94  if ($settings['offset_used']) {
95  $offset = (int)substr($settings['when'], 4) * 60;
96  $when = iso8601_ts($val) + $offset;
97  if ($when < time()) {
98  // it's in the past
99  if ($custom_message != '') trigger_error($custom_message, $custom_error_level);
100  return FALSE;
101  }
102  $fs->setAttrValue('when', 'OO='.substr(ts_iso8601($when), 0, 16));
103  } else {
104  // just the straight value
105  $ts = iso8601_ts($val);
106  if ($ts < time()) {
107  // it's in the past
108  if ($custom_message != '') trigger_error($custom_message, $custom_error_level);
109  return FALSE;
110  }
111  $fs->setAttrValue('when', 'OO='.substr(ts_iso8601($ts), 0, 16));
112  }
113  } else if ($settings['when_type'] == 'by_meta_value') {
114  // need to try to consult a metadata value
115  if (empty($settings['when_meta_field_id'])) {
116  return FALSE; // incomplete config
117  }
118 
119  // Grab the Metadata for the asset which fired this trigger
120  $mm = $GLOBALS['SQ_SYSTEM']->getMetadataManager();
121  $val = $mm->getMetadataValueByAssetid($state['assetid'], $settings['when_meta_field_id'], FALSE, TRUE);
122 
123  // Now attempt to find our relevant Metadata Field
124  // If everything is fine then we should have a date value of some sort - otherwise fail
125  if (!isset($val)) return FALSE; // Expected Metadata Field not assigned
126 
127  if (empty($val)) return FALSE; // empty date time attr
128 
129  if ($settings['offset_used']) {
130  $offset = (int)substr($settings['when'], 4) * 60;
131  $when = iso8601_ts($val) + $offset;
132  if ($when < time()) {
133  // it's in the past
134  if ($custom_message != '') trigger_error($custom_message, $custom_error_level);
135  return FALSE;
136  }
137  $fs->setAttrValue('when', 'OO='.substr(ts_iso8601($when), 0, 16));
138  } else {
139  // just the straight value
140  $ts = iso8601_ts($val);
141  if ($ts < time()){
142  // it's in the past
143  if ($custom_message != '') trigger_error($custom_message, $custom_error_level);
144  return FALSE;
145  }
146  $fs->setAttrValue('when', 'OO='.substr(ts_iso8601($ts), 0, 16));
147  }
148  } else {
149  // just the straight value
150  // the simple, and backwards-compatible case:
151  $fs->setAttrValue('when', $settings['when']);
152  }
153 
154 
155  if ($GLOBALS['SQ_SYSTEM']->runLevelEnables(SQ_SECURITY_PERMISSIONS)) {
156  $user_for_status_change = $GLOBALS['SQ_SYSTEM']->user;
157  } else {
158  // not doing the whole "security" thing - so pretend we are root
159  $user_for_status_change = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('root_user');
160  }
161 
162  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
163  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
164 
165  // bail if we cannot set the asset that this cron job is to update
166  if (!$fs->setAssetToUpdate($state['asset'])) {
167  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
168  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
169  return FALSE;
170  }
171 
172  if ($cron_mgr->addJob($fs, $user_for_status_change)) {
173  if ($GLOBALS['SQ_SYSTEM']->am->acquireLock($fs->id, 'links')) {
174  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
175  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
176  $is_updated = TRUE;
177  $GLOBALS['SQ_SYSTEM']->am->releaseLock($fs->id, 'links');
178  } else {
179  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
180  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
181  return FALSE;
182  }
183  } else {
184  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
185  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
186  return FALSE;
187  }
188 
189  return Array(
190  'jobid' => $fs->id,
191  'userid' => $user_for_status_change->id,
192  'status' => $fs->attr('status'),
193  'when' => $fs->attr('when'),
194  );
195 
196  }//end execute()
197 
198 
209  public static function getInterface($settings, $prefix, $write_access=FALSE)
210  {
211  // set defaults
212  $settings['status'] = array_get_index($settings, 'status', SQ_STATUS_LIVE_APPROVAL);
213  $settings['cascade'] = array_get_index($settings, 'cascade', FALSE);
214  $settings['when'] = array_get_index($settings, 'when');
215  $settings['when_asset_type'] = array_get_index($settings, 'when_asset_type', '');
216  $settings['when_attr_name'] = array_get_index($settings, 'when_attr_name', '');
217  $settings['when_meta_field_id'] = array_get_index($settings, 'when_meta_field_id', '');
218 
219  if (!isset($settings['when_type'])) {
220  if (empty($settings['when'])) {
221  $settings['when_type'] = 'explicit_exact';
222  } else {
223  // some backwards compatibility
224  if (FALSE === strpos($settings['when'], 'OO!')) {
225  $settings['when_type'] = 'explicit_exact';
226  } else {
227  $settings['when_type'] = 'on_trigger_fire';
228  $weights = Array('i' => 1, 'h' => 60, 'd' => 1440, 'w' => 10080, 'm' => 43200, 'y' => 535600);
229  $settings['when'] = 'OO!i'.($weights[$settings['when'][3]] * substr($settings['when'], 4));
230  }
231  }
232  }
233  $munge_prefix = str_replace('[', '_', $prefix);
234  $munge_prefix = str_replace(']', '', $munge_prefix);
235  hidden_field($prefix.'[prefix]', $munge_prefix);
236  $prefix = $munge_prefix;
237 
238  ob_start();
239 
240  include_once SQ_ATTRIBUTES_PATH.'/duration/duration.inc';
241  $duration = new Asset_Attribute_Duration();
242  $duration->setEditParam('biggest_units', $duration->units['days']);
243  $duration->setEditParam('smallest_units', $duration->units['minutes']);
244  $mins = 0;
245  if (0 === strpos($settings['when'], 'OO!i')) {
246  $mins = ((int)(substr($settings['when'], 4)) * 60);
247  $duration->value = abs($mins);
248  }
249 
250  include_once SQ_ATTRIBUTES_PATH.'/datetime/datetime.inc';
251  $datetime = new Asset_Attribute_Datetime();
252  $datetime->setEditParam('show', Array('y', 'm', 'd', 'h', 'i'));
253  $datetime->setEditParam('min', date('Y-m-d H:i:s')); // must be in the future
254  if (FALSE === strpos($settings['when'], 'OO!')) {
255  $datetime->value = substr($settings['when'], 3).':00';
256  }
257 
258  echo translate('trigger_action_future_status_make_status_change_to').' ';
259 
260  $GLOBALS['SQ_SYSTEM']->am->includeAsset('cron_job_future_status');
262  if ($write_access) {
263  combo_box($prefix.'_status', $descs, FALSE, $settings['status'], NULL);
264  } else {
265  echo '<b>'.$descs[$settings['status']].'</b> ';
266  }
267 
268  $formats = Array();
269 
270  ob_start();
271  label(translate('immediately_when_trigger_fired'), $prefix.'_when_type_on_trigger_fire');
272  $formats['on_trigger_fire'] = ob_get_clean();
273 
274  ob_start();
275  label(translate('trigger_action_future_status_explicit_exact').' ', $prefix.'_when_type_explicit_exact');
276  $datetime->paint($prefix.'_explicit_exact', !$write_access);
277  $formats['explicit_exact'] = ob_get_clean();
278 
279  ob_start();
280  label(translate('as_determined_from_asset_attribute').'&nbsp', $prefix.'_as_determined_from_attr');
281  echo Trigger_Action_Set_Future_Status::getAttributeChooser($prefix.'_exact_attr', $write_access, $settings['when_asset_type'], $settings['when_attr_name']);
282  $formats['by_attr_value'] = ob_get_clean();
283 
284  ob_start();
285  label(translate('as_determined_from_metadata_field').'&nbsp;&nbsp;&nbsp;', $prefix.'_as_determined_from_meta');
286  $metadata_field_id = $settings['when_meta_field_id'];
287  if ($write_access) {
288  asset_finder($prefix.'_when_meta_field_id', $metadata_field_id, Array('metadata_field_date' => 'D'));
289  ?>
290  <p><em class="sq-backend-smallprint">(<?php echo translate('trigger_action_future_status_date_format'); ?>)</em></p>
291  <?php
292  } else {
293  if ($metadata_field_id) {
294  $metadata_field = $GLOBALS['SQ_SYSTEM']->am->getAsset($metadata_field_id);
295 
296  // Found the associated Metadata Field asset
297  if ($metadata_field) {
298  echo get_asset_tag_line($metadata_field_id);
299  } else {
300  // Looks like we have an ex-asset...
301  echo '<span class="sq-backend-warning">Unknown asset (Id: #'.$metadata_field_id.')</span>';
302  }
303  } else {
304  echo '<b>No metadata field specified</b>';
305  }
306  }
307  $formats['by_meta_value'] = ob_get_clean();
308 
309  if ($write_access) {
310  $GLOBALS['SQ_SYSTEM']->backend->out->addOnLoad('initEnableFieldLists();');
311  ?>
312  <ul class="radio-list enable-field-list">
313  <?php
314  foreach ($formats as $type => $content) {
315  ?>
316  <li>
317  <?php radio_button($prefix.'_when_type', $type, ($settings['when_type'] == $type)); ?><div>
318  <?php echo $content; ?>
319  </div>
320  </li>
321  <?php
322  }
323 
324 
325  ?>
326  </ul>
327  <?php
328  } else {
329  echo preg_replace('/<label([^>]*)>/', '', $formats[$settings['when_type']]);
330  }
331 
332  echo '<p>';
333  label(translate('offset_for_above_fields').': ', $prefix.'_offset');
334  $duration->paint($prefix.'_offset_value', !$write_access);
335  echo ' ';
336  if ($write_access) {
337  combo_box($prefix.'_offset_operator', Array('-' => translate('before'), '+' => translate('after')), FALSE, ($mins < 0) ? '-' : '+');
338  } else {
339  echo translate(($mins < 0) ? 'before' : 'after');
340  }
341  echo ' '.translate('specified_value').'<br /><i>'.translate('offset_field_note').'</i><br /><br /></p>';
342 
343  if ($write_access) {
344  check_box($prefix.'_cascade_all', '1', $settings['cascade']);
345  label(translate('trigger_action_future_status_cascade_all'), $prefix.'_cascade_all');
346  ?>
347  <p><em class="sq-backend-smallprint">(<?php echo translate('trigger_action_future_status_failure_conditions'); ?>)</em></p>
348  <?php
349  } else {
350  if ($settings['cascade']) {
351  echo ' '.translate('trigger_action_future_status_cascade_all');
352  }
353  }
354 
355  echo '<p>';
356  echo translate('trigger_action_future_status_customise_msg');
357  $custom_message = array_get_index($settings, 'custom_error_msg', '');
358  if ($write_access) {
359  text_box($prefix.'_custom_error_msg', $custom_message, '40');
360  } else {
361  echo ' : '.$custom_message;
362  }
363  echo translate('trigger_action_future_status_customise_msg_note');
364  '<br />()<b>NOTE :</b> If customised, this error message will be displayed if the caluclated time is in past.</p>';
365 
366  echo '<p>';
367  echo translate('trigger_action_future_status_treat_as_fatal');
368  $treat_fatal = array_get_index($settings, 'treat_as_fatal', 0);
369  if ($write_access) {
370  check_box($prefix.'_treat_as_fatal', '1', $treat_fatal);
371  } else {
372  echo '<img src="'.sq_web_path('lib').'/web/images/'.($treat_fatal ? 'tick' : 'cross').'.gif" alt="'.($treat_fatal ? translate('yes') : translate('no')).'" /> ';
373  }
374  echo translate('trigger_action_future_status_treat_as_fatal_note');
375 
376  return ob_get_clean();
377 
378  }//end getInterface()
379 
380 
392  public static function processInterface(&$settings, $request_data)
393  {
394  $prefix = $request_data['prefix'];
395 
396  if (empty($_POST[$prefix.'_when_type'])) return TRUE;
397 
398  $settings['when_type'] = $_POST[$prefix.'_when_type'];
399  $settings['cascade'] = !empty($_POST[$prefix.'_cascade_all']);
400  $settings['custom_error_msg'] = array_get_index($_POST, $prefix.'_custom_error_msg', '');
401  $settings['treat_as_fatal'] = array_get_index($_POST, $prefix.'_treat_as_fatal', 0);
402 
404  if (!isset($status_list[$_POST[$prefix.'_status']])) {
405  return 'Invalid status';
406  }
407  $settings['status'] = $_POST[$prefix.'_status'];
408 
409  include_once SQ_ATTRIBUTES_PATH.'/duration/duration.inc';
410  $duration = new Asset_Attribute_Duration();
411  $duration->setEditParam('biggest_units', $duration->units['days']);
412  $duration->setEditParam('smallest_units', $duration->units['minutes']);
413 
414  include_once SQ_ATTRIBUTES_PATH.'/datetime/datetime.inc';
415  $datetime = new Asset_Attribute_Datetime();
416  $datetime->setEditParam('show', Array('y', 'm', 'd', 'h', 'i'));
417  $datetime->setEditParam('min', date('Y-m-d H:i:s')); // must be in the future
418 
419  switch ($settings['when_type']) {
420  case 'explicit_exact':
421  $settings['when_asset_type'] = '';
422  $settings['when_attr_name'] = '';
423  $datetime->process($prefix.'_explicit_exact');
424  $settings['when'] = 'OO='.substr($datetime->value, 0, 16);
425  break;
426 
427  case 'on_trigger_fire':
428  $settings['when_asset_type'] = '';
429  $settings['when_attr_name'] = '';
430  $settings['when'] = '';
431  break;
432 
433  case 'by_attr_value':
434  $settings['when_asset_type'] = $_POST[$prefix.'_exact_attr']['asset_type'];
435  $settings['when_attr_name'] = array_get_index($_POST[$prefix.'_exact_attr'], 'attribute');
436  $settings['when'] = '';
437  break;
438 
439  case 'by_meta_value':
440  $settings['when_meta_field_id'] = 0;
441  if (isset($_POST[$prefix.'_when_meta_field_id']['assetid'])) {
442  $settings['when_meta_field_id'] = $_POST[$prefix.'_when_meta_field_id']['assetid'];
443  }
444 
445  $settings['when'] = '';
446  }//end switch
447 
448  // Add or subtract any applicable offset when the "when_type" is not exact (ie; an absolute time)
449  $settings['offset_used'] = FALSE;
450  if ($settings['when_type'] != 'explicit_exact') {
451  $duration->process($prefix.'_offset_value');
452  $mins = ((int)$duration->value/60);
453 
454  // Only allow a "before" offset if we are not using an exact time or the Trigger Fire time as a reference
455  if (($settings['when_type'] != 'on_trigger_fire') && ($_POST[$prefix.'_offset_operator'] == '-')) {
456  $mins *= -1;
457  }
458 
459  $settings['when'] = 'OO!i'.$mins;
460  $settings['offset_used'] = TRUE;
461  }
462 
463  return FALSE;
464 
465  }//end processInterface()
466 
467 
476  protected static function _getStatusList()
477  {
478  $status = Array();
479  foreach (get_constant_values('SQ_STATUS_') as $status_value) {
480  $status[$status_value] = get_status_description($status_value);
481  }
482  return $status;
483 
484  }//end _getStatusList()
485 
486 
498  protected static function getAttributeChooser($prefix, $write_access, $type, $attr)
499  {
500  ob_start();
501  if ($write_access) {
502  asset_type_chooser($prefix.'[asset_type]', FALSE, Array($type), TRUE);
503  } else {
504  echo '<b>'.$type.'</b> ';
505  }
506  $basic_part_1 = ob_get_contents();
507  ob_end_clean();
508 
509  ob_start();
510  if ($type == '') {
511  echo '<em>['.translate('asset_type_not_selected').']</em>';
512  } else {
513  $attrs = $GLOBALS['SQ_SYSTEM']->am->getAssetTypeAttributes($type, Array('name', 'type'));
514  if (empty($attrs)) {
515  echo '<b>['.translate('asset_type_no_attributes_found').']</b>';
516  } else {
517  if ($write_access) {
518  $attr_options = Array('' => '');
519  foreach ($attrs as $name => $type) {
520  if ($type['type'] == 'datetime') {
521  $attr_options[$name] = $name;
522  }
523  }
524  combo_box($prefix.'[attribute]', $attr_options, FALSE, $attr);
525  } else {
526  echo '<b>'.$attr.'</b>';
527  }
528  }
529  }
530  $basic_part_2 = ob_get_contents();
531  ob_end_clean();
532 
533  return $basic_part_1.$basic_part_2;
534 
535  }//end getAttributeChooser()
536 
537 
538 }//end class
539 
540 ?>