Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
workflow_schema_edit_fns.inc
1 <?php
17 require_once SQ_CORE_PACKAGE_PATH.'/folder/folder_edit_fns.inc';
18 require_once SQ_FUDGE_PATH.'/general/datetime.inc';
19 
32 {
33 
34 
39  function __construct()
40  {
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']);
47 
48 
49  }//end constructor
50 
51 
52  public function paintWorkflowStreams(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
53  {
54  $write_access = (boolean)$asset->writeAccess('links');
55  $stream_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($asset->id, SQ_LINK_TYPE_2, 'workflow_stream', TRUE);
56  $streamids = Array();
57 
58  hidden_field($prefix.'_new_selected_stream', '');
59  if ($write_access === FALSE) {
60  $selected_stream = NULL;
61  } else {
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);
66  }
67  }
68 
69  foreach ($stream_links as $stream_link) {
70  if ($stream_link['value'] == 'default_stream') {
71  // Push the default stream into the front
72  array_unshift($streamids, $stream_link['minorid']);
73  } else {
74  // Push any other streams into the back, so the default will
75  // always be at the "front"
76  array_push($streamids, $stream_link['minorid']);
77  }
78  }
79 
80  $streams_info = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo($streamids);
81 
82  ?>
83  <table class="sq-backend-table">
84  <thead>
85  <colgroup>
86  <col width="70" />
87  <col />
88  <col />
89  <?php
90  if ($write_access === TRUE) {
91  ?><col width="70" /><?php
92  }
93  ?>
94  </colgroup>
95  <tr>
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>
99  <?php
100  if ($write_access === TRUE) {
101  ?><th align="center"><b><?php echo translate('delete_question'); ?></b></th><?php
102  }
103  ?>
104  </tr>
105  </thead>
106  <tbody>
107  <?php
108  // The default stream is the first one on the list
109  $alt_stream_num = 0;
110  foreach ($streamids as $streamid) {
111  $stream_info = $streams_info[$streamid];
112  $streamid = (string)$streamid;
113 
114  // Get an abbreviated summary of steps - less full than that
115  // of an edit order
116  ob_start();
117  $current_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($streamid, SQ_LINK_TYPE_2, 'workflow_step', TRUE, 'major', NULL, TRUE, FALSE);
118 
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'];
127 
128  // Okay, now at current depth, so increment step number;
129  $current_step_num++;
130 
131  $step_asset =& $GLOBALS['SQ_SYSTEM']->am->getAsset($step_assetid);
132 
133  echo '<tr>';
134 
135  $border_style = '';
136  if ($current_step_num === count($current_links)) {
137  $border_style = ' style="border-bottom: 0;"';
138  }
139 
140  echo '<td'.$border_style.'>';
141  echo '<strong>'.$current_step_num.'.</strong> '.$step_asset->name.'</strong></td>';
142 
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);
145 
146  if (count($conditions) === 0) {
147  echo '<span class="sq-backend-warning">No conditions selected</span>';
148  } else {
149  if (($step_asset->attr('logic') === 'all') || ($step_asset->attr('logic_num') == count($conditions))) {
150  // Nothing
151  } else {
152  echo '<em>At least '.$step_asset->attr('logic_num').' condition(s) of:</em> ';
153  }
154  }
155 
156  $condition_names = Array();
157  foreach ($conditions as $condition) {
158  if (count($condition_names) > 3) {
159  $condition_names[] = '...';
160  break;
161  }
162 
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.')';
167 
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;
173  } else {
174  $condition_name = 'At least '.$logic_num[$condition['minorid']].' of '.$condition_name;
175  }
176  }
177 
178  $condition_names[] = $condition_name;
179  }
180  echo implode('; ', $condition_names);
181 
182  echo '</td>';
183 
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);
187 
188  if ($expiry > 0) {
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));
192  } else {
193  echo translate('workflow_stream_reminder_sent_msg', $expiry_text);
194  }
195  }
196 
197  echo '</div></td>';
198  echo '</tr>';
199  }
200 
201  // Add a drop point after the last main step
202  echo '</tbody></table>';
203  } else {
204  echo '<span class="sq-backend-warning">No workflow defined</span>';
205  }
206 
207  $workflow_summary = ob_get_clean();
208 
209  $class_style = 'sq-table-row';
210  if ($selected_stream === $streamid) {
211  $class_style .= ' alt';
212  }
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
217  }
218  ?>
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
222  } ?></td>
223  <td><p><strong><?php echo $stream_info['name'] ?></strong></p></td>
224  <td><?php echo $workflow_summary; ?></td>
225  <?php
226  if ($write_access === TRUE) {
227  if ($alt_stream_num === 0) {
228  ?><td align="center" class="sq-backend-table-header"></td><?php
229  } else {
230  ?><td align="center" class="sq-backend-table-header"><?php echo check_box($prefix.'_delete_stream[]', $streamid, FALSE); ?></td><?php
231  }
232  }
233  ?>
234  </tr>
235  <?php
236  // After we have gone through once, the rest are non-default.
237  $alt_stream_num++;
238  }
239 
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
243  }
244 
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
247  ?>
248  <tr>
249  <td></td>
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"');
254  ?></td>
255  </tr>
256  <?php
257  }
258  ?>
259  </tbody>
260  </table>
261  <?php
262  return FALSE;
263 
264  }//end paintWorkflowStreams()
265 
266 
267  public function processWorkflowStreams(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
268  {
269  // need to have write access to make any changes
270  if (!$asset->writeAccess('links')) return FALSE;
271 
272  // Creating a stream
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;
276 
277  $GLOBALS['SQ_SYSTEM']->am->includeAsset('workflow_stream');
278  $new_stream = new 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;
283  }
284 
285  // Removing a stream - note that we cannot remove the default stream,
286  // and that removing a stream only removes it from the current schema,
287  // not delete it entirely. Therefore, it is possible for streams to be
288  // sitting in the trash if the last link is removed.
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'])) {
295  return FALSE;
296  }
297  if (array_get_index($_POST, $prefix.'_selected_stream', NULL) === $remove_stream) {
298  unset($_POST[$prefix.'_selected_stream']);
299  }
300  if (array_get_index($_POST, $prefix.'_new_selected_stream', NULL) === $remove_stream) {
301  unset($_POST[$prefix.'_new_selected_stream']);
302  }
303  }
304  }
305  }
306 
307  return TRUE;
308 
309  }//end processWorkflowStreams()
310 
311 
322  public function paintNewStep(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
323  {
324  if (!$asset->writeAccess('links')) return FALSE;
325 
326  $selected_stream = $this->getCurrentStream($prefix);
327  if ($selected_stream === NULL) return FALSE;
328 
329  $edit_fns = $selected_stream->getEditFns();
330  return $edit_fns->paintNewStep($selected_stream, $o, $prefix);
331 
332  }//end paintNewStep()
333 
334 
345  public function processNewStep(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
346  {
347  if (!$asset->writeAccess('links')) return FALSE;
348 
349  $selected_stream = $this->getPriorStream($prefix);
350  if ($selected_stream === NULL) return FALSE;
351 
352  $edit_fns = $selected_stream->getEditFns();
353  return $edit_fns->processNewStep($selected_stream, $o, $prefix);
354 
355  }//end processNewStep()
356 
357 
369  public function paintWorkflowSummary(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
370  {
371  if (!$asset->writeAccess('links')) return FALSE;
372 
373  $selected_stream = $this->getCurrentStream($prefix);
374  if ($selected_stream === NULL) return FALSE;
375 
376  $edit_fns = $selected_stream->getEditFns();
377  return $edit_fns->paintWorkflowSummary($selected_stream, $o, $prefix);
378 
379  }//end paintWorkflowSummary()
380 
381 
393  public function processWorkflowSummary(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
394  {
395  if (!$asset->writeAccess('links')) return FALSE;
396 
397  $selected_stream = $this->getPriorStream($prefix);
398  if ($selected_stream === NULL) return FALSE;
399 
400  $edit_fns = $selected_stream->getEditFns();
401  return $edit_fns->processWorkflowSummary($selected_stream, $o, $prefix);
402 
403  }//end processWorkflowSummary()
404 
405 
416  public function paintSteps(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
417  {
418  if (!$asset->writeAccess('links')) return FALSE;
419 
420  $selected_stream = $this->getCurrentStream($prefix);
421  if ($selected_stream === NULL) return FALSE;
422 
423  $edit_fns = $selected_stream->getEditFns();
424  return $edit_fns->paintSteps($selected_stream, $o, $prefix);
425 
426  }//end paintSteps()
427 
428 
439  public function processSteps(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
440  {
441  // need to have write access to make any changes
442  if (!$asset->writeAccess('links')) return FALSE;
443 
444  $selected_stream = $this->getPriorStream($prefix);
445  if ($selected_stream === NULL) return FALSE;
446 
447  $edit_fns = $selected_stream->getEditFns();
448  return $edit_fns->processSteps($selected_stream, $o, $prefix);
449 
450  }//end processSteps()
451 
452 
464  public function generateWorkflowArray(Asset $asset)
465  {
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();
472 
473  $i = 1;
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])) {
481  return FALSE;
482  }
483  if ($i == 1) {
484  $workflow_array['steps'][$i]['started'] = time();
485  }
486  $i++;
487  }
488  return $workflow_array;
489 
490  }//end generateWorkflowArray()
491 
492 
493  public function getPriorStream($prefix)
494  {
495  $selected_stream = array_get_index($_POST, $prefix.'_selected_stream', NULL);
496 
497  if ($selected_stream === NULL) {
498  return NULL;
499  } else {
500  return $GLOBALS['SQ_SYSTEM']->am->getAsset($selected_stream);
501  }
502 
503  }//end getCurrentStream();
504 
505 
506  public function getCurrentStream($prefix)
507  {
508  $selected_stream = array_get_index($_POST, $prefix.'_new_selected_stream', NULL);
509 
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;
513  } else {
514  }
515 
516  return $GLOBALS['SQ_SYSTEM']->am->getAsset($selected_stream);
517 
518  }//end getCurrentStream();
519 
520 
521  public function hasSelectedCurrentStream(Asset $asset, $prefix)
522  {
523  $selected_stream = $this->getCurrentStream($prefix);
524  return ($selected_stream !== NULL);
525 
526  }//end hasSelectedCurrentStream()
527 
528 
529  public function hasSelectedPriorStream(Asset $asset, $prefix)
530  {
531  $selected_stream = $this->getPriorStream($prefix);
532  return ($selected_stream !== NULL);
533 
534  }//end hasSelectedPriorStream()
535 
536 
537  //-- WORKFLOW SCHEMA USAGE --//
538 
539 
540  public function paintUsage(Workflow_Schema $asset, Backend_Outputter $o, $prefix)
541  {
542  $page_size = 10;
543 
544  $o->openRaw();
545 
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
552  AND NOT EXISTS (
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';
561 
562  $query = MatrixDAL::preparePdoQuery($schema_treeids_sql);
563  MatrixDAL::bindValueToPdo($query, 'schemaid', $asset->id);
564  MatrixDAL::bindValueToPdo($query, 'tree_size', SQ_CONF_ASSET_TREE_SIZE);
565  MatrixDAL::bindValueToPdo($query, 'tree_size_1', SQ_CONF_ASSET_TREE_SIZE);
566  $treeids = MatrixDAL::executePdoAssoc($query);
567 
568  if (count($treeids) > 0) {
569  $tree_tops = $this->_getTreeTops($asset, $treeids);
570 
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);
575 
576  if ($num_pages == 1) {
577  $page_tag = translate('page_number', $page_num, $num_pages);
578  } else {
579  $page_tag = translate('page_number_with_pager', $page_num, $num_pages, $prefix.'_usage_page');
580  }
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')));
582 
583  $tree_tops = array_slice($tree_tops, ($page_num - 1) * $page_size, $page_size);
584 
585  $links = Array(
586  'first' => '&lt;&lt;',
587  'previous' => '&lt;',
588  'page' => $page_tag,
589  'next' => '&gt;',
590  'last' => '&gt;&gt;',
591  );
592 
593  if ($page_num > 1) {
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>';
596  } else {
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>';
599  }
600 
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>';
604  } else {
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>';
607  }
608 
609  hidden_field($prefix.'_usage_page', $page_num); ?>
610  <table class="sq-backend-table">
611  <thead>
612  <tr>
613  <td class="sq-backend-table-header-header"><?php echo implode(' &nbsp; &nbsp; ', $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>
615  </tr>
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>
620  </tr>
621  </thead>
622  <tbody>
623  <?php
624 
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']);
629 
630  foreach ($root_trees as $root_assetid => &$tree_info) {
631 
632  ?><tr class="sq-backend-table-row">
633  <td class="sq-backend-table-cell">
634  <?php
635 
636  $tag_line = get_asset_tag_line($tree_info['assetid'], 'details');
637 
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>');
641 
642  ?></td>
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>
645  </td>
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'); ?>" />
648  </td>
649  </tr>
650  <?php
651  }//end foreach entry
652 
653  unset($tree_info);
654 
655  }//end foreach top tree
656  ?>
657 
658  </tbody>
659  </table>
660  <?php
661 
662  $o->note(translate('core_schema_usage_explanation'));
663 
664  } else {
665  $o->note(translate('core_schema_usage_no_assets'));
666  }
667 
668  $o->closeRaw();
669 
670  return FALSE;
671 
672  }//end paintUsage()
673 
674 
691  public function _getTreeTops(Workflow_Schema $asset, Array $treeids)
692  {
693  $used_assetids = Array();
694 
695  $all_treeids = Array();
696  foreach ($treeids as $treeid) {
697  $all_treeids[$treeid['treeid']] = $treeid;
698  }
699  unset($treeids);
700 
701  $res = Array();
702  foreach ($all_treeids as $tree_info) {
703  $treeid = $tree_info['treeid'];
704  $treeid_copy = $treeid;
705  $top_parent = $treeid;
706  $depth = 0;
707  $used_sub_tree = FALSE;
708 
709  while (empty($treeid_copy) === FALSE) {
710  if (isset($res[$treeid_copy]) === TRUE) {
711  if ($used_sub_tree === FALSE) {
712  $used_sub_tree = TRUE;
713  }
714  }
715 
716  if (($used_sub_tree === TRUE) && (array_key_exists($treeid_copy, $all_treeids) === TRUE)) {
717  $top_parent = $treeid_copy;
718  $depth++;
719  }
720 
721  $treeid_copy = substr($treeid_copy, 0, -SQ_CONF_ASSET_TREE_SIZE);
722  }
723 
724  $res[$treeid] = $tree_info;
725  $res[$treeid]['top_parent'] = $top_parent;
726  $res[$treeid]['depth'] = $depth;
727  $res[$treeid]['sub_trees'] = Array();
728 
729  // Have we seen this asset before? If so, let it go, but mark it
730  // to be dumped afterwards so we only have one of each asset
731  if (array_search($tree_info['assetid'], $used_assetids) === FALSE) {
732  $res[$treeid]['dupe'] = FALSE;
733  $used_assetids[] = $tree_info['assetid'];
734  } else {
735  $res[$treeid]['dupe'] = TRUE;
736  }
737  }
738 
739  foreach ($res as $key => &$res_item) {
740  if ($res_item['dupe'] === TRUE) {
741  unset($res[$key]);
742  } else {
743  if ($res_item['depth'] > 0) {
744  $res[$res_item['top_parent']]['sub_trees'][$res_item['treeid']] =& $res_item;
745  unset($res[$key]);
746  }
747  }
748  }
749 
750  // Sort each sub-tree top-to-bottom, to ensure correct tree order
751  foreach ($res as $key => &$res_item) {
752  uksort($res_item['sub_trees'], create_function('$key1,$key2', 'return strcmp($key1, $key2);'));
753  }
754 
755  unset($res_item);
756 
757  return $res;
758 
759  }//end _getTreeTops()
760 
761 
762 }//end class
763 
764 ?>