Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
workflow_bundle_edit_fns.inc
1 <?php
17 require_once SQ_INCLUDE_PATH.'/asset_edit/asset_edit_fns.inc';
18 
36 {
37 
38 
43  function __construct()
44  {
45  parent::__construct();
46 
47  }//end constructor
48 
49 
62  {
63  require_once SQ_INCLUDE_PATH.'/asset_static_screens/details.inc';
64  _paintDetailsCurrentStatus($asset, $o, $prefix);
65 
66  return FALSE;
67 
68  }//end paintCurrentStatus()
69 
70 
83  {
84  // Don't need write access to process status changes, since the changes
85  // allowed are handled by the asset status objects. So process it here
86  // where Matrix will (generally) not have a temper tantrum.
87  if ($this->processCustomStatusChange($asset, $o, $prefix) === TRUE) {
88  // Was a HIPO (for bundle status change) queued? If so, then point
89  // to the URL so it runs
90  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
91  $url = $hh->runQueuedJobs();
92  if (empty($url) === FALSE) $o->setRedirect($url);
93  return FALSE;
94  }
95 
96  // Otherwise, paint the status change - or the message saying you can't
97  // do it here; do it on the Workflow screen instead
98  if ((int)$asset->status === SQ_STATUS_PENDING_APPROVAL) {
99  $need_commit = FALSE;
100  $o->note(translate('asset_currently_in_workflow', $asset->getBackendHref('workflow')));
101  } else {
102  require_once SQ_INCLUDE_PATH.'/asset_static_screens/details.inc';
103  ob_start();
104  $need_commit = _paintDetailsChangeStatus($asset, $o, $prefix);
105  $status_output = ob_get_clean();
106 
107  $filter_output = '';
108  $found = preg_match('/<select.*"'.$prefix.'_change_status"[^>]*>.*<\/select>/U', $status_output, $select_matches);
109  if ($found === 1) {
110  $filter_output .= $select_matches[0].' ';
111  $found = preg_match('/<input.*"'.$prefix.'_change_status_all_children"[^>]*><label [^>]*>.*<\/label>/', $status_output, $cb_matches);
112  if ($found === 1) {
113  $filter_output .= $cb_matches[0].' ';
114  }
115 
116  $status_output = $filter_output;
117  }
118 
119  // Do we need to add the streams?
120  // (Do so if we're Editing, we can go to Approving, and there's at
121  // least one alternate stream available.)
122  $available_statuses = $asset->getAvailableStatii();
123  if (((int)$asset->status === SQ_STATUS_UNDER_CONSTRUCTION) && ((array_key_exists(SQ_STATUS_PENDING_APPROVAL, $available_statuses) === TRUE) || (array_key_exists(SQ_STATUS_APPROVED, $available_statuses) === TRUE))) {
124  $streams['workflow'] = $asset->getAllBundleStreams();
125 
126  if (count($streams) > 0) {
127  $bypass_streams = $asset->getAllBypassableBundleStreams();
128  foreach ($bypass_streams as $bypass_streamid) {
129  $streams['bypass'][$bypass_streamid] = $streams['workflow'][$bypass_streamid];
130  unset($streams['workflow'][$bypass_streamid]);
131  }
132 
133  // Get what the status change check-box looks like
134  // so we can use it to inject the stream drop-down
135  ob_start();
136  check_box($prefix.'_change_status_all_children');
137  $cascade_box = ob_get_clean();
138 
139  // Buffer the stream drop-down
140  ob_start();
141  $options = Array(
142  'bypass' => Array(),
143  'workflow' => Array(),
144  );
145 
146  if ($asset->isDefaultStreamBypassable() === TRUE) {
147  $options['bypass'] = Array('SQ_USE_DEFAULT' => 'Default Stream');
148  } else {
149  $options['workflow'] = Array('SQ_USE_DEFAULT' => 'Default Stream');
150  }
151 
152  $total_options = 1;
153  foreach (array_keys($streams) as $stream_type) {
154  $streams[$stream_type] = array_unique($streams[$stream_type]);
155  foreach ($streams[$stream_type] as $workflow_stream_name) {
156  $options[$stream_type][$workflow_stream_name] = $workflow_stream_name;
157  $total_options++;
158  }
159  }
160 
161  if ($total_options > 1) {
162  ob_start();
163  combo_box($prefix.'_change_status_stream', $options['workflow'], FALSE, Array(), 0, ' disabled="disabled" id="'.$prefix.'_change_status_stream_workflow"');
164  combo_box($prefix.'_change_status_stream', $options['bypass'], FALSE, Array(), 0, ' disabled="disabled" id="'.$prefix.'_change_status_stream_bypass"');
165  $cb = ob_get_clean();
166  echo translate('workflow_stream_using_workflow_stream', $cb);
167  } else {
168  // Only one option; hide the stream field and chuck it into a hidden field
169  $all_options = $options['bypass'] + $options['workflow'];
170  reset($all_options);
171  hidden_field($prefix.'_change_status_stream', key($all_options));
172  }
173  ?>
174  <script type="text/javascript">
175  //<![CDATA[
176  var status_cb = document.getElementById("<?php echo $prefix ?>_change_status");
177  var stream_wf_cb = document.getElementById("<?php echo $prefix ?>_change_status_stream_workflow");
178  var stream_byp_cb = document.getElementById("<?php echo $prefix ?>_change_status_stream_bypass");
179 
180  if (stream_wf_cb.options.length == 0) {
181  stream_wf_cb.style.display = 'none';
182  } else {
183  stream_byp_cb.style.display = 'none';
184  }
185 
186  status_cb.onchange = function() {
187  if ((this.value & <?php echo SQ_SC_STATUS_PENDING ?>) > 0) {
188  stream_wf_cb.disabled = false;
189  stream_wf_cb.style.display = 'inline';
190  stream_byp_cb.style.display = 'none';
191  } else {
192  stream_wf_cb.disabled = true;
193  }
194 
195  if ((this.value & <?php echo SQ_SC_STATUS_ALL_APPROVED ?>) > 0) {
196  stream_byp_cb.disabled = false;
197  stream_byp_cb.style.display = 'inline';
198  stream_wf_cb.style.display = 'none';
199  } else {
200  stream_byp_cb.disabled = true;
201  }
202  }
203  // ]]></script>
204  <?php
205  $stream_box = ob_get_clean();
206  echo str_replace($cascade_box, $stream_box.$cascade_box, $status_output);
207  if (isset($this->_tmp['incomplete_metadata'])) {
208  $new_status = isset($_POST[$prefix.'_change_status']) ? ' to \''.get_status_description($_POST[$prefix.'_change_status']).'\'' : '';
209  echo "<p>".translate('cannot_change_bundle_status_metadata_incomplete', $new_status);
210  foreach (array_keys($this->_tmp['incomplete_metadata']) as $incomplete_meta_assetid) {
211  $assetinfo = get_asset_tag_line($incomplete_meta_assetid, 'metadata');
212  echo "<br />$assetinfo";
213  }
214  echo "</p>";
215  }
216  } else {
217  echo $status_output;
218  }
219  } else {
220  echo $status_output;
221  }
222  }
223 
224  return $need_commit;
225 
226  }//end paintCustomStatusChange()
227 
228 
247  {
248  if (isset($_POST[$prefix.'_change_status'])) {
249  $dependants_only = (isset($_POST[$prefix.'_change_status_all_children']) && $_POST[$prefix.'_change_status_all_children']) ? FALSE : TRUE;
250  if ($_POST[$prefix.'_change_status'] > 0 || !$dependants_only) {
251  $new_status = 0;
252  if ($_POST[$prefix.'_change_status'] == 0 && !$dependants_only) {
253  $new_status = $asset->status;
254  } else if ($_POST[$prefix.'_change_status'] > 0) {
255  $new_status = $_POST[$prefix.'_change_status'];
256  }
257  // before we try to change the asset status lets see if the
258  // required metadata fields are set or else notify user abt it
259  $this->_checkRequiredMetadataComplete($asset);
260 
261  if (!isset($this->_tmp['incomplete_metadata'])) {
262  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
263  $vars = Array(
264  'bundle_assetid' => $asset->id,
265  'new_status' => $new_status,
266  );
267  if (isset($_POST[$prefix.'_change_status_stream'])) {
268  if ($_POST[$prefix.'_change_status_stream'] !== 'SQ_USE_DEFAULT') {
269  $vars['workflow_stream'] = $_POST[$prefix.'_change_status_stream'];
270  }
271  }
272  $hh->queueHipo('hipo_job_edit_bundled_assets_status', $vars);
273  return TRUE;
274  }
275  }
276  }
277 
278  return FALSE;
279 
280  }//end processCustomStatusChange()
281 
282 
296  {
297  $ok = FALSE;
298 
299  require_once SQ_INCLUDE_PATH.'/asset_static_screens/details.inc';
300  ob_start();
301  $need_commit = _paintDetailsFutureStatusCurrent($asset, $o, $prefix);
302  $ok = $ok || $need_commit;
303  $current_fs_contents = ob_get_clean();
304 
305  ob_start();
306  $need_commit = _paintDetailsFutureStatusNew($asset, $o, $prefix);
307  $ok = $ok || $need_commit;
308  $new_fs_contents = ob_get_clean();
309 
310  // Only show current contents if there are set FS jobs
311  if (empty($current_fs_contents) === FALSE) {
312  $o->openField(translate('scheduled_future_status_change'), 'new_line');
313  echo $current_fs_contents;
314  $o->closeField();
315  }
316 
317  // Only show Add FS section if write access allowed
318  if ($asset->writeAccess()) {
319  $o->openField(translate('add_new_future_status'), 'new_line');
320  echo $new_fs_contents;
321  $o->closeField();
322  }//end if
323 
324  return $ok;
325 
326  }//end paintFutureStatus()
327 
328 
339  {
340  require_once SQ_INCLUDE_PATH.'/asset_static_screens/details.inc';
341  $need_commit = _processDetailsFutureStatusNew($asset, $o, $prefix);
342 
343  return $need_commit;
344 
345  }//end processFutureStatus()
346 
347 
357  public function paintWorkflow(Workflow_Bundle $asset, Backend_Outputter $o, $prefix)
358  {
359  // Cheat the system, since we shouldn't need write access
360  // so long as we have the right permissions to approve workflow
361  if ($this->processWorkflow($asset, $o, $prefix) === TRUE) {
362  // Was a HIPO (for bundle status change) queued? If so, then point
363  // to the URL so it runs
364  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
365  $url = $hh->runQueuedJobs();
366  if (empty($url) === FALSE) $o->setRedirect($url);
367  return FALSE;
368  }
369 
370  // Otherwise, paint the approval interface - or the message saying you
371  // can't do it here because no workflow is running
372  if ((int)$asset->status === SQ_STATUS_PENDING_APPROVAL) {
373  if ($this->showIfCanApprove($asset) === TRUE) {
374  $o->openField(translate('log_message'));
375  text_area($prefix.'_workflow_new_log_message', '', 60, 6);
376  if ($this->bundleRequiresComment($asset) === TRUE) {
377  $comment_button_js = "elt = document.getElementById('".$prefix."_workflow_new_log_message'); if (elt && elt.value.replace(".'/^\s+|\s+$/g'.", '').length == 0) { alert(js_translate('must_enter_comment_error')); } else { submit_form(); }";
378  $o->note(translate('workflow_must_enter_reason_for_decision_bundle'));
379  } else {
380  $comment_button_js = 'submit_form();';
381  $o->note(translate('workflow_may_enter_reason_for_decision'));
382  }
383  $o->closeField();
384  $o->openField('');
385  $button_js = 'document.getElementById("'.$prefix.'_workflow_new_status").value = %status%; '.$comment_button_js;
386 
387  hidden_field($prefix.'_workflow_new_status', '0');
388  $available_statuses = $asset->getAvailableStatii();
389 
390  $reject_status = NULL;
391  $approve_status = NULL;
392 
393  foreach ($available_statuses as $new_status => $status_text) {
394  if ((int)$new_status < (int)$asset->status) {
395  $reject_status = Array($new_status => $status_text);
396  } else {
397  $approve_status = Array($new_status => $status_text);
398  }
399  }
400 
401  // Put the approve button first, if any
402  if ($approve_status !== NULL) {
403  normal_button($prefix.'_workflow_status_update_approve', current($approve_status), str_replace('%status%', (string)(key($approve_status)), $button_js));
404  }
405 
406  if ($reject_status !== NULL) {
407  normal_button($prefix.'_workflow_status_update_reject', current($reject_status), str_replace('%status%', (string)(key($reject_status)), $button_js));
408  }
409  if (isset($this->_tmp['incomplete_metadata'])) {
410  $new_status = isset($_POST[$prefix.'_workflow_new_status']) ? ' to \''.get_status_description($_POST[$prefix.'_workflow_new_status']).'\'' : '';
411  echo "<p>".translate('cannot_change_bundle_status_metadata_incomplete', $new_status);
412  foreach (array_keys($this->_tmp['incomplete_metadata']) as $incomplete_meta_assetid) {
413  $assetinfo = get_asset_tag_line($incomplete_meta_assetid, 'metadata');
414  echo "<br />$assetinfo";
415  }
416  echo "</p>";
417  }
418 
419  $o->closeField();
420  } else {
421  $o->openField(translate('workflow_status'));
422  echo translate('workflow_bundle_not_current_step');
423  $o->closeField();
424  }
425  } else {
426  $o->openField(translate('workflow_status'));
427  echo translate('workflow_not_running_bundle');
428  $o->closeField();
429  }
430 
431  return FALSE;
432 
433  }//end paintWorkflow()
434 
435 
450  public function processWorkflow(Workflow_Bundle $asset, Backend_Outputter $o, $prefix)
451  {
452  if ($this->showIfCanApprove($asset) === FALSE) {
453  return FALSE;
454  }
455 
456  if (isset($_POST[$prefix.'_workflow_new_status'])) {
457  $new_status = (int)$_POST[$prefix.'_workflow_new_status'];
458  $log_message = array_get_index($_POST, $prefix.'_workflow_new_log_message', '');
459 
460  // before we try to change the asset status lets see if the
461  // required metadata fields are set or else notify user abt it
462  // if we are rejecting the workflow then its alright but
463  // don't approve the changes if the metadata is gone missing
464  if (!($new_status & SQ_STATUS_UNDER_CONSTRUCTION)) $this->_checkRequiredMetadataComplete($asset);
465 
466  if (!isset($this->_tmp['incomplete_metadata'])) {
467  if ($new_status > 0) {
468  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
469  $vars = Array(
470  'bundle_assetid' => $asset->id,
471  'new_status' => $new_status,
472  'log_message' => $log_message,
473  );
474  $hh->queueHipo('hipo_job_edit_bundled_assets_status', $vars);
475  return TRUE;
476  }
477  }
478  }
479 
480  return FALSE;
481 
482  }//end processWorkflow()
483 
484 
496  public function showIfCanApprove(Workflow_Bundle $asset)
497  {
498  $wfm = $GLOBALS['SQ_SYSTEM']->getWorkflowManager();
499  $current_userid = $GLOBALS['SQ_SYSTEM']->currentUserId();
500 
501  $bundled_asset_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_NOTICE);
502  foreach ($bundled_asset_links as $linkid => $bundled_asset_link) {
503  $bundled_assetid = $bundled_asset_link['minorid'];
504  $approvers = $wfm->whoCanPublish($bundled_assetid);
505 
506  // If the current user is in the workflow's current step, then
507  // all is good - there is something to approve
508  if (in_array($current_userid, $approvers) === TRUE) {
509  return TRUE;
510  } else {
511  $bundled_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($bundled_assetid);
512  if ($bundled_asset->adminAccess() === TRUE) {
513  // We have admin access to the bundled asset
514  return TRUE;
515  }
516  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($bundled_asset);
517  unset($bundled_asset);
518  }
519  }
520 
521  return FALSE;
522 
523  }//end showIfCanApprove()
524 
525 
538  public function bundleRequiresComment(Workflow_Bundle $asset)
539  {
540  $wfm = $GLOBALS['SQ_SYSTEM']->getWorkflowManager();
541  $current_userid = $GLOBALS['SQ_SYSTEM']->currentUserId();
542 
543  $bundled_asset_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_NOTICE);
544  foreach ($bundled_asset_links as $linkid => $bundled_asset_link) {
545  $bundled_assetid = $bundled_asset_link['minorid'];
546 
547  // If the current user would be required to enter a comment, then
548  // we don't need to go any further - the bundle needs a comment
549  if ($wfm->requiresComment($bundled_assetid, $current_userid) === TRUE) {
550  return TRUE;
551  }
552  }
553 
554  return FALSE;
555 
556  }//end showIfCanApprove()
557 
558 
567  private function _checkRequiredMetadataComplete(Workflow_Bundle $asset)
568  {
569  $links = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_NOTICE);
570  $mm = $GLOBALS['SQ_SYSTEM']->getMetadataManager();
571  $not_cool_assets = Array();
572 
573  foreach ($links as $link) {
574  $assetid = $link['minorid'];
575  if (!isset($this->_tmp['incomplete_metadata'][$assetid]) && !$mm->requiredFieldsComplete($assetid)) {
576  $this->_tmp['incomplete_metadata'][$assetid] = TRUE;
577  }
578  }//end foreach
579 
580  }//end _checkRequiredMetadataComplete
581 
582 
583 }//end class
584 
585 ?>