Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
hipo_job_edit_bundled_assets_status.inc
1 <?php
2 
3 
4 require_once SQ_SYSTEM_ROOT.'/core/hipo/hipo_job.inc';
5 
6 
8 {
9 
10 
19  protected $_usual_statuses = Array(
20  SQ_STATUS_UNDER_CONSTRUCTION => SQ_SC_STATUS_CAN_APPROVE,
21  SQ_STATUS_PENDING_APPROVAL => SQ_SC_STATUS_PENDING,
22  SQ_STATUS_APPROVED => SQ_SC_STATUS_ALL_APPROVED,
23  SQ_STATUS_LIVE => SQ_STATUS_LIVE,
24  );
25 
26 
27 
34  public static function getConfigVars()
35  {
36  return Array(
37  'SQ_HIPO_EDIT_BUNDLED_ASSETS_STATUS_THRESHOLD' => Array('editable' => 1, 'default' => 1),
38  );
39 
40  }//end getConfigVars()
41 
42 
64  {
65  if (SQ_HIPO_EDIT_BUNDLED_ASSETS_STATUS_THRESHOLD < 1) {
66  return 0;
67  }
68 
69  }//end getThresholdPercentageRequired()
70 
71 
72 
73 
74 
81  function getHipoName()
82  {
83  return translate('hipo_name_edit_bundled_assets_status');
84 
85  }//end getHipoName()
86 
87 
99  function getCodeName()
100  {
101  return parent::getCodeName().'-'.$this->_running_vars['bundle_assetid'];
102 
103  }//end getCodeName()
104 
105 
114  {
115  return Array(
116  0 => Array(
117  'name' => translate('hipo_job_edit_bundled_assets_status_status'),
118  'function_call' => Array(
119  'paint_function' => 'paintStatusChangeWarning',
120  'process_function' => 'processStatusChangeWarning',
121  ),
122  'running_mode' => 'web',
123  'auto_step' => FALSE,
124  'skip_step' => FALSE,
125  'allow_cancel' => TRUE,
126  'percent_done' => 0,
127  'complete' => FALSE,
128  'message' => '',
129  ),
130  1 => Array(
131  'name' => translate('hipo_job_edit_bundled_assets_status_status'),
132  'function_call' => Array(
133  'process_function' => 'processBundledAsset',
134  ),
135  'running_mode' => 'server',
136  'auto_step' => TRUE,
137  'allow_cancel' => TRUE,
138  'percent_done' => 0,
139  'complete' => FALSE,
140  'message' => '',
141  ),
142  2 => Array(
143  'name' => translate('hipo_job_edit_bundled_assets_status_send'),
144  'function_call' => Array(
145  'process_function' => 'sendBundleWorkflowMessage',
146  ),
147  'running_mode' => 'server',
148  'auto_step' => TRUE,
149  'allow_cancel' => TRUE,
150  'percent_done' => 0,
151  'complete' => FALSE,
152  'message' => '',
153  ),
154  );
155 
156  }//end getInitialStepData()
157 
158 
164  public function prepare()
165  {
166  // We must have a bundle asset ID
167  if (array_key_exists('bundle_assetid', $this->_running_vars) === FALSE) {
168  trigger_localised_error('HIPO0092', E_USER_WARNING);
169  return FALSE;
170  }
171 
172  // Validate the bundle asset ID and ensure it's actually a bundle
173  $bundle_assetid = $this->_running_vars['bundle_assetid'];
174  $type_code = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo($bundle_assetid, '', TRUE, 'type_code');
175 
176  // The asset doesn't exist...
177  if (count($type_code) === 0) {
178  trigger_localised_error('HIPO0093', E_USER_WARNING, $bundle_assetid);
179  return FALSE;
180  }
181 
182  // It's not a bundle...
183  if ($type_code[$bundle_assetid] !== 'workflow_bundle') {
184  trigger_localised_error('HIPO0094', E_USER_WARNING, $bundle_assetid);
185  return FALSE;
186  }
187 
188  if (array_key_exists('workflow_stream', $this->_running_vars) === FALSE) {
189  $this->_running_vars['workflow_stream'] = '';
190  }
191 
192  $todo_assetids = $this->_getBundledAssets($bundle_assetid);
193 
194  $this->_running_vars['todo_assetids'] = Array();
195  $this->_running_vars['warn_assetids'] = Array();
196 
197  $bundle_status = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo(Array($bundle_assetid), '', FALSE, 'status');
198  $this->_running_vars['bundle_current_status'] = (int)$bundle_status[$bundle_assetid];
199 
200  foreach ($todo_assetids as $todo_assetid) {
201  $new_asset_status = $this->_getNewAssetStatus($todo_assetid, (int)$this->_running_vars['bundle_current_status'], (int)$this->_running_vars['new_status'], $this->_running_vars['workflow_stream']);
202  $this->_running_vars['todo_assetids'][$todo_assetid] = $new_asset_status;
203 
204  // Is this is not an asset status that we expect?
205  if ($new_asset_status !== NULL) {
206  if (((int)$new_asset_status & $this->_usual_statuses[(int)$this->_running_vars['new_status']]) === 0) {
207  $this->_running_vars['warn_assetids'][$new_asset_status][] = $todo_assetid;
208  }
209  }
210  }
211 
212  if (count($this->_running_vars['warn_assetids']) === 0) {
213  $this->skipStep(0);
214  }
215 
216  $this->_running_vars['done_root'] = FALSE;
217  $this->_running_vars['done_assetids'] = Array();
218 
219  $this->_running_vars['msg_filters'] = Array();
220 
221  return parent::prepare();
222 
223  }//end prepare()
224 
225 
238  function paint(&$o, $nested=FALSE)
239  {
240  parent::paint($o, $nested);
241 
242  // paint dependant hipo job here
243  if (!empty($this->_running_vars['sub_job'])) {
244  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
245  $sub_job = $hh->getJob($this->_running_vars['sub_job']);
246  if (!is_null($sub_job)) {
247  $sub_job->paint($o, TRUE);
248  } else {
249  unset($this->_running_vars['sub_job']);
250  }
251  }
252 
253  }//end paint()
254 
255 
261  public function freestyle()
262  {
263  while (!empty($this->_running_vars['todo_assetids']) || !empty($this->_running_vars['sub_job'])) {
264  if ($this->processBundledAsset($this->_steps[0], get_class($this), TRUE) !== TRUE) {
265  return FALSE;
266  }
267  }
268 
269  if ($this->sendBundleWorkflowMessage($this->_steps[1], get_class($this), TRUE) !== TRUE) {
270  return FALSE;
271  }
272 
273  return TRUE;
274 
275  }//end freestyle()
276 
277 
293  public function paintStatusChangeWarning(Array &$step_data, Hipo_Backend_Outputter $o, $prefix)
294  {
295  $o->openSection(translate('hipo_job_edit_bundled_assets_status_status'));
296 
297  $o->openRaw();
298  echo translate('hipo_job_edit_bundled_assets_status_status_warning');
299  $o->closeRaw();
300 
301  foreach ($this->_running_vars['warn_assetids'] as $status => $warn_assetids) {
302  $o->openSection(translate('hipo_job_edit_bundled_assets_status_status_line', get_asset_status_icon($status), get_status_description($status)));
303  $o->openRaw();
304  ?><ul><?php
305  foreach ($warn_assetids as $assetid) {
306  ?><li><?php
307  echo get_asset_tag_line($assetid);
308  ?></li><?php
309  }
310  ?></ul><?php
311  $o->closeRaw();
312  $o->closeSection();
313  }
314 
315  $o->closeSection();
316 
317  return TRUE;
318 
319  }//end paintStatusChangeWarning()
320 
321 
333  public function processStatusChangeWarning(Array &$step_data, $prefix)
334  {
335  $complete = (($step_data['percent_done'] > 0) || (empty($this->_running_vars['warn_assetids']) === TRUE));
336 
337  if ($complete === FALSE) {
338  $step_data['percent_done'] = 50;
339  } else {
340  $step_data['percent_done'] = 100;
341  $step_data['complete'] = TRUE;
342  }
343 
344  return TRUE;
345 
346  }//end processStatusChangeWarning()
347 
348 
358  public function processBundledAsset(&$step_data, $prefix, $freestyle=FALSE)
359  {
360  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
361  if (empty($this->_running_vars['sub_job']) === FALSE) {
362  $sub_job = $hh->getJob($this->_running_vars['sub_job']);
363  if (empty($sub_job) === TRUE) {
364  return FALSE;
365  }
366  } else {
367  $current_status = (int)$this->_running_vars['bundle_current_status'];
368  $new_status = (int)$this->_running_vars['new_status'];
369 
370  if ($this->_running_vars['done_root'] === FALSE) {
371  $assetid = $this->_running_vars['bundle_assetid'];
372  $new_asset_status = $this->_running_vars['new_status'];
373  $this->_running_vars['done_root'] = TRUE;
374  } else {
375  $new_asset_status = reset($this->_running_vars['todo_assetids']);
376  $assetid = key($this->_running_vars['todo_assetids']);
377  unset($this->_running_vars['todo_assetids'][$assetid]);
378  }
379 
380  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid);
381 
382  if (isset($this->_running_vars['no_status_integrity'][$assetid])) {
383  $run_level = $GLOBALS['SQ_SYSTEM']->getRunLevel();
384  $GLOBALS['SQ_SYSTEM']->setRunLevel($run_level ^ SQ_SECURITY_STATUS_INTEGRITY);
385  }
386 
387  // NULL asset status means we should be skipping this asset instead
388  if ($new_asset_status !== NULL) {
389  $code_name = $this->_prepareStatusChangeHIPO($assetid, $new_asset_status);
390  $asset_current_status = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo(Array($assetid), 'asset', FALSE, 'status');
391  $asset_current_status = $asset_current_status[$assetid];
392 
393  // If the asset is currently in workflow, send a log message.
394  // (It does not matter if the change itself goes through - this
395  // is consistent with normal Workflow screen workings, where the
396  // log is logged first, then the status change run)
397  if (empty($this->_running_vars['log_message']) === FALSE) {
398  if (($asset_current_status & SQ_SC_STATUS_PENDING) > 0) {
399  $this->_sendUserLogMessage($assetid, $this->_running_vars['log_message']);
400  }
401  }
402 
403  $this->_running_vars['sub_job'] = $code_name;
404  $sub_job = $hh->getJob($code_name);
405  $step_data['message'] = translate('hipo_edit_status', htmlentities($asset->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET), $assetid);
406  } else {
407  $step_data['message'] = translate('hipo_skipping_asset', $assetid);
408  }
409  }
410 
411  $filters = Array(
412  'start' => 'asset.workflow.invitation',
413  'progress' => 'asset.workflow.invitation.progress',
414  'approve' => 'asset.workflow.announce.approve',
415  'reject' => 'asset.workflow.announce.reject',
416  'auto_approve_progress' => 'asset.workflow.announce.started',
417  );
418 
419  $msg_types = $this->_getRequiredBundleMessages($this->_running_vars['bundle_current_status'], $this->_running_vars['new_status']);
420  $used_filters = Array();
421  foreach ($msg_types as $msg_type) {
422  $used_filters[$msg_type] = $filters[$msg_type];
423  }
424 
425  if (empty($sub_job) === FALSE) {
426  if ($freestyle === TRUE) {
427  // in stereo, with tha freestylah =P
428  if ($sub_job->freestyle() === TRUE) {
429  $running_vars = $sub_job->getRunningVars();
430  $this->_running_vars['done_assetids'][] = $running_vars['assetid'];
431 
432  // If we are not the bundle, examine the messages we get,
433  // filter the invite ones out
434  if ((string)$running_vars['assetid'] !== (string)$this->_running_vars['bundle_assetid']) {
435  $job_messages = array_get_index($running_vars, 'messages', Array());
436  $this->_filterMessages($running_vars['assetid'], $job_messages, $used_filters);
437  } else {
438  $job_messages = Array();
439  }
440 
441  // Grab the errors from the status sub-job, since we need
442  // to show them to the user afterwards
443  $this->_hipo_vars['errors'] = array_merge($this->_hipo_vars['errors'], $sub_job->_hipo_vars['errors']);
444  unset($this->_running_vars['sub_job']);
445  $sub_job->save();
446  $hh->uncacheJob($sub_job->code_name);
447  } else {
448  // Failed to process! Get the errors at least, and bail
449  $this->_hipo_vars['errors'] = array_merge($this->_hipo_vars['errors'], $sub_job->_hipo_vars['errors']);
450  return FALSE;
451  }
452  } else {
453  if ($sub_job->process() === TRUE) {
454  if ($sub_job->complete() === TRUE) {
455  // process the sub hipo on each refresh
456  $running_vars = $sub_job->getRunningVars();
457  if (isset($running_vars['assetid'])) {
458  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($running_vars['assetid']);
459  $asset->_updated(FALSE);
460  $this->_running_vars['done_assetids'][] = $running_vars['assetid'];
461 
462  // If we are not the bundle, examine the messages we get,
463  // filter the invite ones out
464  if ((string)$running_vars['assetid'] !== (string)$this->_running_vars['bundle_assetid']) {
465  $job_messages = array_get_index($running_vars, 'messages', Array());
466  $this->_filterMessages($running_vars['assetid'], $job_messages, $used_filters);
467  } else {
468  $job_messages = Array();
469  }
470  }
471 
472  // Grab the errors from the status sub-job, since we need
473  // to show them to the user afterwards
474  $this->_hipo_vars['errors'] = array_merge($this->_hipo_vars['errors'], $sub_job->_hipo_vars['errors']);
475  unset($this->_running_vars['sub_job']);
476  }
477  } else {
478  // Failed to process! Get the errors at least, and bail
479  $this->_hipo_vars['errors'] = array_merge($this->_hipo_vars['errors'], $sub_job->_hipo_vars['errors']);
480  return FALSE;
481  }
482  }
483  }
484 
485  if (empty($job_messages) === FALSE) {
486  // Send any messages we have left - these would be log
487  // messages, so these should still be passed on as usual
488  $ms = $GLOBALS['SQ_SYSTEM']->getMessagingService();
489  $ms->send($job_messages);
490  }
491 
492 
493  if (empty($this->_running_vars['todo_assetids'])) {
494  if (empty($this->_running_vars['sub_job'])) {
495  // todo array is empty, and no dependant job left
496  $step_data['percent_done'] = 100;
497  $step_data['complete'] = TRUE;
498  } else {
499  // todo array is empty, but sub-hipo is processing the dependants
500  // so we'll continue until it completes
501  $step_data['complete'] = FALSE;
502  }
503  } else {
504  $total = count($this->_running_vars['todo_assetids']) + count($this->_running_vars['done_assetids']);
505  $step_data['percent_done'] =(count($this->_running_vars['done_assetids']) / $total) * 100;
506  $step_data['complete'] = FALSE;
507  }
508 
509  if (isset($this->_running_vars['no_status_integrity'][$assetid])) {
510  unset($this->_running_vars['no_status_integrity'][$assetid]);
511  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
512  }
513 
514  return TRUE;
515 
516  }//end processBundledAsset()
517 
518 
528  public function sendBundleWorkflowMessage(&$step_data, $prefix, $freestyle=FALSE)
529  {
530  $bundle = $GLOBALS['SQ_SYSTEM']->am->getAsset($this->_running_vars['bundle_assetid']);
531 
532  $ms = $GLOBALS['SQ_SYSTEM']->getMessagingService();
533  $msg_list = Array();
534  $msg_types = Array();
535 
536  // Convert from our message types to internal message type codes
537  $im_types = Array(
538  'start' => 'asset.workflow.bundle.invitation',
539  'progress' => 'asset.workflow.bundle.invitation.progress',
540  'approve' => 'asset.workflow.bundle.announce.approve',
541  'reject' => 'asset.workflow.bundle.announce.reject',
542  'auto_approve_progress' => 'asset.workflow.bundle.started',
543  );
544 
545  $msg_types = $this->_getRequiredBundleMessages($this->_running_vars['bundle_current_status'], $this->_running_vars['new_status']);
546 
547  if (count($msg_types) > 0) {
548  foreach ($msg_types as $msg_type) {
549  if (empty($this->_running_vars['msg_filters'][$msg_type]) === FALSE) {
550  foreach ($this->_running_vars['msg_filters'][$msg_type] as $userid => $assets) {
551  $asset_list_lines = Array();
552 
553  foreach ($assets as $assetid) {
554  $workflow_url = $this->_getBackendScreenKeywordReplacement($assetid, 'workflow');
555  $preview_url = $this->_getBackendScreenKeywordReplacement($assetid, 'preview');
556 
557  $asset_info = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo($assetid);
558  $format_line = '<a href="'.$workflow_url.'">'.$asset_info[$assetid]['name'].' (Id: #'.$assetid.')</a> [<a href="'.$preview_url.'">Preview</a>]';
559 
560  $asset_list_lines[] = $format_line;
561 
562  }//end foreach asset
563 
564  $body = trim($bundle->attr($msg_type.'_workflow_msg'));
565  $subject = trim($bundle->attr($msg_type.'_workflow_subject'));
566  $keywords = extract_keywords($body);
567 
568  $replacements = Array();
569 
570  // Bundle keywords
571  $replacements['bundle_reject_url'] = $this->_getBackendScreenKeywordReplacement($bundle->id, 'workflow').'&asset_version='.$bundle->version.'&workflow_link_action=reject';
572  $replacements['bundle_approve_url'] = $this->_getBackendScreenKeywordReplacement($bundle->id, 'workflow').'&asset_version='.$bundle->version.'&workflow_link_action=approve';
573  $replacements['bundle_workflow_url'] = $this->_getBackendScreenKeywordReplacement($bundle->id, 'workflow');
574  $replacements['bundle_name'] = $bundle->name;
575  $replacements['bundle_assetid'] = $bundle->id;
576  $replacements['new_status'] = $bundle->getStatus()->getDescription();
577 
578  // Asset list
579  if (count($asset_list_lines) > 0) {
580  $replacements['asset_list'] = '<ul><li>'.implode('</li><li>', $asset_list_lines).'</li></ul>';
581  } else {
582  $replacements['asset_list'] = '';
583  }
584 
585  // User keywords
586  $replacements['workflow_user'] = $GLOBALS['SQ_SYSTEM']->user->short_name;
587  $replacements['workflow_user_first_name'] = $GLOBALS['SQ_SYSTEM']->user->attr('first_name');
588  $replacements['workflow_user_last_name'] = $GLOBALS['SQ_SYSTEM']->user->attr('last_name');
589  $replacements['workflow_user_email'] = $GLOBALS['SQ_SYSTEM']->user->attr('email');
590 
591  $msg = $ms->newMessage(Array($userid), $im_types[$msg_type], $replacements);
592  if ($subject !== '') {
593  $msg->subject = $subject;
594  }
595  if ($body !== '') {
596  $msg->body = $body;
597  }
598  $msg_list[] = $msg;
599  }//end foreach item in this filter
600 
601  }//end if this filter type was used
602 
603  }//end foreach message type
604 
605 
606  }//end if there are message types to take notice of
607 
608  if (count($msg_list) > 0) {
609  $ms->send($msg_list);
610  }
611 
612  $step_data['percent_done'] = 100;
613  $step_data['complete'] = TRUE;
614 
615  return TRUE;
616 
617  }//end sendBundleWorkflowMessage()
618 
619 
633  protected function _prepareStatusChangeHIPO($assetid, $new_status)
634  {
635  require_once(SQ_SYSTEM_ROOT.'/core/hipo/jobs/hipo_job_edit_status.inc');
636 
637  $init_hipo = new Hipo_Job_Edit_Status();
638  $options['auto_complete'] = TRUE;
639 
640  // Create a sub-job for this asset ID. Always dependants only.
641  // Also stop it from sending messages, because we will send out our
642  // own instead
643  $running_vars = Array(
644  'assetid' => $assetid,
645  'new_status' => $new_status,
646  'dependants_only' => TRUE,
647  'send_messages' => FALSE,
648  );
649 
650  if (array_key_exists('workflow_stream', $this->_running_vars) === TRUE) {
651  $running_vars['workflow_stream'] = $this->_running_vars['workflow_stream'];
652  }
653 
654  $init_hipo->setRunningVars($running_vars);
655  foreach ($options as $k => $v) {
656  $init_hipo->setOption($k, $v);
657  }
658 
659  // create our sub-sub-hipo thingy, until this job is completed, we need
660  // to process it in place of our todo assets
661  $code_name = $init_hipo->initialise($this->source_code_name);
662  if ($code_name) return $code_name;
663  return FALSE;
664 
665  }//end prepareStatusChangeHIPO()
666 
667 
677  protected function _getBundledAssets($bundle_assetid)
678  {
679  $linked_assets = Array();
680  $linked_asset_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($bundle_assetid, SQ_LINK_NOTICE);
681 
682  foreach ($linked_asset_links as $linked_asset_link) {
683  $linked_assets[] = $linked_asset_link['minorid'];
684  }
685 
686  return $linked_assets;
687 
688  }//end _getBundledAssets()
689 
690 
705  protected function _getNewAssetStatus($assetid, $bundle_status, $new_status, $workflow_stream='')
706  {
707  $status_changes = Array();
708 
709  // Sent the bundle asset...it changes to what it changes to
710  if ($assetid === $this->_running_vars['bundle_assetid']) {
711  return $new_status;
712  }
713 
714  $wfm = $GLOBALS['SQ_SYSTEM']->getWorkflowManager();
715 
716  $asset_status = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo(Array($assetid), '', FALSE, 'status');
717  $asset_status = (int)$asset_status[$assetid];
718 
719  $schemas = $wfm->getSchemas($assetid);
720 
721  switch ($bundle_status) {
722  case SQ_STATUS_UNDER_CONSTRUCTION:
723  if ($new_status === SQ_STATUS_UNDER_CONSTRUCTION) {
724  // Reinforcing "Editing" status
725  $status_changes = Array(
726  // Don't allow any backward changes, but otherwise
727  // get some assets up to speed
728  SQ_STATUS_ARCHIVED => SQ_STATUS_UNDER_CONSTRUCTION,
729  SQ_STATUS_UNDER_CONSTRUCTION => NULL,
730  SQ_STATUS_PENDING_APPROVAL => NULL,
731  SQ_STATUS_APPROVED => NULL,
732  SQ_STATUS_LIVE => SQ_STATUS_EDITING,
733  SQ_STATUS_LIVE_APPROVAL => NULL,
734  SQ_STATUS_EDITING => NULL,
735  SQ_STATUS_EDITING_APPROVAL => NULL,
736  SQ_STATUS_EDITING_APPROVED => NULL,
737  );
738 
739  } else if ($new_status === SQ_STATUS_PENDING_APPROVAL) {
740  // Changing from "Editing" to "Approving".
741  $status_changes = Array(
742  // Archived => Pending Approval is a known error
743  // So is Live => Safe Edit Pending - setting to "Up for Review"
744  // is not the best move here since we should have been in Editing
745  // status before, which means we should be in Safe Edit at this point.
746  // Otherwise, only forward jumps in status allowed (ie.
747  // Approved statuses won't be rejected, but won't be made
748  // live either)
749  SQ_STATUS_ARCHIVED => SQ_STATUS_PENDING_APPROVAL,
750  SQ_STATUS_UNDER_CONSTRUCTION => SQ_STATUS_PENDING_APPROVAL,
751  SQ_STATUS_PENDING_APPROVAL => NULL,
752  SQ_STATUS_APPROVED => NULL,
753  SQ_STATUS_LIVE => SQ_STATUS_EDITING_APPROVAL,
754  SQ_STATUS_LIVE_APPROVAL => NULL,
755  SQ_STATUS_EDITING => SQ_STATUS_EDITING_APPROVAL,
756  SQ_STATUS_EDITING_APPROVAL => NULL,
757  SQ_STATUS_EDITING_APPROVED => NULL,
758  );
759 
760  if (count($schemas) === 0) {
761  // There's actually no workflow here, so we can jump
762  // to Live where we can
763  // EXCEPT: Safe Edit - can only jump to S/E Approved
764  // (since changing to Live is a cancelling).
765  // AND: Safe Edit Approved - no change since this is
766  // still valid when no workflow exists
767 
768  // Valid changes
769  $status_changes[SQ_STATUS_UNDER_CONSTRUCTION] = SQ_STATUS_LIVE;
770  $status_changes[SQ_STATUS_EDITING] = SQ_STATUS_EDITING_APPROVED;
771 
772  // This is still an error condition...
773  $status_changes[SQ_STATUS_ARCHIVED] = SQ_STATUS_LIVE;
774  $status_changes[SQ_STATUS_LIVE] = SQ_STATUS_EDITING_APPROVED;
775 
776  // The remainder are pretty much FIXME statuses without schemas,
777  // so don't know whether it will error or not, but oh well
778  $status_changes[SQ_STATUS_PENDING_APPROVAL] = SQ_STATUS_APPROVED;
779  $status_changes[SQ_STATUS_APPROVED] = SQ_STATUS_LIVE;
780  $status_changes[SQ_STATUS_EDITING_APPROVAL] = SQ_STATUS_EDITING_APPROVED;
781 
782  } else if ($wfm->testPublish($assetid, $GLOBALS['SQ_SYSTEM']->currentUserId(), $workflow_stream) === TRUE) {
783  // We would complete this workflow in one go
784 
785  // Valid changes
786  $status_changes[SQ_STATUS_UNDER_CONSTRUCTION] = SQ_STATUS_APPROVED;
787  $status_changes[SQ_STATUS_PENDING_APPROVAL] = SQ_STATUS_APPROVED;
788  $status_changes[SQ_STATUS_EDITING] = SQ_STATUS_EDITING_APPROVED;
789  $status_changes[SQ_STATUS_EDITING_APPROVAL] = SQ_STATUS_EDITING_APPROVED;
790 
791  // This is still an error condition...
792  $status_changes[SQ_STATUS_ARCHIVED] = SQ_STATUS_APPROVED;
793  $status_changes[SQ_STATUS_LIVE] = SQ_STATUS_EDITING_APPROVED;
794 
795  }//end if workflow
796 
797  } else if ($new_status === SQ_STATUS_APPROVED) {
798  // Changing from "Editing" to "Approved"
799  // All possible workflows pre-determined to complete in one go.
800  // Those assets in a workflow can go into their "approved to go live" status.
801 
802  $status_changes = Array(
803  // Archived => Approved is a known error
804  // Pending "from" statuses are probably a FIXME since we wouldn't
805  // have offered a bundle status of Approved if we needed workflow.
806  SQ_STATUS_ARCHIVED => SQ_STATUS_APPROVED,
807  SQ_STATUS_UNDER_CONSTRUCTION => SQ_STATUS_APPROVED,
808  SQ_STATUS_PENDING_APPROVAL => SQ_STATUS_APPROVED,
809  SQ_STATUS_APPROVED => NULL,
810  SQ_STATUS_LIVE => NULL,
811  SQ_STATUS_LIVE_APPROVAL => SQ_STATUS_LIVE,
812  SQ_STATUS_EDITING => SQ_STATUS_EDITING_APPROVED,
813  SQ_STATUS_EDITING_APPROVAL => SQ_STATUS_EDITING_APPROVED,
814  SQ_STATUS_EDITING_APPROVED => NULL,
815  );
816 
817  if (count($schemas) === 0) {
818  // If we have no workflow, just push them live
819  // (but not Safe Edit Approved, as this is valid when
820  // there is no workflow)
821 
822  // Valid changes
823  $status_changes[SQ_STATUS_UNDER_CONSTRUCTION] = SQ_STATUS_LIVE;
824 
825  // This is still an error condition...
826  $status_changes[SQ_STATUS_ARCHIVED] = SQ_STATUS_LIVE;
827 
828  // Still very much FIXME, but oh well
829  $status_changes[SQ_STATUS_PENDING_APPROVAL] = SQ_STATUS_LIVE;
830  $status_changes[SQ_STATUS_APPROVED] = SQ_STATUS_LIVE;
831  $status_changes[SQ_STATUS_EDITING_APPROVAL] = SQ_STATUS_EDITING_APPROVED;
832 
833  }//end if workflow is applied
834 
835  } else if ($new_status === SQ_STATUS_LIVE) {
836  // Changing from "Editing" to "Live" since no assets have workflow
837  // Make Live, whatever the consequencess
838 
839  $status_changes = Array(
840  // Archived => Live is a known error
841  // Pending => Live statuses are probably a FIXME since we
842  // wouldn't have offered the bundle status if we had workflow
843  // Safe Edit statuses can only safely go to Safe Edit Approved,
844  // since a move to Live should be and Safe Edit => Live is
845  // actually going backwards
846  SQ_STATUS_ARCHIVED => SQ_STATUS_LIVE,
847  SQ_STATUS_UNDER_CONSTRUCTION => SQ_STATUS_LIVE,
848  SQ_STATUS_PENDING_APPROVAL => SQ_STATUS_LIVE,
849  SQ_STATUS_APPROVED => SQ_STATUS_LIVE,
850  SQ_STATUS_LIVE => NULL,
851  SQ_STATUS_LIVE_APPROVAL => SQ_STATUS_LIVE,
852  SQ_STATUS_EDITING => SQ_STATUS_EDITING_APPROVED,
853  SQ_STATUS_EDITING_APPROVAL => SQ_STATUS_EDITING_APPROVED,
854  SQ_STATUS_EDITING_APPROVED => SQ_STATUS_LIVE,
855  );
856 
857  }//end if status
858 
859  break;
860 
861  case SQ_STATUS_PENDING_APPROVAL:
862  if ($new_status === SQ_STATUS_PENDING_APPROVAL) {
863  // Reinforce "Approving" status
864  // Progress the workflow
865 
866  $status_changes = Array(
867  // Archived => Pending is a known error
868  // Live => Safe Edit Pending is a known error, since we actually
869  // have to jump to Safe Edit first
870  SQ_STATUS_ARCHIVED => SQ_STATUS_PENDING_APPROVAL,
871  SQ_STATUS_UNDER_CONSTRUCTION => SQ_STATUS_PENDING_APPROVAL,
872  SQ_STATUS_PENDING_APPROVAL => SQ_STATUS_PENDING_APPROVAL,
873  SQ_STATUS_APPROVED => NULL,
874  SQ_STATUS_LIVE => SQ_STATUS_EDITING_APPROVAL,
875  SQ_STATUS_LIVE_APPROVAL => SQ_STATUS_LIVE_APPROVAL,
876  SQ_STATUS_EDITING => SQ_STATUS_EDITING_APPROVAL,
877  SQ_STATUS_EDITING_APPROVAL => SQ_STATUS_EDITING_APPROVAL,
878  SQ_STATUS_EDITING_APPROVED => NULL,
879  );
880 
881  if (count($schemas) === 0) {
882  // If no workflow, then we're pretty much stuck
883  // since sending no-workflow assets to Live on the basis
884  // of a null change of status seems incorrect
885  $status_changes = Array();
886 
887  } else if ($wfm->testPublish($assetid, $GLOBALS['SQ_SYSTEM']->currentUserId()) === TRUE) {
888  // We would complete this workflow on the next time around
889 
890  // Valid changes
891  $status_changes[SQ_STATUS_UNDER_CONSTRUCTION] = SQ_STATUS_APPROVED;
892  $status_changes[SQ_STATUS_PENDING_APPROVAL] = SQ_STATUS_APPROVED;
893  $status_changes[SQ_STATUS_EDITING] = SQ_STATUS_EDITING_APPROVED;
894  $status_changes[SQ_STATUS_EDITING_APPROVAL] = SQ_STATUS_EDITING_APPROVED;
895 
896  // This is still an error condition...
897  $status_changes[SQ_STATUS_ARCHIVED] = SQ_STATUS_APPROVED;
898 
899  }//end if workflow
900 
901  } else if ($new_status === SQ_STATUS_APPROVED) {
902  // "Approving" => "Approved" means we believe all bundled
903  // assets will finish their workflow this time around.
904 
905  $status_changes = Array(
906  // Archived => Approved is a known error
907  SQ_STATUS_ARCHIVED => SQ_STATUS_APPROVED,
908  SQ_STATUS_UNDER_CONSTRUCTION => SQ_STATUS_APPROVED,
909  SQ_STATUS_PENDING_APPROVAL => SQ_STATUS_APPROVED,
910  SQ_STATUS_APPROVED => NULL,
911  SQ_STATUS_LIVE => NULL,
912  SQ_STATUS_LIVE_APPROVAL => SQ_STATUS_LIVE,
913  SQ_STATUS_EDITING => SQ_STATUS_EDITING_APPROVED,
914  SQ_STATUS_EDITING_APPROVAL => SQ_STATUS_EDITING_APPROVED,
915  SQ_STATUS_EDITING_APPROVED => NULL,
916  );
917 
918  if (count($schemas) === 0) {
919  // If no workflow, then just push U/C assets to Live
920  $status_changes[SQ_STATUS_UNDER_CONSTRUCTION] = SQ_STATUS_LIVE;
921  }
922 
923  } else if ($new_status === SQ_STATUS_UNDER_CONSTRUCTION) {
924 
925  //Bug Fix #4829: we want to reject all assets in the bundle regardless of permission to
926  $this->_running_vars['no_status_integrity'][$assetid] = TRUE;
927 
928  // Reject changes, revert from "Approving" to "Editing":
929  // - Pre-live workflowed assets go back to Under Construction.
930  // - Post-live workflowed assets go back to Safe Editing.
931  // Live/Archived/UC have no change, as there are no changes to reject.
932  // Safe Editing will not be reverted to Live; keep it in edit mode
933  $status_changes = Array(
934  SQ_STATUS_ARCHIVED => NULL,
935  SQ_STATUS_UNDER_CONSTRUCTION => NULL,
936  SQ_STATUS_PENDING_APPROVAL => SQ_STATUS_UNDER_CONSTRUCTION,
937  SQ_STATUS_APPROVED => SQ_STATUS_UNDER_CONSTRUCTION,
938  SQ_STATUS_LIVE => NULL,
939  SQ_STATUS_LIVE_APPROVAL => SQ_STATUS_EDITING,
940  SQ_STATUS_EDITING => NULL,
941  SQ_STATUS_EDITING_APPROVAL => SQ_STATUS_EDITING,
942  SQ_STATUS_EDITING_APPROVED => SQ_STATUS_EDITING,
943  );
944 
945  }//end if status
946 
947  break;
948 
949  case SQ_STATUS_APPROVED:
950  if ($new_status === SQ_STATUS_LIVE) {
951  // "Approved" => "Live"; make live, regardless the consequences
952  // (except: Safe Editing status goes to Safe Edit Approved since
953  // going straight to Live is actually going backwards)
954  $status_changes = Array(
955  SQ_STATUS_ARCHIVED => NULL,
956  SQ_STATUS_UNDER_CONSTRUCTION => SQ_STATUS_LIVE,
957  SQ_STATUS_PENDING_APPROVAL => SQ_STATUS_LIVE,
958  SQ_STATUS_APPROVED => SQ_STATUS_LIVE,
959  SQ_STATUS_LIVE => NULL,
960  SQ_STATUS_LIVE_APPROVAL => SQ_STATUS_LIVE,
961  SQ_STATUS_EDITING => SQ_STATUS_EDITING_APPROVED,
962  SQ_STATUS_EDITING_APPROVAL => SQ_STATUS_EDITING_APPROVED,
963  SQ_STATUS_EDITING_APPROVED => SQ_STATUS_LIVE,
964  );
965 
966  } else if ($new_status === SQ_STATUS_UNDER_CONSTRUCTION) {
967  // Reject Changes; return to Editing. Whoops.
968  $status_changes = Array(
969  SQ_STATUS_ARCHIVED => NULL,
970  SQ_STATUS_UNDER_CONSTRUCTION => NULL,
971  SQ_STATUS_PENDING_APPROVAL => SQ_STATUS_UNDER_CONSTRUCTION,
972  SQ_STATUS_APPROVED => SQ_STATUS_UNDER_CONSTRUCTION,
973  SQ_STATUS_LIVE => NULL,
974  SQ_STATUS_LIVE_APPROVAL => SQ_STATUS_EDITING,
975  SQ_STATUS_EDITING => NULL,
976  SQ_STATUS_EDITING_APPROVAL => SQ_STATUS_EDITING,
977  SQ_STATUS_EDITING_APPROVED => SQ_STATUS_EDITING,
978  );
979 
980  }//end if status
981 
982  break;
983 
984  case SQ_STATUS_LIVE:
985  if ($new_status === SQ_STATUS_UNDER_CONSTRUCTION) {
986  // (re-)Start Editing - send those Live into Safe Edit,
987  // leave Safe Edit assets where they are, move others into
988  // U/C
989  $status_changes = Array(
990  SQ_STATUS_ARCHIVED => SQ_STATUS_UNDER_CONSTRUCTION,
991  SQ_STATUS_UNDER_CONSTRUCTION => NULL,
992  SQ_STATUS_PENDING_APPROVAL => NULL,
993  SQ_STATUS_APPROVED => NULL,
994  SQ_STATUS_LIVE => SQ_STATUS_EDITING,
995  SQ_STATUS_LIVE_APPROVAL => NULL,
996  SQ_STATUS_EDITING => NULL,
997  SQ_STATUS_EDITING_APPROVAL => NULL,
998  SQ_STATUS_EDITING_APPROVED => NULL,
999  );
1000 
1001  } else if ($new_status === SQ_STATUS_LIVE) {
1002  // Reinforcing "Editing" status
1003  $status_changes = Array(
1004  // Don't allow any backward changes, but otherwise
1005  // get some assets up to speed
1006  SQ_STATUS_ARCHIVED => NULL,
1007  SQ_STATUS_UNDER_CONSTRUCTION => NULL,
1008  SQ_STATUS_PENDING_APPROVAL => NULL,
1009  SQ_STATUS_APPROVED => SQ_STATUS_LIVE,
1010  SQ_STATUS_LIVE => NULL,
1011  SQ_STATUS_LIVE_APPROVAL => NULL,
1012  SQ_STATUS_EDITING => NULL,
1013  SQ_STATUS_EDITING_APPROVAL => NULL,
1014  SQ_STATUS_EDITING_APPROVED => SQ_STATUS_LIVE,
1015  );
1016 
1017  }//end if new status
1018 
1019  break;
1020 
1021  }//end switch old status
1022 
1023  return array_get_index($status_changes, $asset_status, NULL);
1024 
1025  }//end _getNewAssetStatus()
1026 
1027 
1045  protected function _filterMessages($assetid, Array &$job_messages, $filters)
1046  {
1047  if (count($filters) === 0) {
1048  return;
1049  }
1050 
1051  foreach ($job_messages as $msg_key => $message) {
1052  // If this is an invite message, then we may be interested
1053  // in adding this asset to the bundle list (since workflow
1054  // has progressed).
1055  foreach ($filters as $filter_name => $filter_msg_code) {
1056  if ($message->type === $filter_msg_code) {
1057  $msg_assetid = $message->parameters['assetid'];
1058 
1059  // Only interested if this is the one for the asset
1060  // itself, and not any dependants (there are no other
1061  // children we have to worry about here)
1062  if ((string)$msg_assetid === (string)$assetid) {
1063  foreach ($message->to as $to_user) {
1064  $this->_running_vars['msg_filters'][$filter_name][$to_user][] = $msg_assetid;
1065 
1066  }//end foreach to user in message
1067 
1068  }//end if not a dependant asset
1069 
1070  // Remove the message from the job list, so we just have the log
1071  // and approval messages left over.
1072  unset($job_messages[$msg_key]);
1073  break;
1074 
1075 
1076  }//end if invitation message
1077  }
1078 
1079  }//end foreach message
1080 
1081  }//end _filterInviteMessages()
1082 
1083 
1093  protected function _getRequiredBundleMessages($old_status, $new_status)
1094  {
1095  $msg_types = Array();
1096 
1097  // Determine the message(s) we need to send.
1098  switch ($old_status) {
1099  case SQ_STATUS_UNDER_CONSTRUCTION:
1100  switch ($new_status) {
1101  case SQ_STATUS_PENDING_APPROVAL:
1102  // Catch any possible approve messages that may appear
1103  // when the workflow may start (if the starting user can
1104  // also approve things)
1105  $msg_types = Array('start', 'approve', 'auto_approve_progress');
1106  break;
1107 
1108  }//end switch new status
1109  break;
1110 
1111  case SQ_STATUS_PENDING_APPROVAL:
1112  switch ($new_status) {
1113  case SQ_STATUS_UNDER_CONSTRUCTION:
1114  $msg_types = Array('reject');
1115  break;
1116 
1117  case SQ_STATUS_PENDING_APPROVAL:
1118  $msg_types = Array('approve', 'progress');
1119  break;
1120 
1121  case SQ_STATUS_APPROVED:
1122  $msg_types = Array('approve');
1123  break;
1124 
1125  }//end switch new status
1126  break;
1127 
1128  case SQ_STATUS_APPROVED:
1129  switch ($new_status) {
1130  case SQ_STATUS_UNDER_CONSTRUCTION:
1131  $msg_types = Array('reject');
1132  break;
1133 
1134  }//end switch new status
1135  break;
1136 
1137  }//end switch old status
1138 
1139  return $msg_types;
1140 
1141  }//end _getRequiredBundleMessages()
1142 
1143 
1152  protected function _getBackendScreenKeywordReplacement($assetid, $screen_name)
1153  {
1154  $replacement = '';
1155  $hrefs = $GLOBALS['SQ_SYSTEM']->am->getAssetBackendHref(Array($assetid => $screen_name), FALSE);
1156 
1157  if (empty($hrefs) === FALSE) {
1158  $href = str_replace('./', '', current($hrefs));
1159 
1160  $current_url = sq_web_path('root_url');
1161  if ($current_url === '') {
1162  $root_urls = explode("\n", SQ_CONF_SYSTEM_ROOT_URLS);
1163  $current_url = 'http://'.current($root_urls);
1164  }
1165 
1166  if (SQ_IN_LIMBO === TRUE) {
1167  $replacement = $current_url;
1168  $replacement .= (strpos($href, SQ_CONF_LIMBO_SUFFIX) !== FALSE) ? '/'.$href : '/'.SQ_CONF_LIMBO_SUFFIX.$href;
1169  } else {
1170  $replacement = $current_url;
1171  $replacement .= (strpos($href, SQ_CONF_BACKEND_SUFFIX) !== FALSE) ? '/'.$href : '/'.SQ_CONF_BACKEND_SUFFIX.$href;
1172  }
1173  }
1174 
1175  return $replacement;
1176 
1177  }//end _getBackendScreenKeywordReplacement()
1178 
1179 
1187  protected function _sendUserLogMessage($assetid, $message_body)
1188  {
1189  $version = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo(Array($assetid), 'asset', FALSE, 'version');
1190  $version = $version[$assetid];
1191 
1192  $ms = $GLOBALS['SQ_SYSTEM']->getMessagingService();
1193  $msg_reps = Array(
1194  'message' => $message_body,
1195  );
1196  $message = $ms->newMessage(Array(), 'asset.workflow.userlog', $msg_reps);
1197  $message->parameters['assetid'] = $assetid;
1198  $message->parameters['version'] = substr($version, 0, strrpos($version, '.'));
1199  $message->send();
1200 
1201  return TRUE;
1202 
1203  }//end _sendUserLogMessage()
1204 
1205 
1206 }//end class
1207 ?>