17 require_once SQ_CORE_PACKAGE_PATH.
'/folder/folder_edit_fns.inc';
18 require_once SQ_FUDGE_PATH.
'/general/datetime.inc';
41 parent::__construct();
42 $this->static_screens[
'details'][
'force_unlock'] = FALSE;
43 $this->static_screens[
'details'][
'lock_type'] =
'content';
44 unset($this->static_screens[
'workflow']);
45 unset($this->static_screens[
'metadataSchemas']);
46 unset($this->static_screens[
'metadata']);
54 $write_access = (boolean)$asset->
writeAccess(
'links');
55 $stream_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_TYPE_2,
'workflow_stream', TRUE);
58 hidden_field($prefix.
'_new_selected_stream',
'');
59 if ($write_access === FALSE) {
60 $selected_stream = NULL;
62 $selected_stream = $this->getCurrentStream($prefix);
63 if ($selected_stream !== NULL) {
64 $selected_stream = (string)$selected_stream->id;
65 hidden_field($prefix.
'_selected_stream', $selected_stream);
69 foreach ($stream_links as $stream_link) {
70 if ($stream_link[
'value'] ==
'default_stream') {
72 array_unshift($streamids, $stream_link[
'minorid']);
76 array_push($streamids, $stream_link[
'minorid']);
80 $streams_info = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo($streamids);
83 <table
class=
"sq-backend-table">
90 if ($write_access === TRUE) {
91 ?><col width=
"70" /><?php
96 <th><p><?php echo translate(
'edit_question'); ?></p></th>
97 <th><?php echo translate(
'stream_name'); ?></th>
98 <th><?php echo translate(
'workflow_summary'); ?></th>
100 if ($write_access === TRUE) {
101 ?><th align=
"center"><b><?php echo translate(
'delete_question'); ?></b></th><?php
110 foreach ($streamids as $streamid) {
111 $stream_info = $streams_info[$streamid];
112 $streamid = (string)$streamid;
117 $current_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($streamid, SQ_LINK_TYPE_2,
'workflow_step', TRUE,
'major', NULL, TRUE, FALSE);
119 if (count($current_links) > 0) {
120 echo
'<table width="100%" style="border-collapse: collapse">';
121 echo
'<thead><colgroup>';
122 echo
'<col width="200" /><col width="*" /><col width="250"/>';
123 echo
'</colgroup></thead><tbody>';
124 $current_step_num = 0;
125 foreach ($current_links as $link) {
126 $step_assetid = $link[
'minorid'];
131 $step_asset =& $GLOBALS[
'SQ_SYSTEM']->am->getAsset($step_assetid);
136 if ($current_step_num === count($current_links)) {
137 $border_style =
' style="border-bottom: 0;"';
140 echo
'<td'.$border_style.
'>';
141 echo
'<strong>'.$current_step_num.
'.</strong> '.$step_asset->name.
'</strong></td>';
143 echo
'<td'.$border_style.
'>';
144 $conditions = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($step_assetid, SQ_LINK_TYPE_2,
'workflow_step_condition', TRUE,
'major', NULL, TRUE);
146 if (count($conditions) === 0) {
147 echo
'<span class="sq-backend-warning">No conditions selected</span>';
149 if (($step_asset->attr(
'logic') ===
'all') || ($step_asset->attr(
'logic_num') == count($conditions))) {
152 echo
'<em>At least '.$step_asset->attr(
'logic_num').
' condition(s) of:</em> ';
156 $condition_names = Array();
157 foreach ($conditions as $condition) {
158 if (count($condition_names) > 3) {
159 $condition_names[] =
'...';
163 $userids = $GLOBALS[
'SQ_SYSTEM']->am->getAttributeValuesByName(
'userid',
'workflow_step_condition', Array($condition[
'minorid']));
164 $userid = $userids[$condition[
'minorid']];
165 $user_name = $GLOBALS[
'SQ_SYSTEM']->am->getAssetInfo($userid);
166 $condition_name = $user_name[$userid][
'name'].
' (Id: #'.$userid.
')';
168 if ($GLOBALS[
'SQ_SYSTEM']->am->isTypeDecendant($user_name[$userid][
'type_code'],
'user_group') === TRUE) {
169 $logic = $GLOBALS[
'SQ_SYSTEM']->am->getAttributeValuesByName(
'logic',
'workflow_step_condition', Array($condition[
'minorid']));
170 $logic_num = $GLOBALS[
'SQ_SYSTEM']->am->getAttributeValuesByName(
'logic_num',
'workflow_step_condition', Array($condition[
'minorid']));
171 if ($logic[$condition[
'minorid']] ===
'all') {
172 $condition_name =
'All of '.$condition_name;
174 $condition_name =
'At least '.$logic_num[$condition[
'minorid']].
' of '.$condition_name;
178 $condition_names[] = $condition_name;
180 echo implode(
'; ', $condition_names);
184 echo
'<td'.$border_style.
'><div style="text-align: right">';
185 $expiry = (int)$step_asset->attr(
'expiry_time');
186 $expiry_text = easy_time_total($expiry);
189 if ($step_asset->attr(
'escalate')) {
190 $esc_links = array_reverse($GLOBALS[
'SQ_SYSTEM']->am->getLinks($step_assetid, SQ_LINK_TYPE_2,
'workflow_step', TRUE,
'major', NULL, TRUE, FALSE));
191 echo translate(
'workflow_stream_escalation_msg', $expiry_text, count($esc_links));
193 echo translate(
'workflow_stream_reminder_sent_msg', $expiry_text);
202 echo
'</tbody></table>';
204 echo
'<span class="sq-backend-warning">No workflow defined</span>';
207 $workflow_summary = ob_get_clean();
209 $class_style =
'sq-table-row';
210 if ($selected_stream === $streamid) {
211 $class_style .=
' alt';
213 if ($alt_stream_num === 0) {
214 ?><tr
class=
"sq-table-row"><td
class=
"sq-backend-table-header-header" colspan=
"<?php echo 3 + ($write_access ? 1 : 0) ?>"><?php echo translate(
'default_stream'); ?></td></tr><?php
215 }
else if ($alt_stream_num === 1) {
216 ?><tr
class=
"sq-table-row"><td
class=
"sq-backend-table-header-header" colspan=
"<?php echo 3 + ($write_access ? 1 : 0) ?>"><?php echo translate(
'alternate_streams'); ?></td></tr><?php
219 <tr
class=
"<?php echo $class_style ?>">
220 <td><?php
if (($write_access === TRUE) && ($selected_stream !== $streamid)) {
221 ?><p><a href=
"#" onclick=
"document.getElementById('<?php echo $prefix; ?>_new_selected_stream').value = <?php echo $streamid ?>; document.main_form.submit(); return false;"><?php echo trim(sq_get_icon(sq_web_path(
'lib').
'/web/images/icons/edit_mode.png', 15, 15, $stream_info[
'name'], NULL,
' border="0"')); ?></a></p><?php
223 <td><p><strong><?php echo $stream_info[
'name'] ?></strong></p></td>
224 <td><?php echo $workflow_summary; ?></td>
226 if ($write_access === TRUE) {
227 if ($alt_stream_num === 0) {
228 ?><td align=
"center" class=
"sq-backend-table-header"></td><?php
230 ?><td align=
"center" class=
"sq-backend-table-header"><?php echo check_box($prefix.
'_delete_stream[]', $streamid, FALSE); ?></td><?php
240 if (count($streams_info) <= 1) {
241 ?><tr
class=
"sq-table-row"><td
class=
"sq-backend-table-header-header" colspan=
"<?php echo 3 + ($write_access ? 1 : 0) ?>"><?php echo translate(
'alternate_streams'); ?></td></tr><?php
242 ?><tr
class=
"sq-table-row"><td></td><td colspan=
"<?php echo 2 + ($write_access ? 1 : 0) ?>"><?php echo translate(
'workflow_stream_no_alternate_'.($write_access ?
'locked' :
'unlocked')); ?></td></tr><?php
245 if ($write_access === TRUE) {
246 ?><tr
class=
"sq-table-row"><td
class=
"sq-backend-table-header-header" colspan=
"4">Add New Workflow Stream</td></tr><?php
250 <td colspan=
"3"><?php
251 check_box($prefix.
'_new_stream',
'1', FALSE,
'document.getElementById("'.$prefix.
'_new_stream_name").disabled = !this.checked; if (this.checked == true) { document.getElementById("'.$prefix.
'_new_stream_name").focus() };');
252 label(translate(
'create_new_stream_called'), $prefix.
'_new_stream');
253 text_box($prefix.
'_new_stream_name',
'', 30, 0, FALSE,
' disabled="disabled"');
273 if ((
int)array_get_index($_POST, $prefix.
'_new_stream', 0) === 1) {
274 $new_stream_name = trim(array_get_index($_POST, $prefix.
'_new_stream_name',
''));
275 if ($new_stream_name ===
'')
return FALSE;
277 $GLOBALS[
'SQ_SYSTEM']->am->includeAsset(
'workflow_stream');
279 $schema_link = Array(
'asset' => &$asset,
'link_type' => SQ_LINK_TYPE_2,
'sort_order' => -1,
'is_dependant' => 1);
280 $new_stream->setAttrValue(
'name', $new_stream_name);
281 if (!$new_stream->create($schema_link))
return FALSE;
282 $_POST[$prefix.
'_new_selected_stream'] = $new_stream->id;
289 $remove_streams = array_get_index($_POST, $prefix.
'_delete_stream', Array());
290 foreach ($remove_streams as $remove_stream) {
291 $stream_link = $GLOBALS[
'SQ_SYSTEM']->am->getLinkByAsset($asset->id, $remove_stream, SQ_LINK_TYPE_2);
292 if (empty($stream_link) === FALSE) {
293 if ($stream_link[
'value'] !==
'default_stream') {
294 if (!$GLOBALS[
'SQ_SYSTEM']->am->deleteAssetLink($stream_link[
'linkid'])) {
297 if (array_get_index($_POST, $prefix.
'_selected_stream', NULL) === $remove_stream) {
298 unset($_POST[$prefix.
'_selected_stream']);
300 if (array_get_index($_POST, $prefix.
'_new_selected_stream', NULL) === $remove_stream) {
301 unset($_POST[$prefix.
'_new_selected_stream']);
326 $selected_stream = $this->getCurrentStream($prefix);
327 if ($selected_stream === NULL)
return FALSE;
329 $edit_fns = $selected_stream->getEditFns();
330 return $edit_fns->paintNewStep($selected_stream, $o, $prefix);
349 $selected_stream = $this->getPriorStream($prefix);
350 if ($selected_stream === NULL)
return FALSE;
352 $edit_fns = $selected_stream->getEditFns();
353 return $edit_fns->processNewStep($selected_stream, $o, $prefix);
373 $selected_stream = $this->getCurrentStream($prefix);
374 if ($selected_stream === NULL)
return FALSE;
376 $edit_fns = $selected_stream->getEditFns();
377 return $edit_fns->paintWorkflowSummary($selected_stream, $o, $prefix);
397 $selected_stream = $this->getPriorStream($prefix);
398 if ($selected_stream === NULL)
return FALSE;
400 $edit_fns = $selected_stream->getEditFns();
401 return $edit_fns->processWorkflowSummary($selected_stream, $o, $prefix);
420 $selected_stream = $this->getCurrentStream($prefix);
421 if ($selected_stream === NULL)
return FALSE;
423 $edit_fns = $selected_stream->getEditFns();
424 return $edit_fns->paintSteps($selected_stream, $o, $prefix);
444 $selected_stream = $this->getPriorStream($prefix);
445 if ($selected_stream === NULL)
return FALSE;
447 $edit_fns = $selected_stream->getEditFns();
448 return $edit_fns->processSteps($selected_stream, $o, $prefix);
466 $workflow_array[
'steps'] = Array();
467 $workflow_array[
'current_step'] = Array(
'1');
468 $workflow_array[
'complete'] = FALSE;
469 $workflow_array[
'schema_name'] = $asset->name;
470 $workflow_array[
'started'] = time();
471 $workflow_array[
'started_by'] = $GLOBALS[
'SQ_SYSTEM']->currentUserId();
474 $current_links = $GLOBALS[
'SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_TYPE_2,
'workflow_step', TRUE,
'major', NULL, TRUE, FALSE);
475 foreach ($current_links as $link_data) {
476 $step = $GLOBALS[
'SQ_SYSTEM']->am->getAsset($link_data[
'minorid']);
477 if (is_null($step))
continue;
478 $edit_fns = $step->getEditFns();
479 $workflow_array[
'steps'][$i] = Array();
480 if (!$edit_fns->generateWorkflowArray($step, $workflow_array[
'steps'][$i])) {
484 $workflow_array[
'steps'][$i][
'started'] = time();
488 return $workflow_array;
493 public function getPriorStream($prefix)
495 $selected_stream = array_get_index($_POST, $prefix.
'_selected_stream', NULL);
497 if ($selected_stream === NULL) {
500 return $GLOBALS[
'SQ_SYSTEM']->am->getAsset($selected_stream);
506 public function getCurrentStream($prefix)
508 $selected_stream = array_get_index($_POST, $prefix.
'_new_selected_stream', NULL);
510 if (empty($selected_stream) === TRUE) {
511 $selected_stream = array_get_index($_POST, $prefix.
'_selected_stream', NULL);
512 if (empty($selected_stream) === TRUE)
return NULL;
516 return $GLOBALS[
'SQ_SYSTEM']->am->getAsset($selected_stream);
521 public function hasSelectedCurrentStream(
Asset $asset, $prefix)
523 $selected_stream = $this->getCurrentStream($prefix);
524 return ($selected_stream !== NULL);
529 public function hasSelectedPriorStream(
Asset $asset, $prefix)
531 $selected_stream = $this->getPriorStream($prefix);
532 return ($selected_stream !== NULL);
546 $schema_treeids_sql =
'SELECT
547 treeid, assetid, granted, cascades
548 FROM (sq_ast_lnk_tree ta
549 JOIN sq_ast_lnk la ON ta.linkid = la.linkid
550 JOIN sq_ast_wflow wa ON la.minorid = wa.assetid)
551 WHERE wa.schemaid = :schemaid
553 SELECT * FROM (sq_ast_lnk_tree tb
554 JOIN sq_ast_lnk lb ON tb.linkid = lb.linkid
555 JOIN sq_ast_wflow wb ON lb.minorid = wb.assetid)
556 WHERE wb.schemaid = wa.schemaid
557 AND length(ta.treeid) - LENGTH(tb.treeid) = :tree_size AND SUBSTR(ta.treeid, 1, LENGTH(ta.treeid) - :tree_size_1) = tb.treeid
558 AND wa.granted = wb.granted
559 AND wa.cascades = wb.cascades
560 ) ORDER BY length(treeid), treeid';
568 if (count($treeids) > 0) {
571 $num_pages = ceil(count($tree_tops) / $page_size);
572 $page_num = array_get_index($_POST, $prefix.
'_usage_page', 1);
573 $page_num = max($page_num, 1);
574 $page_num = min($page_num, $num_pages);
576 if ($num_pages == 1) {
577 $page_tag = translate(
'page_number', $page_num, $num_pages);
579 $page_tag = translate(
'page_number_with_pager', $page_num, $num_pages, $prefix.
'_usage_page');
581 $asset_count_tag = translate(
'item_range', ($page_num - 1) * $page_size + 1, min(count($tree_tops), $page_num * $page_size), count($tree_tops), strtolower(translate(
'trees')));
583 $tree_tops = array_slice($tree_tops, ($page_num - 1) * $page_size, $page_size);
586 'first' =>
'<<',
587 'previous' =>
'<',
590 'last' =>
'>>',
594 $links[
'first'] =
'<a title="'.translate(
'pagination_go_to_first').
'" style="text-decoration: none; color: #fff" href="#" onClick="return sq_pager_jump(\''.$prefix.
'_usage_page\', 1)">'.$links[
'first'].
'</a>';
595 $links[
'previous'] =
'<a title="'.translate(
'pagination_go_to_previous').
'" style="text-decoration: none; color: #fff" href="#" onClick="return sq_pager_jump(\''.$prefix.
'_usage_page\', '.($page_num - 1).
')">'.$links[
'previous'].
'</a>';
597 $links[
'first'] =
'<span title="'.translate(
'pagination_cannot_go_further_back').
'." style="color: #333">'.$links[
'first'].
'</span>';
598 $links[
'previous'] =
'<span title="'.translate(
'pagination_cannot_go_further_back').
'." style="color: #333">'.$links[
'previous'].
'</span>';
601 if ($page_num < $num_pages) {
602 $links[
'last'] =
'<a title="'.translate(
'pagination_go_to_last').
'" style="text-decoration: none; color: #fff" href="#" onClick="return sq_pager_jump(\''.$prefix.
'_usage_page\', '.$num_pages.
')">'.$links[
'last'].
'</a>';
603 $links[
'next'] =
'<a title="'.translate(
'pagination_go_to_next').
'" style="text-decoration: none; color: #fff" href="#" onClick="return sq_pager_jump(\''.$prefix.
'_usage_page\', '.($page_num + 1).
')">'.$links[
'next'].
'</a>';
605 $links[
'last'] =
'<span title="'.translate(
'pagination_cannot_go_further_forward').
'." style="color: #333">'.$links[
'last'].
'</span>';
606 $links[
'next'] =
'<span title="'.translate(
'pagination_cannot_go_further_forward').
'." style="color: #333">'.$links[
'next'].
'</span>';
609 hidden_field($prefix.
'_usage_page', $page_num); ?>
610 <table
class=
"sq-backend-table">
613 <td
class=
"sq-backend-table-header-header"><?php echo implode(
' ', $links) ?></td>
614 <td
class=
"sq-backend-table-header-header" colspan=
"2" style=
"text-align: right; font-weight: normal"><?php echo $asset_count_tag; ?></span></td>
616 <tr
class=
"sq-backend-table-row">
617 <th
class=
"sq-backend-table-cell"><?php echo translate(
'asset'); ?></th>
618 <th style=
"width: 15%" class=
"sq-backend-table-cell"><?php echo translate(
'granted_question') ?></th>
619 <th style=
"width: 15ex" class=
"sq-backend-table-cell"><?php echo translate(
'cascade_question') ?></th>
625 foreach ($tree_tops as $tt_assetid => &$tree_top_info) {
626 $root_tree = $tree_top_info;
627 unset($root_tree[
'sub_trees']);
628 $root_trees = array_merge(Array($root_tree), $tree_top_info[
'sub_trees']);
630 foreach ($root_trees as $root_assetid => &$tree_info) {
632 ?><tr
class=
"sq-backend-table-row">
633 <td
class=
"sq-backend-table-cell">
636 $tag_line = get_asset_tag_line($tree_info[
'assetid'],
'details');
638 echo ($tree_info[
'depth'] === 0 ?
'' :
'<span style="padding-left: '.($tree_info[
'depth']*5).
'ex">');
639 echo translate(
'asset_and_child_count_0', $tag_line);
640 echo ($tree_info[
'depth'] === 0 ?
'' :
'</span>');
643 <td
class=
"sq-backend-table-cell">
644 <strong><span style=
"color: <?php echo (($tree_info['granted'] == '0') ? 'red' : 'green'); ?>"><?php echo (($tree_info[
'granted'] ==
'0') ? translate(
'denied') : translate(
'applied')) ?></span></strong>
646 <td
class=
"sq-backend-table-cell">
647 <img src=
"<?php echo sq_web_path('lib'); ?>/web/images/<?php echo ($tree_info['cascades'] === '1' ? 'tick' : 'cross'); ?>.gif" width=
"15" height=
"15" style=
"vertical-align: middle;" alt=
"<?php echo translate($tree_info['cascades'] === '1' ? 'yes' : 'no'); ?>" />
662 $o->
note(translate(
'core_schema_usage_explanation'));
665 $o->
note(translate(
'core_schema_usage_no_assets'));
693 $used_assetids = Array();
695 $all_treeids = Array();
696 foreach ($treeids as $treeid) {
697 $all_treeids[$treeid[
'treeid']] = $treeid;
702 foreach ($all_treeids as $tree_info) {
703 $treeid = $tree_info[
'treeid'];
704 $treeid_copy = $treeid;
705 $top_parent = $treeid;
707 $used_sub_tree = FALSE;
709 while (empty($treeid_copy) === FALSE) {
710 if (isset($res[$treeid_copy]) === TRUE) {
711 if ($used_sub_tree === FALSE) {
712 $used_sub_tree = TRUE;
716 if (($used_sub_tree === TRUE) && (array_key_exists($treeid_copy, $all_treeids) === TRUE)) {
717 $top_parent = $treeid_copy;
721 $treeid_copy = substr($treeid_copy, 0, -SQ_CONF_ASSET_TREE_SIZE);
724 $res[$treeid] = $tree_info;
725 $res[$treeid][
'top_parent'] = $top_parent;
726 $res[$treeid][
'depth'] = $depth;
727 $res[$treeid][
'sub_trees'] = Array();
731 if (array_search($tree_info[
'assetid'], $used_assetids) === FALSE) {
732 $res[$treeid][
'dupe'] = FALSE;
733 $used_assetids[] = $tree_info[
'assetid'];
735 $res[$treeid][
'dupe'] = TRUE;
739 foreach ($res as $key => &$res_item) {
740 if ($res_item[
'dupe'] === TRUE) {
743 if ($res_item[
'depth'] > 0) {
744 $res[$res_item[
'top_parent']][
'sub_trees'][$res_item[
'treeid']] =& $res_item;
751 foreach ($res as $key => &$res_item) {
752 uksort($res_item[
'sub_trees'], create_function(
'$key1,$key2',
'return strcmp($key1, $key2);'));