Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
asset_edit_interface.inc
1 <?php
18 // require_once 'XML/Tree.php';
19 require_once SQ_LIB_PATH.'/html_form/html_form.inc';
20 
21 
22 /*
23 * Used by both paint() and process() to determine the access that the current user
24 * has - set in _getAccess()
25 */
26 define('SQ_EI_READ', 1);
27 define('SQ_EI_WRITE', 2);
28 
37 {
38 
43  var $_type_code = '';
44 
49  var $_edit_fns = NULL;
50 
55  var $_dirs = Array();
56 
61  var $_screens = Array();
62 
67  var $_default_screen = '';
68 
69 
77  function Asset_Edit_Interface($type_code)
78  {
79  $this->_type_code = $type_code;
80 
81  $type_info = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($this->_type_code);
82  $asset_dir = SQ_SYSTEM_ROOT.'/'.$type_info['dir'];
83  $class_name = $this->_type_code.'_edit_fns';
84  require_once $asset_dir.'/'.$class_name.'.inc';
85  $this->_edit_fns = new $class_name();
86 
87  // check that the edit functions have a details tab or else
88  // we cant even create assets of this type let alone edit them
89  assert_isset($this->_edit_fns->static_screens['details'], translate('no_details_screen_defined', $type_code));
90 
91  $this->_dirs = Array($asset_dir);
92  $parent_type = $type_info['parent_type'];
93 
94  while ($parent_type != 'asset') {
95  $type_info = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($parent_type);
96  $this->_dirs[] = SQ_SYSTEM_ROOT.'/'.$type_info['dir'];
97  $parent_type = $type_info['parent_type'];
98  }
99 
100  // add the default for Asset
101  $this->_dirs[] = SQ_INCLUDE_PATH.'/asset_edit';
102 
103  if (!($file = $this->findFile('screens'))) return;
104 
105  try {
106  $root = new SimpleXMLElement($file, LIBXML_NOCDATA, TRUE);
107  } catch (Exception $e) {
108  throw new Exception('Unable to parse screen list file "'.$file.'": '.$e->getMessage());
109  }
110 
111  $this->_screens = Array();
112  foreach ($root->screen as $screen_node) {
113  $code_name = strtolower(preg_replace('/[^a-z_]/', '', (string)$screen_node->attributes()->code_name));
114  if (!$code_name) continue;
115 
116  $force_unlock = ((isset($screen_node->attributes()->force_unlock)) ? (string)$screen_node->attributes()->force_unlock : '1');
117 
118  $this->_screens[$code_name] = Array(
119  'name' => (string)$screen_node->attributes()->display_name,
120  'force_unlock' => ($force_unlock != '0'),
121  'lock_type' => (isset($screen_node->attributes()->lock_type)) ? (string)$screen_node->attributes()->lock_type : '',
122  'invisible' => (!empty($screen_node->attributes()->invisible)),
123  );
124 
125 
126  if (!empty($screen_node->attributes()->default)) {
127  $this->_default_screen = $code_name;
128  }
129  }//end for
130 
131  }//end constructor
132 
133 
140  function getScreens()
141  {
142  return $this->_screens;
143 
144  }//end getScreens()
145 
146 
156  function _determinePreviewUrl(&$owner, &$o)
157  {
158  // get the asset tree lineage
159  $asset_path = Array();
160  if (isset($_REQUEST['sq_asset_path'])) {
161  // asset map sends comma-separated assetids indicating the path
162  $matches = preg_split('|,([0-9]+:?),?|', $_REQUEST['sq_asset_path'], 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
163  for (reset($matches); NULL !== ($k = key($matches)); next($matches)) {
164  // if a match ends with the shadow id seperator, the next match
165  // is actually part of this match
166  if (substr($matches[$k], -1) == ':') {
167  $asset_path[] = $matches[$k].$matches[$k+1];
168  next($matches);
169  continue;
170  }
171 
172  $asset_path[] = $matches[$k];
173  }
174  } else {
175  if (SQ_IN_LIMBO) {
176  $url_lineage = $GLOBALS['SQ_SYSTEM']->am->getLineageFromURL();
177  foreach ($url_lineage as $asset_info) {
178  $asset_path[] = $asset_info['assetid'];
179  }
180  } else {
181  // asset map didn't send one (e.g initial matrix loading)
182  // pretend it did by making a singleton set of the owner
183  if ($owner->id) $asset_path[] = $owner->id;
184  }
185  }
186 
187  $o->addFormActionGetVar('sq_asset_path', implode(',', $asset_path), TRUE);
188 
189  $preview_url = '';
190  $closest_parentid = $owner->id;
191 
192  foreach ($asset_path as $assetid) {
193  if ($assetid != $owner->id) {
194  $ancestor = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid);
195  } else {
196  $ancestor = $owner;
197  }
198 
199  if (is_null($ancestor)) {
200  $preview_url = '';
201  break;
202  }
203 
204  $paths = $ancestor->getWebPaths();
205  if (!empty($paths)) $closest_parentid = $assetid;
206 
207  if ($preview_url == '') {
208  // we need a base url
209  $url = $ancestor->getUrl();
210  if (!empty($url)) {
211  $preview_url = $ancestor->getUrl();
212  $closest_parentid = $assetid;
213  }
214  } else {
215  // we have a base url, but we need the appropriate paths
216  if (empty($paths)) {
217  // no path defined from here onwards - just use what we've got so far
218  break;
219  } else {
220  $preview_url .= '/'.array_shift($paths);
221  }
222  }
223  }//end foreach
224  $o->addHiddenField('sq_preview_url', $preview_url);
225 
226  // store this preview url into the global vars so that any other asset
227  // can use it as a way to know the content we are in
228  $GLOBALS['sq_preview_url'] = $preview_url;
229 
230  return $closest_parentid;
231 
232  }//end _determinePreviewUrl()
233 
234 
245  function paint(&$owner, &$o, $creating)
246  {
247  // if we dont have read access, go away
248  if ($owner->id && !$owner->readAccess()) {
249  $GLOBALS['SQ_SYSTEM']->paintLogin(translate('login'), translate('cannot_access_asset', htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET)));
250  exit();
251  }
252 
253  if ($creating && SQ_IN_BACKEND) {
254  $o->addOnLoad('focusFirstTextInput();');
255  }
256  // if there are no screens or static screens
257  assert_false(!count($this->_screens) && empty($this->_edit_fns->static_screens));
258 
259  // set the type code again in case it has changed (like when morphing)
260  $this->_type_code = $owner->type();
261 
262 
264  // ALLOWED SCREEN ACCESS //
266  $check_screen_restrictions = !$creating && (!($GLOBALS['SQ_SYSTEM']->userRoot() || $GLOBALS['SQ_SYSTEM']->userSystemAdmin()));
267  if ($check_screen_restrictions) {
268  $allowed_screens = $this->getAllowedScreens($owner);
269  if (empty($allowed_screens)) {
270  $check_screen_restrictions = FALSE;
271  }
272  }
273 
274 
276  // ACTIVE SCREEN //
278  $create_sections = Array();
279  if (!$creating) {
280  if (empty($_REQUEST['asset_ei_screen'])) {
281  if ((SQ_IN_LIMBO || isset($_GET['sq_from_frontend'])) && !empty($this->_default_screen)) {
282  $active_screen = $this->_default_screen;
283  } else {
284  $active_screen = 'details';
285  }
286  $_REQUEST['asset_ei_screen'] = $active_screen;
287  } else {
288  $active_screen = $_REQUEST['asset_ei_screen'];
289  }
290 
291  } else {
292  // if we are creating open the create file to see which fields we are supposed to print out
293  list($create_sections, $active_screen) = $this->_getCreateSections(TRUE);
294  if (!count($create_sections)) return;
295 
296  }//end if
297 
298  if ($check_screen_restrictions) {
299  $user_is_not_allowed = TRUE;
300 
301  foreach ($allowed_screens as $allowed_screen) {
302  // if the allowed screen is in our array or if the access if granted too all the screens
303  // be happy or present the user with login box
304  if (isset($allowed_screen['screen']) && ($allowed_screen['screen'] === 0)) {
305  $user_is_not_allowed = FALSE;
306  } else if (isset($allowed_screen['screen']) && ($allowed_screen['screen'] == $active_screen)) {
307  $user_is_not_allowed = FALSE;
308  }//end if
309  }//end foreach
310 
311  if ($user_is_not_allowed) {
312  // this user is not allowed to view the current screen
313  $GLOBALS['SQ_SYSTEM']->paintLogin(translate('login'), translate('cannot_access_inline_asset_screen', $active_screen, htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET)));
314  exit();
315  }//end if
316  }
317 
318  if (SQ_IN_LIMBO && $owner->id) {
319  // broadcast the 'entering simple edit'
320  $GLOBALS['SQ_SYSTEM']->broadcastTriggerEvent('trigger_event_enter_simple_edit', $owner);
321  }
322 
323  if (!isset($this->_edit_fns->static_screens[$active_screen]) && empty($this->_screens[$active_screen])) {
324  // we cant find this screen, so we will use the details screen as a backup
325  trigger_localised_error('SYS0076', E_USER_WARNING, $active_screen);
326  $active_screen = 'details';
327  }
328 
329  // make sure that we have the screen for next time
330  $o->addFormActionGetVar('asset_ei_screen', $active_screen);
331 
332 
334  // LOCKING AND PERMISSIONS //
336  // do we have write access?
337  $full_write_access = $owner->writeAccess('');
338 
339  // do we print the commit button (ie. have we printed an editable interface?)
340  $print_commit_button = FALSE;
341 
342  // do we unlock this asset when committing?
343  $force_unlock_on_commit = TRUE;
344 
345  // if we are in LIMBO and release locks button was clicked then return to normal page
346  if (SQ_IN_LIMBO && !empty($_REQUEST['sq_lock_release_manual'])) {
347  ?>
348  <script>top.location='<?php echo current_url(TRUE, TRUE); ?>';</script>
349  <?php
350  exit();
351  }
352 
353  if (!$creating) {
354  // default to 'all', so if lock type is left out a lock can still be gotten and the asset edited
355  $screen_lock_type = 'all';
356  if (isset($this->_edit_fns->static_screens[$active_screen])) {
357  if (!empty($this->_edit_fns->static_screens[$active_screen]['lock_type'])) {
358  $screen_lock_type = $this->_edit_fns->static_screens[$active_screen]['lock_type'];
359  }
360  } else {
361  // must be a normal screen
362  if (!empty($this->_screens[$active_screen]['lock_type'])) {
363  $screen_lock_type = $this->_screens[$active_screen]['lock_type'];
364  }
365  }
366 
367  // do they have access to acquire the lock?
368  $acquire_lock_access = $owner->canLiveEdit($screen_lock_type);
369 
370  $locks = $GLOBALS['SQ_SYSTEM']->am->getLockInfo($owner->id, $screen_lock_type, TRUE);
371 
372  $have_any_locks = FALSE;
373  $have_all_locks = TRUE;
374  $need_force_locks = FALSE;
375  $can_force_locks = TRUE;
376  $do_the_limbo_lock = TRUE;
377  foreach ($locks as $lock_type => $lock) {
378 
379  if (empty($lock)) {
380  $have_all_locks = FALSE;
381  } else {
382  // this asset is currently locked
383  $user = $GLOBALS['SQ_SYSTEM']->am->getAsset($lock['userid']);
384  $editing = $GLOBALS['SQ_SYSTEM']->am->getAsset($lock['source_assetid']);
385 
386  if ($GLOBALS['SQ_SYSTEM']->currentUser($user)) {
387  $have_any_locks = TRUE;
388  } else {
389  $have_all_locks = FALSE;
390  $do_the_limbo_lock = FALSE;
391 
392  // this lock is held by someone else so check if we can forceable acquire it
393  $need_force_locks = TRUE;
394  // does the current user has a high
395  // enough level of access to forceably acquire the lock
396  if (!$owner->canForceablyAcquireLock($lock_type)) {
397  $can_force_locks = FALSE;
398  }
399 
400  }
401  }//end if
402 
403  }//end foreach lock types
404 
405  if (SQ_IN_LIMBO && $do_the_limbo_lock && !SQ_DESIGN_NO_FRAME) {
406 
408  // LIMBO LOCKING //
410 
411  // even if we have all the locks for this screen, limbo might require more locks
412  // so acquire any more locks that might be needed
413  $this->acquireLimboLocks($owner, $o, $active_screen, $screen_lock_type);
414 
415  } else {
416 
417  if ((strtolower($screen_lock_type) != 'none') && empty($_REQUEST['print_view'])) {
418  // lets tell the user if the asset is locked for editing
419  // or if they can lock it to edit it
420  $o->openSection(translate('locking_editing'));
421  $o->openRaw();
422  ?>
423  <p class="sq-lock-message"><?php
424  if (!$have_all_locks) {
425  if ($need_force_locks) {
426  if ($can_force_locks) {
427  echo '<div class="sq-backend-locked-by-someone-else">'.translate('forcibly_acquire_lock', htmlspecialchars($user->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET)).'</div>';
428  }
429  } else if ($full_write_access && $acquire_lock_access) {
430  echo translate('acquire_lock', translate('acquire_lock_button'), htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET));
431  }
432  }
433  if ($have_any_locks) {
434  echo translate('release_lock', translate('release_lock_button'), htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET));
435  }
436  ?>
437  <b class="clickable" onclick="sq_toggle_lock_info();" id="sq_lock_info_toggle"><?php echo translate('show_lock_details'); ?></b><br />
438  </p>
439 
440  <div id="sq_lock_info" style="display: none;">
441  <table class="sq-backend-table">
442  <tr>
443  <td class="sq-backend-table-header" style="width: 20px;">
444  <img src="<?php echo $o->filesPath('/images/blank.gif');?>" width="20" height="1" border="0" alt="" />
445  </td>
446  <td class="sq-backend-table-header" align="left" nowrap>
447  &nbsp;<?php echo translate('lock_type'); ?>
448  </td>
449  <td class="sq-backend-table-header" width="100%">
450  &nbsp;
451  </td>
452  </tr>
453  <tr>
454  <td width="100%" colspan="3">
455  <table width="100%" cellspacing="0" cellpadding="0">
456  <?php
457  $class = 'sq-backend-table-cell-alt';
458  foreach ($locks as $lock_type => $lock) {
459  ?>
460  <tr>
461  <td class="sq-backend-table-cell" style="width: 20px;" align="center">
462  <script language="JavaScript" type="text/javascript">sq_print_icon("<?php echo sq_web_path('lib'); ?>/web/images/icons/<?php echo ((empty($lock)) ? 'un' : ''); ?>locked.png", "16", "16", "");</script>
463  </td>
464  <td class="sq-backend-table-cell">
465  <?php echo ucwords(str_replace('_', ' ', $lock_type)); ?>
466  </td>
467  <td class="sq-backend-table-cell">
468  <?php
469  if (empty($lock)) {
470 
471  if ($full_write_access && $acquire_lock_access) {
472  echo translate('currently_not_held').'.';
473  } else {
474  echo translate('no_access_to_edit', htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET));
475  }
476 
477  } else {
478  // this asset is currently locked so display message to the user
479  $user = $GLOBALS['SQ_SYSTEM']->am->getAsset($lock['userid']);
480  $editing = $GLOBALS['SQ_SYSTEM']->am->getAsset($lock['source_assetid']);
481 
482  if (SQ_ROLLBACK_VIEW) {
483  $now = strtotime($_SESSION['sq_rollback_view']['rollback_time']);
484  } else {
485  $now = time();
486  }
487 
488  if (is_null($lock['expires'])) {
489  $expires_in = translate('lock_held_indefinitely');
490  } else {
491  require_once SQ_FUDGE_PATH.'/general/datetime.inc';
492  $expires_in = easy_time_total(($lock['expires'] - $now), TRUE);
493  if (!$expires_in) {
494  $expires_in = '1 '.translate('second');
495  }
496  $expires_in = translate('due_to_expire', $expires_in);
497  }
498 
499  echo translate('lock_held_by', htmlspecialchars($user->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET), htmlspecialchars($editing->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET)).'. ';
500  echo $expires_in;
501  }//end if
502  ?>
503  </td>
504  </tr>
505  <?php
506  }//end foreach lock types
507  ?>
508  </table>
509  </td>
510  </tr>
511  </table>
512  </div>
513 
514  <?php
515  if (!$have_all_locks || $have_any_locks) {
516  ?><div style="margin-top: 4px; margin-bottom: 0px"><?php
517  }
518 
519  if (!$have_all_locks) {
520  hidden_field('sq_lock_acquire', '0');
521  if ($need_force_locks) {
522  if ($can_force_locks) {
523  // they aren't going to do this without a fight though
524  // they'll have to go through our popup window first
525  $popup_url = '?SQ_BACKEND_PAGE=main&backend_section=am&ignore_frames=1&am_section=forceably_acquire_lock&assetid='.$owner->id.'&sq_lock_type='.$screen_lock_type;
526 
527  hidden_field('sq_lock_acquire_by_force', '0');
528  normal_button('sq_forceably_acquire_lock', translate('acquire_lock_button'), "window.open('$popup_url', 'sq_forceably_acquire_lock_popup', 'toolbar=0,menubar=0,location=0,status=0,scrollbars=1,resizable=1,width=500,height=300');");
529  echo '&nbsp;';
530  }
531  } else if ($full_write_access && $acquire_lock_access) {
532  hidden_field('sq_lock_acquire_by_force', '0');
533  normal_button('', translate('acquire_lock_button'), "document.getElementById('sq_lock_acquire').value = 1; submit_form(this.form)", 'accesskey="a"');
534  echo '&nbsp;';
535  }//end if
536  }
537 
538  if ($have_any_locks) {
539  hidden_field('sq_lock_release_manual', 0);
540  normal_button('', translate('release_lock_button'), "document.getElementById('sq_lock_release_manual').value = 1; submit_form(this.form)", 'accesskey="r"');
541  echo '&nbsp;';
542  }
543 
544  if (!$have_all_locks || $have_any_locks) {
545  ?></div><?php
546  }
547 
548  $o->closeRaw();
549  $o->closeSection();
550 
551  }//end if locktype not none
552 
553  }//end else (not in limbo or not do the limbo lock)
554 
555  $o->openRaw();
556  hidden_field('sq_lock_type', $screen_lock_type);
557  $o->closeRaw();
558 
559  }//end if
560 
561  // we need to check if we are going to paint the layout here, so no static screens get printed
562  $paint_layout = FALSE;
563  if (SQ_IN_LIMBO && !$creating) {
564  // Check for a layout based on root node
565  $layout_pattern = 'layout::'.$owner->type().'::'.$active_screen;
566  $lookup_values = $owner->getLookupValues(TRUE, $layout_pattern);
567  foreach ($lookup_values as $values) {
568  foreach ($values as $look_key => $look_value) {
569  if (isset($look_value['value']) && ($look_value['value'] > 0)) {
570  $paint_layout = TRUE;
571  }
572  }
573  }
574 
575  // If none found, try layout manager
576  $lm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('layout_manager');
577  if ($lm->hasLayout($owner, $active_screen)) {
578  $paint_layout = TRUE;
579  }
580  }
581 
582 
583  // check the active screen for special system defined static screens
584  $file = NULL;
585  if (isset($this->_edit_fns->static_screens[$active_screen])) {
586  $active_screen_name = $this->_edit_fns->static_screens[$active_screen]['name'];
587 
588  // only paint the static screens if no layouts are getting painted
589  if (!$paint_layout) {
590  // if we are not creating, paint the system defined bit of this tab
591  if (!$creating) {
592  $paint_function = 'paint'.$active_screen;
593  $this->includeStaticScreen($active_screen);
594  if ($paint_function($owner, $o, $this)) {
595  $print_commit_button = TRUE;
596  }
597  }
598 
599  $force_unlock_on_commit = $this->_edit_fns->static_screens[$active_screen]['force_unlock'];
600  }
601  // try and find the file to print user defined section of the tab
602  $file = @$this->findFile('screen_'.$active_screen);
603 
604  } else {
605 
606  // try and find the file with the screen details
607  if (!($file = $this->findFile('screen_'.$active_screen))) {
608  return;
609  }
610 
611  $force_unlock_on_commit = $this->_screens[$active_screen]['force_unlock'];
612  $active_screen_name = $this->_screens[$active_screen]['name'];
613 
614  }//end if
615 
616 
618  // WHERE AM I //
620  if (isset($_REQUEST['sq_link_path'])) {
621  $link_path = $_REQUEST['sq_link_path'];
622  } else {
623  $link_path = '';
624  }
625  $o->addFormActionGetVar('sq_link_path', $link_path, TRUE);
626  $o->addHiddenField('sq_link_path', $link_path);
627 
628 
630  // PREVIEW URL //
632  // determine and set the preview url, and return the closest parent id to be used below
633  // in determining the page headings
634  $closest_parentid = $this->_determinePreviewUrl($owner, $o);
635 
636 
640  // if we are ignoring frames - normally because we are editing in limbo, we want
641  // to make sure we keep this setting for the future before we use layouts to print the interface
642  if (isset($_REQUEST['ignore_frames']) && $_REQUEST['ignore_frames']) {
643  $o->addFormActionGetVar('ignore_frames', '1', TRUE);
644  }
645 
646  // once we have a preview URL, we can paint the layout if there is one
647  // paint the layout now, if needed
648  if ($paint_layout) {
649  // Find a layout based on root node
650  $layout_pattern = 'layout::'.$owner->type().'::'.$active_screen;
651  $lookup_values = $owner->getLookupValues(TRUE, $layout_pattern);
652  $layoutid = '';
653  foreach ($lookup_values as $values) {
654  foreach ($values as $look_key => $look_value) {
655  if (isset($look_value['value'])) {
656  $layoutid = $look_value['value'];
657  }
658  }
659  }
660  $layout = NULL;
661  if ((!empty($layoutid)) && ($layoutid > 0)) {
662  $layout = $GLOBALS['SQ_SYSTEM']->am->getAsset($layoutid);
663  }
664  if (!is_null($layout)) {
665  $o->addFormActionGetVar('asset_ei_screen', $active_screen, TRUE);
666  return $this->paintLayout($owner, $o, $layout);
667  }
668  // Otherwise refer to layout manager
669  if (NULL !== ($layout = $lm->getLayout($owner, $active_screen))) {
670  $o->addFormActionGetVar('asset_ei_screen', $active_screen, TRUE);
671  return $this->paintLayout($owner, $o, $layout);
672  }
673  }
674 
676  // Navigation History //
678  if (!isset($_SESSION['sq_nav_history']) || !is_array($_SESSION['sq_nav_history'])) {
679  $_SESSION['sq_nav_history'] = Array();
680  }
681 
682  // first work out if we have gone back to a previous entry
683  if (!empty($_SESSION['sq_nav_history'])) {
684  if (isset($_REQUEST['sq_nav_goback'])) {
685  for ($i = count($_SESSION['sq_nav_history']); $i > $_REQUEST['sq_nav_goback']; $i--) {
686  array_pop($_SESSION['sq_nav_history']);
687  if (empty($_SESSION['sq_nav_history'])) break;
688  }
689  }
690  }
691 
692  if (!$creating) {
693  if (!empty($_SESSION['sq_nav_history'])) {
694  $nav_count = count($_SESSION['sq_nav_history']);
695 
696  if ($nav_count >= 20) {
697  array_shift($_SESSION['sq_nav_history']);
698  $nav_count--;
699  }
700 
701  $current_nav_node = $_SESSION['sq_nav_history'][($nav_count-1)];
702  if ($current_nav_node['assetid'] != $owner->id) {
703  $_SESSION['sq_nav_history'][$nav_count] = Array('assetid' => $owner->id, 'screen' => $active_screen);
704  } else if ($current_nav_node['screen'] != $active_screen) {
705  $_SESSION['sq_nav_history'][($nav_count -1)] = Array('assetid' => $owner->id, 'screen' => $active_screen);
706  }
707  } else {
708  $_SESSION['sq_nav_history'][0] = Array('assetid' => $owner->id, 'screen' => $active_screen);
709  }
710  }
711 
712 
714  // PAGE HEADINGS //
716  // set correct page headings based on what we are doing
717  if (!$creating) {
718  $page_heading = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($this->_type_code, 'name').'&nbsp;&nbsp;|&nbsp;&nbsp;';
719  if (empty($_REQUEST['print_view'])) {
720  $infos = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo($owner->id);
721  $page_heading .= '<ul class="info_asset_finder">';
722  foreach ($infos as $assetid => $info) {
723  $page_heading .= '<li>'.get_asset_tag_line($assetid).'</li>';
724  }
725  $page_heading .= '</ul>';
726  } else {
727  $page_heading .= htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET).' (Id: #'.$owner->id.') ';
728  }
729  $page_heading .= 'v. '.$owner->version;
730  } else {
731  $page_heading = 'Create new '.$GLOBALS['SQ_SYSTEM']->am->getTypeInfo($this->_type_code, 'name');
732  }
733  $page_heading .= '&nbsp;&nbsp;|&nbsp;&nbsp;'.$active_screen_name;
734 
735  $o->setHeading($page_heading, sq_get_icon($GLOBALS['SQ_SYSTEM']->am->getAssetIconURL($this->_type_code), 16, 16, ''));
736 
737  $o->setPageTitle(htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET));
738  $sub_heading = '';
739  if ($closest_parentid != $owner->id) {
740  $closest_parent = $GLOBALS['SQ_SYSTEM']->am->getAsset($closest_parentid);
741  if (!is_null($closest_parent)) {
742  $sub_heading = translate('currently_editing', $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($closest_parent->type(), 'name'), htmlspecialchars($closest_parent->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET)).'<br />';
743  }
744  }
745  $o->setSubHeading($sub_heading);
746 
747 
749  // SCREEN MENU //
751  // add all the screens to the combo, but only if we aren't creating the object
752  // set the current screen for both backend and frontend editing
753  $current_location = $o->getCurrentLocation();
754  list($current_loc_base, $current_loc_query) = explode('?', $current_location);
755  if (!$creating) {
756  // add static screens for the asset
757  foreach ($this->_edit_fns->static_screens as $code_name => $data) {
758  if ($check_screen_restrictions) {
759  $user_is_not_allowed = TRUE;
760  foreach ($allowed_screens as $allowed_screen) {
761  if (isset($allowed_screen['screen']) && ($allowed_screen['screen'] == $code_name)) {
762  $user_is_not_allowed = FALSE;
763  }//end if
764  }//end foreach
765 
766  if ($user_is_not_allowed) continue;
767  }//end if
768  $url = replace_query_string_vars(Array('asset_ei_screen' => rawurlencode($code_name)), $current_loc_base, $current_loc_query);
769  $o->addStaticScreen($url, $data['name']);
770  }
771  for (reset($this->_screens); NULL !== ($code = key($this->_screens)); next($this->_screens)) {
772  if ($check_screen_restrictions) {
773  $user_is_not_allowed = TRUE;
774  foreach ($allowed_screens as $allowed_screen) {
775  if (isset($allowed_screen['screen']) && ($allowed_screen['screen'] == $code)) {
776  $user_is_not_allowed = FALSE;
777  }//end if
778  }//end foreach
779 
780  if ($user_is_not_allowed) continue;
781  }//end if
782  if ($this->_screens[$code]['invisible'] && $code != $active_screen) {
783  continue;
784  }
785  $url = replace_query_string_vars(Array('asset_ei_screen' => rawurlencode($code)), $current_loc_base, $current_loc_query);
786  $o->addScreen($url, $this->_screens[$code]['name']);
787  }//end for
788  }//end if
789 
790 
792  // EDIT INTERFACE //
794  if ($file) {
795  $print_commit_button |= $this->printEditInterface('screen_'.$active_screen, $owner, $o, $creating, $create_sections);
796  }
797 
798  // we have printed an editable interface on a static screen - show the commit button
799  if ($print_commit_button && empty($_REQUEST['print_view'])) {
800  $o->commitButton('', $force_unlock_on_commit);
801  }
802 
803  }//end paint()
804 
805 
819  function paintInline(&$owner, &$o, $creating, $active_screen)
820  {
821  $print_commit_button = FALSE;
822 
823  // if we dont have read access, go away
824  if ($owner->id && !$owner->readAccess()) {
825  $o->openField('');
826  ?>
827  <span class="error"><?php echo translate('cannot_access_asset', htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET)); ?></span>
828  <?php
829  $o->closeField();
830  return FALSE;
831  }
832 
833  // if there are no screens or static screens
834  assert_false(!count($this->_screens) && empty($this->_edit_fns->static_screens));
835 
836 
838  // ALLOWED SCREEN ACCESS //
840  $check_screen_restrictions = !$creating && (!($GLOBALS['SQ_SYSTEM']->userRoot() || $GLOBALS['SQ_SYSTEM']->userSystemAdmin()));
841  if ($check_screen_restrictions) {
842  $allowed_screens = $this->getAllowedScreens($owner);
843  if (empty($allowed_screens)) {
844  $check_screen_restrictions = FALSE;
845  }
846  }
847 
848 
850  // ACTIVE SCREEN //
852  $create_sections = Array();
853  if ($creating) {
854  // if we are creating open the create file to see which fields we are supposed to print out
855  list($create_sections, $active_screen) = $this->_getCreateSections(TRUE);
856  if (!count($create_sections)) return;
857 
858  }//end if
859 
860 
861  // this user is not allowed to view the current screen
862  if ($check_screen_restrictions) {
863  $user_is_not_allowed = TRUE;
864  foreach ($allowed_screens as $allowed_screen) {
865  if (isset($allowed_screen['screen']) && ($allowed_screen['screen'] == $active_screen)) {
866  $user_is_not_allowed = FALSE;
867  }//end if
868  }//end foreach
869 
870  if ($user_is_not_allowed) {
871  $o->openField('');
872  ?>
873  <span class="error"><?php echo translate('cannot_access_inline_asset_screen', $active_screen, htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET)); ?></span>
874  <?php
875  $o->closeField();
876  return FALSE;
877  }//end if
878  }//end if
879 
880  if (!isset($this->_edit_fns->static_screens[$active_screen]) && empty($this->_screens[$active_screen])) {
881  // we cant find this screen, so we will use the details screen as a backup
882  trigger_localised_error('SYS0076', E_USER_WARNING, $active_screen);
883  $active_screen = 'details';
884  }
885 
886  // we need to check if we are going to paint the layout here, so no static screens get printed
887  $paint_layout = FALSE;
888  if (SQ_IN_LIMBO && !$creating) {
889  $lm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('layout_manager');
890  if ($lm->hasLayout($owner, $active_screen)) {
891  $paint_layout = TRUE;
892  }
893  }
894 
895  // check the active screen for special system defined static screens
896  $file = NULL;
897  if (isset($this->_edit_fns->static_screens[$active_screen])) {
898  $active_screen_name = $this->_edit_fns->static_screens[$active_screen]['name'];
899 
900  // only paint the static screens if no layouts are getting painted
901  if (!$paint_layout) {
902  // if we are not creating, paint the system defined bit of this tab
903  if (!$creating) {
904  $paint_function = 'paint'.$active_screen;
905  $this->includeStaticScreen($active_screen);
906  if ($paint_function($owner, $o, $this)) {
907  $print_commit_button = TRUE;
908  }
909  }
910 
911  $force_unlock_on_commit = $this->_edit_fns->static_screens[$active_screen]['force_unlock'];
912  }
913  // try and find the file to print user defined section of the tab
914  $file = @$this->findFile('screen_'.$active_screen);
915 
916  } else {
917 
918  // try and find the file with the screen details
919  if (!($file = $this->findFile('screen_'.$active_screen))) {
920  return;
921  }
922 
923  $force_unlock_on_commit = $this->_screens[$active_screen]['force_unlock'];
924  $active_screen_name = $this->_screens[$active_screen]['name'];
925 
926  }//end if
927 
928  // once we have a preview URL, we can paint the layout if there is one
929  // paint the layout now, if needed
930  if ($paint_layout) {
931  if (NULL !== ($layout = $lm->getLayout($owner, $active_screen))) {
932  $o->addFormActionGetVar('asset_ei_screen', $active_screen, TRUE);
933  return $this->paintLayout($owner, $o, $layout);
934  }
935  }
936 
938  // EDIT INTERFACE //
940  if ($file) {
941  $print_commit_button |= $this->printEditInterface('screen_'.$active_screen, $owner, $o, $creating, $create_sections);
942  }
943 
944  return $print_commit_button;
945 
946  }//end paintInline()
947 
948 
961  function printEditInterface($screen, &$owner, &$o, $creating=FALSE, $create_sections=Array())
962  {
963  // grab the closest language file generated for this screen, then
964  // unserialise it to get our XML_Tree root
965  $root = $this->findScreen($screen);
966  if (is_null($root)) return FALSE;
967 
968  $print_commit_button = FALSE;
969 
970  // prefix for all the form vars
971  $prefix = $owner->getPrefix();
972 
973  // Loop over the sections
974  foreach ($root->section as $section) {
975  // if we are in limbo and this section is not to be printed in limbo - dont print it
976  if (SQ_IN_LIMBO && (!isset($section->attributes()->limbo_access) || (int)$section->attributes()->limbo_access == 0)) {
977  continue;
978  }
979 
980  // if this ain't a section, or if we are printing the create interface and this section
981  // is not included in that, ignore it
982  if ($creating && empty($create_sections[(string)$section->attributes()->name])) {
983  continue;
984  }
985 
986  $section_access = $this->_getAccess($owner, $section, $prefix);
987  if (!($section_access & SQ_EI_READ)) {
988  continue;
989  }
990 
991  // if a translated display name has been specified, use it
992  if (!is_null($section->attributes()->display_name)) {
993  $o->openSection((string)$section->attributes()->display_name);
994  } else {
995  $o->openSection((string)$section->attributes()->name);
996  }
997 
998  if (!($num_fields = count($section->children()))) {
999  continue;
1000  }
1001 
1002  $section_note = NULL;
1003  if ($section->function_call) {
1004 
1005  $paint_node = $section->function_call->paint_function;
1006 
1007  if (!isset($paint_node->attributes()->name) || !method_exists($this->_edit_fns, (string)$paint_node->attributes()->name)) {
1008  $o->openField('');
1009  echo translate('section_not_found', (string)$section->attributes()->name);
1010  $o->closeField();
1011  } else {
1012  // if we are printing the create interface and this section is not included in that, ignore it
1013  if ($creating && !in_array((string)$paint_node->attributes()->name, $create_sections[(string)$section->attributes()->name])) {
1014  continue;
1015  }
1016 
1017  if ($this->_edit_fns->{(string) $paint_node->attributes()->name}($owner, $o, $prefix)) {
1018  $print_commit_button = TRUE;
1019  }
1020  }
1021 
1022  // See if there's a section note
1023  if (isset($section->note)) {
1024  if (count($section->note) > 1) {
1025  throw new Exception('Unable to parse edit interface for asset type "'.$owner->type().'", screen "'.$screen.'": a section has multiple section notes; it should have just one');
1026  } else {
1027  $section_note = (string)$section->note;
1028  }
1029  }
1030 
1031  // they must just be normal fields
1032  } else {
1033 
1034  // Loop over the fields
1035  foreach ($section->children() as $field) {
1036  switch ($field->getName()) {
1037  case 'field':
1038  $display_name = '';
1039  $name = '';
1040  $field_note = '';
1041  $attr_tag = NULL; // TODO: TOF what is $attr_tag
1042  foreach ($field->children() as $sub_field) {
1043  switch ($sub_field->getName()) {
1044  case 'display_name':
1045  $display_name = (string)$sub_field;
1046  break;
1047  case 'note':
1048  $field_note = (string)$sub_field;
1049  break;
1050 
1051  default:
1052  if (!is_null($attr_tag)) {
1053  trigger_localised_error('SYS0194', E_USER_WARNING);
1054  } else {
1055  $attr_tag = $sub_field;
1056  }
1057  break;
1058  }//end switch
1059 
1060  }
1061 
1062  // if we are in limbo and this field is not to be printed in limbo - dont print it
1063  if (SQ_IN_LIMBO && (isset($field->attributes()->limbo_access) && (int)$field->attributes()->limbo_access == 0)) {
1064  continue;
1065  }
1066 
1067  $field_access = $this->_getAccess($owner, $field, $prefix, $section_access);
1068  if (!($field_access & SQ_EI_READ)) {
1069  continue;
1070  }
1071 
1072  if (!isset($field->attributes()->format)) {
1073  $field->attributes()->format = '';
1074  }
1075 
1076  if (!empty($field->attributes()->attribute)) {
1077  // if this ain't a field, or if we are printing the create interface and this field is not included in that, ignore it
1078  if (($field->getName() != 'field') || ($creating && (empty($field->attributes()->attribute) || !in_array((string)$field->attributes()->attribute, $create_sections[(string)$section->attributes()->name])))) {
1079  continue;
1080  }
1081 
1082  // TODO TOF fix display_name
1083  $o->openField($display_name, $field->attributes()->format, '', isset($field->attributes()->hidden));
1084  $attr = $owner->getAttribute((string)$field->attributes()->attribute);
1085 
1086  if (is_null($attr)) continue;
1087  // TODO: TOF fix the line below
1088  if (!$attr->setEditParams($attr_tag)) continue;
1089  $attr->paint($prefix.'_'.$attr->id, !($field_access & SQ_EI_WRITE));
1090  if ($field_access & SQ_EI_WRITE) {
1091  $print_commit_button = TRUE;
1092  }
1093 
1094  if (!empty($field_note)) {
1095  $field_note = str_replace('%description%', $attr->description, $field_note);
1096  }
1097 
1098  } else if ($attr_tag->getName() == 'function_call') {
1099 
1100  $paint_node = $attr_tag->paint_function;
1101 
1102  // if this ain't a field, or if we are printing the create interface and this field is not included in that, ignore it
1103  if ($field->getName() != 'field' || ($creating && !in_array((string) $paint_node->attributes()->name, $create_sections[(string) $section->attributes()->name]))) {
1104  continue;
1105  }
1106 
1107  $o->openField($display_name, $field->attributes()->format, '', isset($field->attributes()->hidden));
1108 
1109  if (empty($paint_node->attributes()->name) || !method_exists($this->_edit_fns, $paint_node->attributes()->name)) {
1110  $o->note(translate('specific_painting_function_not_found', $paint_node->attributes()->name));
1111  } else {
1112  $method_name = (string) $paint_node->attributes()->name;
1113  if ($this->_edit_fns->{$method_name}($owner, $o, $prefix)) {
1114  $print_commit_button = TRUE;
1115  }
1116  }
1117 
1118  }//end if
1119 
1120  if (!empty($field_note)) $o->note($field_note);
1121 
1122  break;
1123 
1124  case 'note':
1125  // notice that only the last "note" will be used if multiple are supplied
1126  if (!empty($field)) {
1127  $section_note = (string)$field;
1128  }
1129  break;
1130 
1131  default:
1132  trigger_localised_error('SYS0140', E_USER_WARNING, $field->name);
1133  continue;
1134 
1135  }//end switch
1136 
1137  }//end foreach fields
1138 
1139  }//end else section uses function call
1140 
1141  if (!empty($section_note)) {
1142  $o->sectionNote($section_note);
1143  }
1144 
1145  $o->closeSection();
1146 
1147  }//end foreach
1148 
1149  // paint the choosing link section when creating a new asset in backend
1150  if($creating && SQ_IN_BACKEND) {
1151  $o->openSection(translate('link'));
1152  $this->_edit_fns->paintCreateLink($owner, $o, $prefix);
1153  $o->closeSection();
1154  }
1155  return $print_commit_button;
1156 
1157  }//end printEditInterface()
1158 
1159 
1171  function acquireLimboLocks(&$owner, &$o, $active_screen='details', $screen_lock_type=NULL)
1172  {
1173  $locks = Array();
1174  if (!is_null($screen_lock_type)) {
1175  $locks[] = $screen_lock_type;
1176  }
1177 
1178  $lm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('layout_manager');
1179 
1180  if ($lm->hasLayout($owner, $active_screen)) {
1181 
1182  $layout = $lm->getLayout($owner, $active_screen);
1183  if (is_null($layout)) return FALSE;
1184 
1185  $keywords = $layout->getLayoutKeywords();
1186  if (empty($keywords)) return FALSE;
1187 
1188  if (isset($keywords['custom']) && !empty($keywords['custom'])) {
1189  // acquire any locks that the owner needs to paint the layout
1190  $locks = array_merge($locks, $owner->getEditingLocks($keywords['custom']));
1191  }
1192 
1193  // if there are other screens used by the layout, then we need to acquire locks on those screens as well
1194  $screens = array_merge(array_keys($keywords['screens']), array_keys($keywords['entire_screens']));
1195  $screens = array_unique($screens);
1196 
1197  foreach ($screens as $screen) {
1198  // default to 'all', so if lock type is left out a lock can still be gotten and the asset edited
1199  $screen_lock_type = 'all';
1200  if (isset($this->_edit_fns->static_screens[$screen])) {
1201  if (!empty($this->_edit_fns->static_screens[$screen]['lock_type'])) {
1202  $screen_lock_type = $this->_edit_fns->static_screens[$screen]['lock_type'];
1203  }
1204  } else {
1205  // must be a normal screen
1206  if (!empty($this->_screens[$screen]['lock_type'])) {
1207  $screen_lock_type = $this->_screens[$screen]['lock_type'];
1208  }
1209  }
1210 
1211  $locks[] = $screen_lock_type;
1212 
1213  }//end foreach
1214 
1215  }//end if hasLayout
1216 
1217  $locks = array_unique($locks);
1218  $have_all_locks = TRUE;
1219  foreach ($locks as $lock_name) {
1220  $lock_info = $GLOBALS['SQ_SYSTEM']->am->getLockInfo($owner->id, $lock_name, TRUE);
1221  foreach ($lock_info as $lock_type => $lock_data) {
1222  if (!isset($lock_data['userid']) || $lock_data['userid'] != $GLOBALS['SQ_SYSTEM']->currentUserId()) {
1223  $have_all_locks = FALSE;
1224  }
1225  }
1226  }
1227 
1228  if (!$have_all_locks) {
1229  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
1230  $vars = Array(
1231  'assetids' => Array($owner->id,),
1232  'lock_type' => $locks,
1233  'forceably_acquire' => FALSE,
1234  );
1235 
1236  // if redirect locations is already set, pass it onto hipo job
1237  $on_complete_url = (empty($o->_redirect) ? '' : $o->_redirect);
1238  $hh->queueHipo('hipo_job_acquire_locks', $vars, $on_complete_url);
1239  $url = $hh->runQueuedJobs();
1240  if (!empty($url)) {
1241  // redirect to the correct url and fire hipo (not passing sq_redirect_url)
1242  // so that we do not redirect and refresh many times
1243  $o->setRedirect($url);
1244  }
1245  }
1246 
1247  $o->openRaw();
1248  hidden_field('sq_limbo_lock_type', urlencode(serialize($locks)));
1249  $o->closeRaw();
1250 
1251  }//end acquireLimboLocks()
1252 
1253 
1264  function paintLayout(&$owner, &$o, &$layout)
1265  {
1266  // Get the order in which keywords are placed in the raw content in container.
1267  // This order is required to deciede which keyword to evaluate first. Say a metadata keyword is placed
1268  // after custom keyword in a container, if it is evaluted before custom keyword, the the js code for wysiwyg (i.e.
1269  // if metadata contains wysiwyg field) is placed with metadata keyword. In this case, custom key will only have
1270  // function call to wysiwyg (as the wysiwyg js code printed only once in a page), but since it is defined later in page,
1271  // its will give 'undefined function call' js error.
1272  //
1273  // See bug #3698 + bug #4458 Conflicting WYSIWYG's
1274  $layout_keywords_order = $this->_getLayoutKeywordsOrder($layout);
1275 
1276  $this->getKeywordsReplacementsForPaint($owner, $o, $layout, $layout_keywords_order);
1277 
1278  // we need to open a raw section so that the form gets printed before the contents of the layout
1279  $o->openRaw();
1280  $layout->printBody();
1281  $o->closeRaw();
1282 
1283  return TRUE;
1284 
1285  }//end paintLayout()
1286 
1287 
1301  public function getKeywordsReplacementsForPaint(&$owner, &$o, &$layout, $layout_keywords_order, $set_keywords_replacement = TRUE, $invoke_backend = FALSE)
1302  {
1303  $keywords = $layout->getLayoutKeywords();
1304  $print_commit_button = FALSE;
1305 
1306  // find what screens we need to process
1307  if (!isset($keywords['screens'])) {
1308  $keywords['screens'] = Array();
1309  }
1310 
1311  if (!isset($keywords['entire_screens'])) {
1312  $keywords['entire_screens'] = Array();
1313  }
1314 
1315  $screens = array_merge(array_keys($keywords['screens']), array_keys($keywords['entire_screens']));
1316  $screens = array_unique($screens);
1317 
1318  $this->_tmp['layout_keyword_replacements'] = Array();
1319 
1320  // let the backend outputter know that we want buffering turned off
1321  $o->setBuffering(FALSE);
1322 
1323  foreach ($layout_keywords_order as $order_keyword) {
1324  // loop over the screens and get the xml file for each screen
1325  // generate some keywords for each screen
1326  if ($order_keyword == 'screen') {
1327  foreach ($screens as $screen) {
1328  // check to see if we want the entire screen
1329  $entire_screen = FALSE;
1330  if (in_array($screen, array_keys($keywords['entire_screens']))) {
1331  $entire_screen = TRUE;
1332  }
1333 
1334  // there is a problem with metadataSchemas and lookup settings
1335  // a quick fix was to add in the "if" statement a condition for
1336  // metadataschema and lookupSetting
1337 
1338  // if we have a static screen on our hands, then we want to
1339  // call the function to paint it
1340  if (isset($this->_edit_fns->static_screens[$screen]) || (($screen == 'metadataschemas') && (isset($this->_edit_fns->static_screens['metadataSchemas']))) || (($screen == 'lookupvalues') && (isset($this->_edit_fns->static_screens['lookupValues']))) ) {
1341  $static_keywords = (isset($keywords['screens'][$screen])) ? $keywords['screens'][$screen] : NULL;
1342  // for situations where there are keywords from a static screen like 'metadata' and the commit_button keyword is used
1343  if (!is_null($static_keywords)) {
1344  $print_commit_button = TRUE;
1345  }
1346  if (!is_null($static_keywords) || $entire_screen) {
1347  if (is_null($static_keywords)) {
1348  $static_keywords = Array();
1349  }
1350  if ($screen == 'metadataschemas') {
1351  if ($this->_getStaticScreenKeywordReplacements($owner, $o, 'metadataSchemas', $static_keywords, $entire_screen)) {
1352  $print_commit_button = TRUE;
1353  }
1354  } else if ($screen == 'lookupvalues') {
1355  if ($this->_getStaticScreenKeywordReplacements($owner, $o, 'lookupValues', $static_keywords, $entire_screen)) {
1356  $print_commit_button = TRUE;
1357  }
1358  } else if ($screen == 'metadata') {
1359  $layout_options = $layout->attr('options');
1360  if ($this->_getStaticScreenKeywordReplacements($owner, $o, $screen, $static_keywords, $entire_screen, $layout_options)) {
1361  $print_commit_button = TRUE;
1362  }
1363  } else if ($this->_getStaticScreenKeywordReplacements($owner, $o, $screen, $static_keywords, $entire_screen)) {
1364  $print_commit_button = TRUE;
1365  }
1366  }
1367  }//end if
1368  // Metadata & workflow don't have an xml file defined, so move onto the next screen.
1369  if ($screen == 'metadata') continue;
1370  if ($screen == 'workflow') continue;
1371  if ($screen == 'tagging') continue;
1372  if ($screen == 'settings') continue;
1373  if ($screen == 'permissions') continue;
1374  if ($screen == 'roles') continue;
1375  if ($screen == 'metadataschemas') continue;
1376  if ($screen == 'dependants') continue;
1377  if ($screen == 'linking') continue;
1378  if ($screen == 'history') continue;
1379  if ($screen == 'logs') continue;
1380  if ($screen == 'preview') continue;
1381  if ($screen == 'tagging') continue;
1382  if ($screen == 'lookupvalues') continue;
1383  if ($screen == 'layouts') continue;
1384 
1385  // its not a static screen, so get the xml file and parse it for
1386  // the keywords that we want, if the xml file exists
1387  $file = $this->findLanguageFile('screen_'.$screen);
1388  if (empty($file)) {
1389  $file = $this->findFile('screen_'.$screen);
1390  if(empty($file)) {
1391  continue;
1392  }
1393  try {
1394  $root = new SimpleXMLElement($file, LIBXML_NOCDATA, TRUE);
1395  } catch (Exception $e) {
1396  throw new Exception('Unable to parse localised screen "'.$screen.'" for asset type "'.$owner->type().'": '.$e->getMessage());
1397  }
1398 
1399  } else {
1400  $root = new SimpleXMLElement($file, LIBXML_NOCDATA, TRUE);
1401  }
1402 
1403  if ($root) {
1404  // get the layout replacements for this NON-static screen
1405  if ($this->_getLayoutKeywordReplacements($root, $o, $owner, $keywords, $screen, $entire_screen)) {
1406  $print_commit_button = TRUE;
1407  }
1408  }//end if
1409 
1410  }//end foreach
1411 
1412  }// End if screen
1413 
1414  // if there are some custom keywords, get some replacements from the owner
1415  if (isset($keywords['custom']) && !empty($keywords['custom']) && $order_keyword == 'custom') {
1416  $custom_replacements = $owner->getCustomKeywordReplacements($keywords['custom'], $invoke_backend);
1417 
1418  if (!empty($custom_replacements)) {
1419  assert_isset_array_index($custom_replacements, 'replacements');
1420  assert_isset_array_index($custom_replacements, 'print_commit_button');
1421  $replacements = Array();
1422 
1423  // rebuild the keyword so the bodycopy can properly replace it
1424  foreach ($custom_replacements['replacements'] as $keyword => $replacement) {
1425  $replacements['__custom-'.$keyword] = $replacement;
1426  }
1427  $this->_tmp['layout_keyword_replacements'] = array_merge($this->_tmp['layout_keyword_replacements'], $replacements);
1428  if ($custom_replacements['print_commit_button']) {
1429  $print_commit_button = TRUE;
1430  }
1431 
1432  }//end if
1433 
1434  }//end if
1435 
1436  }// End foreach layout_keywords_order
1437 
1438  if (!isset($keywords['layout'])) {
1439  $keywords['layout'] = Array();
1440  }
1441 
1442  // set keywords for the commit button, screen menu dropdown, or any of the
1443  // available keywords for asset being exposed
1444  foreach ($keywords['layout'] as $keyword) {
1445  if (($keyword == 'commit_button') && $print_commit_button) {
1446  ob_start();
1447  $o->commitButton('', FALSE);
1448  $this->_tmp['layout_keyword_replacements']['commit_button'] = ob_get_contents();
1449  ob_end_clean();
1450  continue;
1451 
1452  } else if (($keyword == 'commit_button_clean') && $print_commit_button) {
1453  ob_start();
1454  $o->commitButton('', FALSE, FALSE);
1455  $this->_tmp['layout_keyword_replacements']['commit_button_clean'] = ob_get_contents();
1456  ob_end_clean();
1457  continue;
1458 
1459  } else if (($keyword == 'release_locks_button')) {
1460  ob_start();
1461  submit_button('sq_lock_release_manual', translate('release_lock_button'), '', 'accesskey="r"');
1462  $this->_tmp['layout_keyword_replacements']['release_locks_button'] = ob_get_contents();
1463  ob_end_clean();
1464  continue;
1465 
1466  } else if ($keyword == 'screen_menu') {
1467  $lm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('layout_manager');
1468  // if we're using a different limbo assetid, make sure that the
1469  // assetid is being brought through
1470  if (SQ_IN_LIMBO && isset($_REQUEST['limbo_assetid'])) {
1471  $o->addFormActionGetVar('limbo_assetid', $_REQUEST['limbo_assetid'], TRUE);
1472  }
1473  $current_location = $o->getCurrentLocation();
1474  list($current_loc_base, $current_loc_query) = explode('?', $current_location);
1475 
1476  for (reset($this->_screens); NULL !== ($code = key($this->_screens)); next($this->_screens)) {
1477  if (!$lm->hasLayout($owner, $code)) continue;
1478  $url = replace_query_string_vars(Array('asset_ei_screen' => rawurlencode($code)), $current_loc_base, $current_loc_query);
1479  $o->addScreen($url, $this->_screens[$code]['name']);
1480  }
1481  foreach ($this->_edit_fns->static_screens as $code_name => $data) {
1482  if (!$lm->hasLayout($owner, $code_name)) {
1483  continue;
1484  }
1485  $url = replace_query_string_vars(Array('asset_ei_screen' => rawurlencode($code_name)), $current_loc_base, $current_loc_query);
1486  $o->addStaticScreen($url, $data['name']);
1487  }
1488  ob_start();
1489  $o->printScreenMenu();
1490  $this->_tmp['layout_keyword_replacements']['screen_menu'] = ob_get_contents();
1491  ob_end_clean();
1492 
1493  ob_start();
1494  $o->printSimpleContextSwitcher();
1495  $this->_tmp['layout_keyword_replacements']['context_switcher'] = ob_get_contents();
1496  ob_end_clean();
1497  continue;
1498 
1499  } else {
1500  $this->_tmp['layout_keyword_replacements'][$keyword] = $owner->getKeywordReplacement($keyword);
1501 
1502  // Replace Global Keywords when in a Simple Edit Layout
1503  if (strpos($this->_tmp['layout_keyword_replacements'][$keyword], '%globals_') === 0) {
1504  replace_global_keywords($this->_tmp['layout_keyword_replacements'][$keyword]);
1505  }
1506  }
1507  }//end foreach
1508 
1509  // turn buffering back on so the output is not malformed
1510  $o->setBuffering(TRUE);
1511 
1512  if (!$print_commit_button) {
1513  $this->_tmp['layout_keyword_replacements']['commit_button'] = '';
1514  $this->_tmp['layout_keyword_replacements']['commit_button_clean'] = '';
1515  }
1516 
1517  if (!$set_keywords_replacement) return $this->_tmp['layout_keyword_replacements'] ;
1518 
1519  // tell the layout what the keyword replacements are
1520  $layout->setKeywordReplacements($this->_tmp['layout_keyword_replacements']);
1521 
1522  }//end getKeywordsReplacementsForPaint()
1523 
1524 
1538  function _getStaticScreenKeywordReplacements(&$owner, &$o, $screen, $static_keywords, $get_screen=FALSE, Array $layout_options=Array())
1539  {
1540  $this->includeStaticScreen($screen);
1541  $print_commit_button = FALSE;
1542 
1543  ob_start();
1544  $paint_function = 'paint'.$screen;
1545  if ($paint_function($owner, $o, $this, $static_keywords, $layout_options)) {
1546  $print_commit_button = TRUE;
1547  }
1548 
1549  if ($get_screen) {
1550  if ($screen == 'metadataSchemas') {
1551  $this->_tmp['layout_keyword_replacements']['metadataschemas-'] = ob_get_contents();
1552  } else if ($screen == 'lookupValues') {
1553  $this->_tmp['layout_keyword_replacements']['lookupvalues-'] = ob_get_contents();
1554  } else {
1555  $this->_tmp['layout_keyword_replacements'][$screen.'-'] = ob_get_contents();
1556  }
1557  }
1558  ob_end_clean();
1559 
1560  return $print_commit_button;
1561 
1562  }//end _getStaticScreenKeywordReplacements()
1563 
1564 
1578  function _getLayoutKeywordReplacements(&$root, &$o, &$owner, $layout_keywords, $screen='details', $get_screen=FALSE)
1579  {
1580  $prefix = $owner->getPrefix();
1581  $print_commit_button = FALSE;
1582  // start buffering anything and trash the content at the end
1583  ob_start();
1584  foreach ($root->section as $section) {
1585 
1586  // find out if we have permission to print this section
1587  $limbo_access = (isset($section->attributes()->limbo_access) && (int) $section->attributes()->limbo_access == 1) ? TRUE : FALSE;
1588  if ($limbo_access == FALSE) continue;
1589 
1590  // find out what we need to get in this loop
1591  $get_section = FALSE;
1592  $section_name = strtolower(str_replace(' ', '_', (string)$section->attributes()->name));
1593  if (isset($layout_keywords['screens'][$screen]['sections'][$section_name])) {
1594  $get_section = TRUE;
1595  $section_keyword = $layout_keywords['screens'][$screen]['sections'][$section_name];
1596  }
1597 
1598  if (!($num_fields = count($section->children()))) {
1599  continue;
1600  }
1601 
1602  $section_access = $this->_getAccess($owner, $section, $prefix);
1603  if (!($section_access & SQ_EI_READ)) {
1604  continue;
1605  }
1606 
1607  // if we are getting this section, start buffering output
1608  if ($get_section) ob_start();
1609  if ($get_section || $get_screen) {
1610  $o->openSection((string)$section->attributes()->name);
1611  }
1612 
1613  if (isset($section->function_call)) {// TODO TOF FIX
1614  if ($get_section || $get_screen) {
1615  $paint_node = $section->children[0]->children[0];
1616 
1617  if (empty($paint_node->attributes['name']) || !method_exists($this->_edit_fns, $paint_node->attributes['name'])) {
1618  $o->openField('');
1619  echo translate('section_not_found', $section->attributes['name']);
1620  $o->closeField();
1621  } else {
1622  if ($this->_edit_fns->{$paint_node->attributes['name']}($owner, $o, $prefix)) {
1623  $print_commit_button = TRUE;
1624  }
1625  }
1626 
1627  // Loop over the fields to see if there's a section note
1628  for ($j = 0; $j < count($section->children); $j++) {
1629  switch ($section->children[$j]->name) {
1630  case 'note':
1631  // notice that only the last "note" will be used if multiple are supplied
1632  if (!empty($section->children[$j]->content)) {
1633  $section_note = $section->children[$j]->content;
1634  }
1635  break;
1636  }
1637  }
1638  }
1639 
1640  // they must just be normal fields
1641  } else {
1642  $section_note = NULL;
1643 
1644  // Loop over the fields
1645  foreach ($section->children() as $field) {
1646  switch ($field->getName()) {
1647  case 'field':
1648  $display_name = '';
1649  $field_note = '';
1650  $attr_tag = NULL;
1651 
1652  foreach ($field->children() as $sub_field) {
1653  switch ($sub_field->getName()) {
1654  case 'display_name':
1655  $display_name = (string)$sub_field;
1656  break;
1657 
1658  case 'note':
1659  $field_note = (string)$sub_field;
1660  break;
1661 
1662  default:
1663  if (!is_null($attr_tag)) {
1664  trigger_localised_error('SYS0194', E_USER_WARNING);
1665  } else {
1666  $attr_tag = $sub_field;
1667  }
1668  break;
1669  }//end switch
1670  }
1671 
1672  $field_access = $this->_getAccess($owner, $field, $prefix, $section_access);
1673  if (!($field_access & SQ_EI_READ)) {
1674  continue;
1675  }
1676 
1677  if (!isset($field->attributes()->format)) {
1678  $field->attributes()->format = '';
1679  }
1680 
1681  // reset get_field
1682  $get_field = FALSE;
1683 
1684  if (isset($field->attributes()->attribute)) {
1685  // find out what we need to get in this loop
1686  if (isset($layout_keywords['screens'][$screen]['fields'][(string)$field->attributes()->attribute])) {
1687  $get_field = TRUE;
1688  $field_keyword = $layout_keywords['screens'][$screen]['fields'][(string)$field->attributes()->attribute];
1689  }
1690  // if we do not want anything in this loop, continue
1691  if (!$get_field && !$get_section && !$get_screen) {
1692  continue;
1693  }
1694 
1695  if ($field->getName() != 'field') continue;
1696  $o->openField($display_name, (string)$field->attributes()->format, '', isset($field->attributes()->hidden));
1697 
1698  $attr = $owner->getAttribute((string)$field->attributes()->attribute);
1699 
1700  if (is_null($attr)) continue;
1701  if (!$attr->setEditParams($attr_tag)) continue;
1702  // if this is not a wanted keyword, then continue on our way
1703  if (isset($layout_keywords['screens'][$screen]['fields'][(string)$field->attributes()->attribute]))
1704 
1705  // start buffering for this field
1706  if ($get_field) ob_start();
1707 
1708  $attr->paint($prefix.'_'.$attr->id, !(($field_access & SQ_EI_WRITE) && $limbo_access));
1709  if (($field_access & SQ_EI_WRITE) && $limbo_access) {
1710  $print_commit_button = TRUE;
1711  }
1712 
1713  if (!empty($field_note)) {
1714 
1715  $field_note = str_replace('%description%', $attr->description, $field_note);
1716  $o->note($field_note);
1717  }
1718 
1719  // end buffering
1720  if ($get_field) {
1721  $this->_tmp['layout_keyword_replacements'][$field_keyword] = ob_get_contents();
1722  ob_end_flush();
1723  }
1724  $o->closeField();
1725 
1726  } else if ($attr_tag->getName() == 'function_call') {
1727 
1728  if (isset($field->attributes()->keyword)) {
1729  // find out what we need to get in this loop
1730  if (isset($layout_keywords['screens'][$screen]['fields'][(string)$field->attributes()->keyword])) {
1731  $get_field = TRUE;
1732  $field_keyword = $layout_keywords['screens'][$screen]['fields'][(string)$field->attributes()->keyword];
1733  }
1734  }
1735 
1736  $paint_node = $attr_tag->paint_function;
1737  if ($field->getName() != 'field') continue;
1738 
1739  $o->openField($display_name, (string)$field->attributes()->format, '', isset($field->attributes()->hidden));
1740 
1741  if ((!isset($paint_node->attributes()->name)) || !method_exists($this->_edit_fns, (string)$paint_node->attributes()->name)) {
1742  echo translate('painting_funtion_not_found');
1743  } else {
1744  if ($get_field) ob_start();
1745 
1746  if ($this->_edit_fns->{(string)$paint_node->attributes()->name}($owner, $o, $prefix)) {
1747  $print_commit_button = TRUE;
1748  }
1749  // get a replacement for this field is there is a keyword for it
1750  if ($get_field) {
1751  $this->_tmp['layout_keyword_replacements'][$field_keyword] = ob_get_contents();
1752  ob_end_flush();
1753  }
1754  }//end if
1755 
1756  $o->closeField();
1757 
1758  }//end if
1759  break;
1760 
1761  case 'note':
1762  // notice that only the last "note" will be used if multiple are supplied
1763  if (!empty($field->note)) {
1764  $section_note = (string)$field->note;
1765  }
1766  break;
1767  }//end switch
1768  }//end foreach
1769  }//end else section == function_call
1770 
1771  if ($get_section || $get_screen) {
1772  if (!empty($section_note)) {
1773  $o->sectionNote($section_note);
1774  }
1775  $o->closeSection();
1776  }
1777 
1778  if ($get_section) {
1779  $this->_tmp['layout_keyword_replacements'][$section_keyword] = ob_get_contents();
1780  ob_end_flush();
1781  }
1782  }//end for
1783 
1784  if ($get_screen) {
1785  // we might have some part of a static screen in here, so append to the end of the keyword
1786  if (!isset($this->_tmp['layout_keyword_replacements'][$screen.'-'])) {
1787  $this->_tmp['layout_keyword_replacements'][$screen.'-'] = '';
1788  }
1789  $this->_tmp['layout_keyword_replacements'][$screen.'-'] .= ob_get_contents();
1790  }
1791 
1792  // trash
1793  ob_end_clean();
1794 
1795  return $print_commit_button;
1796 
1797  }//end _getLayoutKeywordReplacements()
1798 
1799 
1810  function process(&$owner, &$o, $creating)
1811  {
1812  // determine and set the preview url
1813  // we don't care about the returned value, it's not used here
1814  $this->_determinePreviewUrl($owner, $o);
1815 
1816  $current_screen = (empty($_REQUEST['asset_ei_screen'])) ? 'details' : $_REQUEST['asset_ei_screen'];
1817 
1818  return $this->processInline($owner, $o, $creating, $current_screen);
1819 
1820  }//end process()
1821 
1822 
1834  function processInline(&$owner, &$o, $creating, $current_screen)
1835  {
1836  // used to check if anything has bed saved
1837  $saved = FALSE;
1838 
1839  // if there are no screens or static screens
1840  if (!count($this->_screens) && empty($this->_edit_fns->static_screens)) {
1841  return FALSE;
1842  }
1843 
1844  // if we are creating open the create file to see which fields we are supposed to print out
1845  if ($creating) {
1846 
1847  list($create_sections, $current_screen) = $this->_getCreateSections(FALSE);
1848  if (!count($create_sections)) return FALSE;
1849 
1850  $screens = Array($current_screen);
1851 
1852 
1853  } else {
1854 
1855  $screens = Array($current_screen);
1856 
1857  $lm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('layout_manager');
1858  $layout = $lm->getLayout($owner, $current_screen);
1859 
1860  // if we have a layout and there are some defined screen components, then these
1861  // screens also need to be processed
1862  if (!is_null($layout)) {
1863  $keywords = $layout->getLayoutKeywords();
1864 
1865  if (isset($keywords['screens']) && !empty($keywords['screens'])) {
1866  $screens = array_unique(array_merge(array_keys($keywords['screens']), $screens));
1867  }
1868 
1869  if (isset($keywords['entire_screens']) && !empty($keywords['entire_screens'])) {
1870  $screens = array_unique(array_merge(array_keys($keywords['entire_screens']), $screens));
1871  }
1872 
1873  // if there are some special keywords, we need to ask the owner to process them
1874  if (isset($keywords['custom']) && !empty($keywords['custom'])) {
1875  $owner->processCustomKeywords($keywords['custom']);
1876  }
1877  }
1878  }
1879 
1880  foreach ($screens as $active_screen) {
1881 
1882  $ret_val = FALSE;
1883 
1884  if (!$creating) {
1886  // ALLOWED SCREEN ACCESS //
1888  if (!$owner->adminAccess('')) {
1889  $allowed_screens = $this->getAllowedScreens($owner);
1890 
1891  if (!empty($allowed_screens)) {
1892  $user_is_not_allowed = TRUE;
1893  foreach ($allowed_screens as $allowed_screen) {
1894  if (isset($allowed_screen['screen']) && ($allowed_screen['screen'] == $active_screen)) {
1895  $user_is_not_allowed = FALSE;
1896  }//end if
1897  }//end foreach
1898 
1899  if ($user_is_not_allowed) {
1900  // this user is not allowed to view the current screen
1901  $GLOBALS['SQ_SYSTEM']->paintLogin(translate('login'), translate('cannot_access_asset', htmlspecialchars($owner->name, ENT_COMPAT, SQ_CONF_DEFAULT_CHARACTER_SET)));
1902  exit();
1903  }//end if
1904  }//end if
1905  }//end if
1906 
1907  }//end if
1908 
1909  // check the active screen for special system defined static screens
1910  $file = NULL;
1911  if (isset($this->_edit_fns->static_screens[$active_screen])) {
1912 
1913  // save the status for later so we can see if it changed
1914  $old_status = $owner->status;
1915 
1916  // process the system defined bit of this tab if we
1917  // are not creating the asset
1918  if (!$creating) {
1919  $process_function = 'process'.$active_screen;
1920  $this->includeStaticScreen($active_screen);
1921  if ($process_function($owner, $o, $this)) {
1922  $ret_val = TRUE;
1923  }
1924  }
1925 
1926  // If we have just reverted to the system version, so don't overwrite those
1927  // with the attribute values submitted in safe edit mode (see bug #5786)
1928  if (isset($owner->_tmp['reverting_to_system_version']) && $owner->_tmp['reverting_to_system_version']) {
1929  return TRUE;
1930  }
1931  // try and find the file to print user defined
1932  $file = @$this->findLanguageFile('screen_'.$active_screen);
1933 
1934  if (empty($file)) {
1935  // no language files, try and find the base structure
1936  $file = @$this->findFile('screen_'.$active_screen);
1937 
1938  // still can't find anything?!
1939  if (empty($file)) {
1940  $root = NULL;
1941  } else {
1942  try {
1943  $root = new SimpleXMLElement($file, LIBXML_NOCDATA, TRUE);
1944  } catch (Exception $e) {
1945  throw new Exception('Unsable to find static screen "'.$active_screen.'" for asset type "'.$owner->type().'": '.$e->getMessage());
1946  }
1947  }
1948  } else {
1949  $root_from_file = file_get_contents($file);
1950  $root = $output = simplexml_load_string($root_from_file);
1951  }
1952  } else {
1953 
1954  // must be a normal screen
1955  if (empty($this->_screens[$active_screen])) {
1956  trigger_localised_error('SYS0076', E_USER_WARNING, $active_screen);
1957  return FALSE;
1958  }
1959 
1960  // try and find the file to print user defined
1961  $root = $this->findScreen('screen_'.$active_screen);
1962 
1963  }//end if
1964 
1965  if (!is_null($root) && $owner->writeAccess('')) {
1966 
1967  // prefix for all the form vars
1968  $prefix = $owner->getPrefix();
1969 
1970  // Loop over the sections (skipping any non-sections that may
1971  // have crept in for some unknown reason)
1972  foreach ($root->section as $section) {
1973  // if we are in limbo and this section is not to be printed in limbo - dont print it
1974 
1975  if (SQ_IN_LIMBO && (!isset($section->attributes()->limbo_access) || (int)$section->attributes()->limbo_access == 0)) {
1976  continue;
1977  }
1978 
1979  // if we are printing the create interface and this section
1980  // is not included in that, ignore it
1981  if ($creating && empty($create_sections[(string)$section->attributes()->name])) {
1982  continue;
1983  }
1984 
1985  if (!($num_fields = count($section->children()))) {
1986  continue;
1987  }
1988 
1989  $section_access = $this->_getAccess($owner, $section, $prefix);
1990  if (!($section_access & SQ_EI_READ)) {
1991  continue;
1992  }
1993 
1994  // if this is section only has function call, then process accordingly
1995  if ($section->function_call) {
1996 
1997  $process_node = $section->function_call->process_function;
1998 
1999  // if there is nothing declared there is nothing for us to do
2000  if (empty($process_node) || empty($process_node->attributes()->name)) {
2001  continue;
2002  // There is something declared but it doesn't exist
2003  } else if (!method_exists($this->_edit_fns, (string)$process_node->attributes()->name)) {
2004  trigger_localised_error('SYS0188', E_USER_WARNING, $section->attributes()->name);
2005  } else {
2006  // if we are processing the create interface and this section function is not included in that, ignore it
2007  if ($creating && !in_array((string)$process_node->attributes()->name, $create_sections[(string)$section->attributes()->name])) {
2008  continue;
2009  }
2010 
2011  if ($this->_edit_fns->{(string)$process_node->attributes()->name}($owner, $o, $prefix)) {
2012  $ret_val = TRUE;
2013  }
2014 
2015  }
2016 
2017  // they must just be normal fields
2018  } else {
2019  // Loop over the fields
2020  foreach ($section->field as $field) {
2021  if ($field->getName() == 'note') continue;
2022 
2023  $child_fields = $field->children();
2024  // in the previous implementation of matrix the first child
2025  // was the "display_name" and the second last was the "note"
2026  // So the last child was the remaining element (i.e.: text, boolean, email)
2027  // we are now changing it so $last_child variable contains the element which
2028  // is not the "display_name" or not the "note' element
2029  // $last_child = $child_fields->{count($child_fields)-1};
2030  $last_child = NULL;
2031  foreach ($child_fields as $child) {
2032  $child_name = $child->getName();
2033  if (($child_name != 'display_name') && ($child_name != 'note')) {
2034  $last_child = $child;
2035  break;
2036  }
2037  }
2038 
2039  $field_access = $this->_getAccess($owner, $field, $prefix, $section_access);
2040  if (!($field_access & SQ_EI_WRITE)) {
2041  continue;
2042  }
2043 
2044  if (!empty($field->attributes()->attribute)) {
2045  // if this ain't a field, or if we are printing the create interface and this field is not included in that, ignore it
2046  if ($field->getName() != 'field' || ($creating && (empty($field->attributes()->attribute) || !in_array((string)$field->attributes()->attribute, $create_sections[(string)$section->attributes()->name])))) {
2047  continue;
2048  }
2049 
2050  $attr = $owner->getAttribute((string)$field->attributes()->attribute);
2051  if (is_null($attr)) continue;
2052  if (!$attr->setEditParams($last_child)) continue;
2053 
2054  $revert_attr = $attr;
2055  $attr->process($prefix.'_'.$attr->id, $owner->id);
2056  if ($attr->processed && $owner->setAttrValue($attr->name, $attr->value)) {
2057  $ret_val = TRUE;
2058  } else {
2059  // processing failed so revert to old version
2060  $attr = $revert_attr;
2061  }
2062  unset($revert_attr);
2063 
2064  } else if ($last_child->getName() == 'function_call') {
2065 
2066  // If there is no process function node at all, then skip
2067  if (!isset($last_child->process_function)) continue;
2068 
2069  $process_node = $last_child->process_function;
2070 
2071  // if this ain't a field, or if we are printing the create interface and this field is not included in that, ignore it
2072  if ($field->getName() != 'field' || ($creating && !in_array((string)$process_node->attributes()->name, $create_sections[(string)$section->attributes()->name]))) {
2073  continue;
2074  }
2075 
2076  // if there is nothing declared there is nothing for use to do
2077  if (!isset($process_node->attributes()->name)) {
2078  continue;
2079  // There is something declared but it doesn't exist
2080  } else if (!method_exists($this->_edit_fns, (string)$process_node->attributes()->name)) {
2081  trigger_localised_error('SYS0187', E_USER_WARNING, (string)$section->attributes()->name, (string)$last_child);
2082  } else {
2083  if ($this->_edit_fns->{(string)$process_node->attributes()->name}($owner, $o, $prefix)) {
2084  $ret_val = TRUE;
2085  }
2086  }
2087 
2088  }//end if
2089 
2090  }//end foreach fields
2091 
2092  }//end else section funcion call
2093 
2094  }//end foreach
2095 
2096  }//end if $file
2097 
2098  if ($ret_val) {
2099  // some attributes have been updated, so save the asset
2100  if ($owner->saveAttributes()) $saved = TRUE;
2101  }
2102 
2103  }//end foreach screens
2104 
2105  return $saved;
2106 
2107  }//end processInline()
2108 
2109 
2122  function _getAccess(&$owner, $node, $prefix, $inherit_access=NULL)
2123  {
2124  $access = 0;
2125 
2126  // check show if condition for this node
2127  if (isset($node->attributes()->show_if)) {
2128  $show_if_fn = (string)$node->attributes()->show_if;
2129  $edit_fns = $owner->getEditFns();
2130 
2131  if (method_exists($edit_fns, $show_if_fn)) {
2132  if (!$edit_fns->$show_if_fn($owner, $prefix)) return 0;
2133  } else {
2134  // if show if function doesn't exist, error, then continue as normal
2135  trigger_localised_error('SYS0136', E_USER_WARNING, $show_if_fn, $node->name);
2136  return 0;
2137  }
2138  }
2139 
2140  // if there is nothing specified, and if an inherited access was specified we must use that
2141  if (!isset($node->attributes()->write_access) && !is_null($inherit_access)) {
2142  if ($inherit_access & SQ_EI_WRITE) {
2143  $access |= SQ_EI_WRITE;
2144  }
2145 
2146  // otherwise attempt to find write access
2147  } else {
2148  $wa = (!isset($node->attributes()->write_access)) ? 'write:all' : (string)$node->attributes()->write_access;
2149  // all these write access checks must have a lock type to use
2150  if (preg_match('/^(.+):(.*)$/', $wa, $matches)) {
2151  // got to have writeAccess at least (this checks for locks as well)
2152  if ($owner->writeAccess($matches[2])) {
2153  switch ($matches[1]) {
2154  case 'root' :
2155  if ($GLOBALS['SQ_SYSTEM']->userRoot()) {
2156  $access |= SQ_EI_WRITE;
2157  }
2158  break;
2159  case 'sys_admin' :
2160  if ($GLOBALS['SQ_SYSTEM']->userRoot() || $GLOBALS['SQ_SYSTEM']->userSystemAdmin()) {
2161  $access |= SQ_EI_WRITE;
2162  }
2163  break;
2164  case 'admin' :
2165  if ($owner->adminAccess($matches[2])) {
2166  $access |= SQ_EI_WRITE;
2167  }
2168  break;
2169  case 'write' :
2170  $access |= SQ_EI_WRITE; // this was checked above
2171  break;
2172 
2173  case 'none' :
2174  // meaning that this attribute is not to be written
2175  break;
2176 
2177  }//end switch
2178  }//end if write access
2179  }//end if preg
2180 
2181  }//end else
2182 
2183  // if they have write access they have read access by definition
2184  if ($access & SQ_EI_WRITE) {
2185  $access |= SQ_EI_READ;
2186  } else {
2187 
2188  // if there is nothing specified, and if an inherited access was specified we must use that
2189  if (!isset($node->attributes()->read_access) && !is_null($inherit_access)) {
2190  if ($inherit_access & SQ_EI_READ) {
2191  $access |= SQ_EI_READ;
2192  }
2193 
2194  // otherwise attempt to find read access
2195  } else {
2196  $ra = (!isset($node->attributes()->read_access)) ? 'read' : (string)$node->attributes()->read_access;
2197  switch ($ra) {
2198  case 'root' :
2199  if ($GLOBALS['SQ_SYSTEM']->userRoot()) {
2200  $access |= SQ_EI_READ;
2201  }
2202  break;
2203  case 'sys_admin' :
2204  if ($GLOBALS['SQ_SYSTEM']->userRoot() || $GLOBALS['SQ_SYSTEM']->userSystemAdmin()) {
2205  $access |= SQ_EI_READ;
2206  }
2207  break;
2208  case 'read' :
2209  if ($owner->readAccess()) $access |= SQ_EI_READ;
2210  break;
2211  default :
2212  // if it's admin or write access, there needs to be a lock type to use
2213  if (preg_match('/^(admin|write):(.*)$/', $ra, $matches)) {
2214  if ($matches[1] == 'admin') {
2215  if ($owner->adminAccess($matches[2])) {
2216  $access |= SQ_EI_READ;
2217  }
2218  } else {
2219  if ($owner->writeAccess($matches[2])) {
2220  $access |= SQ_EI_READ;
2221  }
2222  }
2223  }
2224 
2225  }//end switch
2226  }//end else
2227 
2228  }//end else
2229 
2230  return $access;
2231 
2232  }//end _getAccess()
2233 
2234 
2243  function getAllowedScreens(&$owner)
2244  {
2245  $db = MatrixDAL::getDb();
2246 
2247  // get all the user groups that we exist in
2248  $user =& $GLOBALS['SQ_SYSTEM']->am->getAsset($GLOBALS['SQ_SYSTEM']->currentUserId());
2249  $groups = $user->getUserGroups();
2250  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($user);
2251 
2252  if (empty($groups)) return Array(); // all screens allowed
2253 
2254  $bind_vars = Array();
2255  foreach ($groups as $key => $group) {
2256  $bind_vars['group_'.$key] = (string) $group;
2257  }
2258 
2259  $sql = 'SELECT screen, section
2260  FROM '.SQ_TABLE_RUNNING_PREFIX.'ast_edit_access ';
2261  $where = 'userid IN (:'.implode(', :', array_keys($bind_vars)).')';
2262 
2263  require_once SQ_FUDGE_PATH.'/db_extras/db_extras.inc';
2264  $where .= ' AND (type_code = :null_type_code
2265  OR type_code IN (
2266  SELECT inhd_type_code
2267  FROM sq_ast_typ_inhd
2268  WHERE type_code = :type_code
2269  ))';
2270  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where);
2271 
2272  try {
2273  $query = MatrixDAL::preparePdoQuery($sql.$where);
2274  foreach ($bind_vars as $bind_var => $bind_value) {
2275  MatrixDAL::bindValueToPdo($query, $bind_var, $bind_value);
2276  }
2277  MatrixDAL::bindValueToPdo($query, 'null_type_code', '0');
2278  MatrixDAL::bindValueToPdo($query, 'type_code', $owner->type());
2279  $allowed_screens = MatrixDAL::executePdoAssoc($query);
2280  } catch (Exception $e) {
2281  throw new Exception('Unable to get allowed screens for type code: '.$owner->type().' due to database error: '.$e->getMessage());
2282  }
2283  return $allowed_screens;
2284 
2285  }//end getAllowedScreens()
2286 
2287 
2298  function findFile($file_name, $throw_error=TRUE)
2299  {
2300  $file_name = 'edit_interface_'.$file_name.'.xml';
2301 
2302  $file = '';
2303  for ($i = 0; $i < count($this->_dirs); $i++) {
2304  if (file_exists($this->_dirs[$i].'/'.$file_name)) {
2305  $file = $this->_dirs[$i].'/'.$file_name;
2306  break;
2307  }
2308  }
2309  if ( (!$file) && $throw_error) {
2310  trigger_localised_error('SYS0065', E_USER_WARNING, $file_name, $this->_type_code);
2311  return FALSE;
2312  }
2313 
2314  return $file;
2315 
2316  }//end findFile()
2317 
2318 
2331  function findLanguageFile($file_name, $include_asset=TRUE)
2332  {
2333  $type_parents = $GLOBALS['SQ_SYSTEM']->am->getTypeAncestors($this->_type_code, $include_asset);
2334  array_unshift($type_parents, $this->_type_code);
2335 
2336  $file = '';
2337  $test_locales = Array();
2338  foreach ($GLOBALS['SQ_SYSTEM']->lm->locale_stack as $locale) {
2339  list($lang, $country, $variant) = $GLOBALS['SQ_SYSTEM']->lm->getLocaleParts($locale);
2340 
2341  if (!is_null($variant)) {
2342  $test_locales[] = $lang.'_'.$country.'@'.$variant;
2343  }
2344  if (!is_null($country)) {
2345  $test_locales[] = $lang.'_'.$country;
2346  }
2347  $test_locales[] = $lang;
2348  }
2349 
2350  foreach ($test_locales as $locale) {
2351 
2352  foreach ($type_parents as $type_code) {
2353  $file_path = SQ_DATA_PATH.'/private/asset_types/'.$type_code.'/localised_screens/'.$file_name.'.'.$locale;
2354  if (file_exists($file_path)) {
2355  $file = $file_path;
2356  break;
2357  }
2358  }
2359 
2360  if (!empty($file)) break;
2361 
2362  }
2363  return $file;
2364 
2365  }//end findLanguageFile()
2366 
2367 
2385  function &findScreen($screen_name)
2386  {
2387  $root = NULL;
2388 
2389  if (($file = $this->findFile($screen_name))) {
2390  try {
2391  $root = new SimpleXMLElement($file, LIBXML_NOCDATA, TRUE);
2392  } catch (Exception $e) {
2393  throw new Exception('Unable to parse screen file "'.$file.'": '.$e->getMessage());
2394  }
2395 
2396  // if empty, then just skip the searching for language files,
2397  // otherwise find the closest language file
2398  if (!empty($root) && (count($root->children()) > 0)) {
2399  $lang_file = $this->findLanguageFile($screen_name);
2400  if (empty($lang_file)) {
2401  trigger_localised_error('SYS0197', E_USER_WARNING, $screen_name);
2402  $root = NULL;
2403  return $root;
2404  } else {
2405  $root_xml = file_get_contents($lang_file);
2406  $root = simplexml_load_string($root_xml);
2407  }
2408  }
2409  }
2410 
2411  return $root;
2412 
2413  }//end findScreen()
2414 
2415 
2425  function _getCreateSections($painting)
2426  {
2427  $create_sections = Array();
2428 
2429  if (!($create_file = $this->findFile('create'))) {
2430  return Array($create_sections, '');
2431  }
2432 
2433  try {
2434  $root = simplexml_load_file($create_file);
2435  } catch (Exception $e) {
2436  throw new Exception('Unable to parse Create screen file "'.$create_file.'": '.$e->getMessage());
2437  }
2438 
2439  // Loop over the sections
2440  foreach ($root->section as $section) {
2441 
2442  $create_sections[(string)$section->attributes()->name] = Array();
2443  // Loop over the fields
2444 
2445  foreach ($section->children() as $field) {
2446  switch ($field->getName()) {
2447  case 'function_call' :
2448  if ($painting) {
2449  $node_name = 'paint_function';
2450  } else {
2451  $node_name = 'process_function';
2452  }
2453  $fn_node = $field->{$node_name};
2454  $create_sections[(string)$section->attributes()->name][] = (string)$fn_node->attributes()->name;
2455  break;
2456 
2457  case 'field' :
2458  if (isset($field->attributes()->attribute)) {
2459  $create_sections[(string)$section->attributes()->name][] = (string)$field->attributes()->attribute;
2460  } else if (isset($field->function_call)) {
2461  // There is a function call
2462  if ($painting) {
2463  $node_name = 'paint_function';
2464  } else {
2465  $node_name = 'process_function';
2466  }
2467  $fn_node = $field->function_call->{$node_name};
2468  if (isset($fn_node['name'])) {
2469  $create_sections[(string)$section->attributes()->name][] = (string)$fn_node->attributes()->name;
2470  }
2471  } else {
2472  throw new Exception('Unable to parse Create screen file "'.$create_file.'": it contains a field tag without an attribute or function call specified:'.$field->asXml());
2473  } //end if
2474  break;
2475 
2476  }// end switch
2477 
2478  }//end foreach
2479 
2480  }//end foreach
2481 
2482  return Array($create_sections, (string)$root->attributes()->screen);
2483 // return Array($create_sections, $root->attributes['screen']);
2484 
2485  }//end _getCreateSections()
2486 
2487 
2496  function includeStaticScreen($screen)
2497  {
2498  require_once SQ_INCLUDE_PATH.'/asset_static_screens/'.$screen.'.inc';
2499 
2500  }//end includeStaticScreen()
2501 
2502 
2513  function findSpecificFile($file_name, $throw_error=TRUE)
2514  {
2515  if (file_exists($file_name)) return $file_name;
2516  if ($throw_error) {
2517  trigger_localised_error('SYS0065', E_USER_WARNING, $file_name, $this->_type_code);
2518  return FALSE;
2519  }
2520 
2521  return FALSE;
2522 
2523  }//end findSpecificFile()
2524 
2525 
2533  function &findSpecificScreen($specific_file)
2534  {
2535  $root = NULL;
2536  if (($file = $this->findSpecificFile($specific_file))) {
2537  try {
2538  $root = new SimpleXMLElement($file, LIBXML_NOCDATA, TRUE);
2539  return $root;
2540  } catch (Exception $e) {
2541  throw new Exception('Unable to parse specific screen file "'.$file.'": '.$e->getMessage());
2542  $root = NULL;
2543  return $root;
2544  }
2545 
2546  // if empty, then just skip the searching for language files,
2547  // otherwise find the closest language file
2548  if (!empty($root) && (count($root->children()) > 0)) {
2549  $lang_file = $this->findLanguageFile($screen_name, FALSE);
2550  if (empty($lang_file)) {
2551  $root = NULL;
2552  return $root;
2553  } else {
2554  $root = unserialize(file_get_contents($lang_file));
2555  }
2556  }
2557  }
2558 
2559  return $root;
2560 
2561  }//end findSpecificScreen()
2562 
2563 
2579  function getSimpleEditKeywords($asset_type='page_standard', &$o)
2580  {
2581 
2582  $ei = new Asset_Edit_Interface($asset_type);
2583 
2584  $GLOBALS['SQ_SYSTEM']->am->includeAsset($asset_type);
2585  $as = new $asset_type();
2586  $asset_info = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($asset_type);
2587  $asset_dir = SQ_SYSTEM_ROOT.'/'.$asset_info['dir'];
2588  $ef = $as->getEditFns();
2589 
2590  $screens_static = Array();
2591  $screens_specific = Array();
2592 
2593  foreach ($ef->static_screens as $key => $screen) {
2594  $screens_static[$screen['name']] = $key;
2595  }
2596 
2597  $screens_all = $screens_static;
2598  foreach ($ei->getScreens() as $key => $screen) {
2599  $screens_specific[$screen['name']] = $key;
2600  $screens_all[$screen['name']] = $key;
2601  }
2602 
2603  $o->openRaw();
2604  ?>
2605  <div><h1 style="font-size:1.7em;">General Screens</h1></div>
2606  <?php
2607  $o->closeRaw();
2608 
2609  // loop through all the screen and all the xml files
2610  foreach ($screens_all as $current_screen_name => $current_screen) {
2611 
2612  // the dependant and format screens have some problems with the links displayed
2613  // therefore we dont display dependants and format screens keywords
2614  // until they are fixed
2615  if ($current_screen == 'dependants') continue;
2616  $section_array = Array();
2617 
2618  if ($this->findFile('static_screen_'.$current_screen, FALSE)) {
2619  $root = $this->findScreen('static_screen_'.$current_screen);
2620 
2621  foreach ($root->section as $section) {
2622 
2623  // if the section should not be displayed, continue
2624  if ((isset($section->attributes()->limbo_access)) && (((int) $section->attributes()->limbo_access) === 0)) {
2625  continue;
2626  }
2627 
2628  $current_section_name = (string) $section->attributes()->name;
2629 
2630  if (!isset($section_array[$current_section_name])) {
2631  $section_array[$current_section_name] = Array();
2632  }
2633 
2634  foreach ($section->children() as $field) {
2635  $keyword = (string) $field->attributes()->code;
2636  if (!empty($keyword)) {
2637  $section_array[$current_section_name][] = $keyword;
2638  }
2639  }
2640 
2641  }
2642  }
2643 
2644  if ($this->findFile('screen_'.$current_screen, FALSE)) {
2645  $root = $this->findScreen('screen_'.$current_screen);
2646 
2647  foreach ($root->section as $section) {
2648 
2649  // if the section should not be displayed, continue
2650  if ((isset($section->attributes()->limbo_access)) && (((int) $section->attributes()->limbo_access) === 0)) {
2651  continue;
2652  }
2653 
2654  $current_section_name = (string) $section->attributes()->name;
2655  if (!isset($section_array[$current_section_name])) {
2656  $section_array[$current_section_name] = Array();
2657  }
2658 
2659  foreach ($section->children() as $field) {
2660  $keyword = (string) $field->attributes()->attribute;
2661  if (!empty($keyword)) {
2662  $section_array[$current_section_name][] = $keyword;
2663 
2664  }
2665  }
2666  }
2667  }
2668 
2669  if ($tmpFile=$this->findSpecificFile($asset_dir.'/edit_interface_screen_'.$current_screen.'.xml', FALSE)) {
2670 
2671  $root = $this->findSpecificScreen($tmpFile);
2672 
2673  foreach ($root->section as $section) {
2674 
2675  // if the section should not be displayed, continue
2676  if ((isset($section->attributes()->limbo_access)) && ((int) $section->attributes()->limbo_access === 0)) {
2677  continue;
2678  }
2679 
2680  $current_section_name = (string) $section->attributes()->name;
2681 
2682  if (!isset($section_array[$current_section_name])) {
2683  $section_array[$current_section_name] = Array();
2684  }
2685 
2686  foreach ($section->children() as $field) {
2687  $keyword = (string) $field->attributes()->attribute;
2688  if (empty($keyword)) {
2689  $keyword = $field->attributes()->keyword;
2690  }
2691  if (!empty($keyword)) {
2692  $section_array[$current_section_name][] = $keyword;
2693  }
2694  }
2695 
2696  }
2697 
2698  // remove duplicates fields
2699  foreach ($section_array as $key => $value) {
2700  $value = (array_unique($value));
2701  $section_array[$key]= $value;
2702  }
2703  }//end if
2704 
2705  $o->openRaw();
2706  ?>
2707  <style type="text/css">
2708  .screen_kw, .section_kw, .field_kw {
2709  font-weight:normal;
2710  }
2711 
2712  .field_kw {
2713  display:block;
2714  }
2715 
2716  .section_title, .field_title {
2717  }
2718 
2719  .section_title {
2720  }
2721  .field_title {
2722  margin:0;
2723  padding:0;
2724  }
2725  #limbo_keywords .sq-backend-field {
2726  padding-bottom:0;
2727  }
2728  </style>
2729  <div id="limbo_keywords">
2730  <?php
2731 
2732  $o->closeRaw();
2733  $counter = 0;
2734  reset($screens_specific);
2735 
2736  if (!strcmp($current_screen, current($screens_specific))) {
2737 
2738  $o->openRaw();
2739  ?>
2740  <div><h1 style="font-size:1.7em;">Asset Specific Screens</h1></div>
2741  <?php
2742  $o->closeRaw();
2743 
2744  }
2745 
2746  // the dependant and format screens have some problems with the links displayed
2747  // therefore we dont display dependants and format screens keywords
2748  // until they are fixed
2749  if ($current_screen == 'formats') continue;
2750 
2751  if (strtolower($current_screen) != 'contents') {
2752  $o->openSection($current_screen_name.' screen'.' <span class="screen_kw">(%'.str_replace(' ', '_', strtolower($current_screen)).'-%)</span>');
2753  } else {
2754  if (in_array($asset_type, Array('page_standard', 'calendar_event_multi_date'))) {
2755  $o->openSection($current_screen_name.' screen'.' <span class="screen_kw">(%__custom-'.str_replace(' ', '_', strtolower($current_screen)).'%)</span>');
2756  $o->closeSection();
2757  continue;
2758  } else {
2759  // list of asset types that should not get this limbo keyword
2760  $filter_list = Array('image');
2761  if (!in_array($asset_type, $filter_list)) {
2762  $o->openSection($current_screen_name.' screen'.' <span class="screen_kw">(%'.str_replace(' ', '_', strtolower($current_screen)).'-%)</span>');
2763  } else {
2764  continue;
2765  }
2766  }
2767  }
2768 
2769  foreach ($section_array as $tmp_section => $tmp_fields) {
2770  // if the section name is empty
2771  if (strlen($tmp_section) > 0) {
2772  $o->openSection('<span class="section_title">Section <strong>"'.$tmp_section.'"</strong></span> <span class="section_kw">(%'.$current_screen.'-S_'.strtolower(str_replace(' ', '_', $tmp_section)).'%)</span>');
2773  } else {
2774  $o->openSection('&nbsp;');
2775  }
2776 
2777  // display the fields of that section
2778  foreach ($tmp_fields as $tmp_field) {
2779  $o->openField('<span class="field_title">Field <strong>"'.$tmp_field.'"</strong></span>');
2780  echo '<span class="field_kw">%'.$current_screen.'-F_'.$tmp_field.'%</span>';
2781  $o->closeField();
2782  }
2783 
2784  $o->closeSection();
2785  }
2786 
2787  if (!strcmp(strtolower($current_screen_name), 'metadata')) {
2788  $o->openField('<span class="field_title"><strong>Print a specific metadata section name</strong></span> ');
2789  echo '<span class="field_kw">%metadata-F_section_{metadata section id}_name%</span>';
2790  $o->closeField();
2791  $o->openField('<span class="field_title"><strong>Print a specific metadata section description</strong></span> ');
2792  echo '<span class="field_kw">%metadata-F_section_{metadata section id}_description%</span>';
2793  $o->closeField();
2794  $o->openField('<span class="field_title"><strong>Print a specific metadata section interface</strong></span> ');
2795  echo '<span class="field_kw">%metadata-F_section_{metadata section id}_values%</span>';
2796  $o->closeField();
2797  $o->openField('<span class="field_title"><strong>Print a specific metadata schema field</strong></span> ');
2798  echo '<span class="field_kw">%metadata-F_{metadata schema field id}%</span>';
2799  $o->closeField();
2800  $o->openRaw();
2801  echo '<span class="field_title">For example: %metadata-F_99999%</span>';
2802  $o->closeRaw();
2803  }
2804 
2805  $o->closeSection();
2806  $o->openRaw();
2807  echo '</div>';
2808  $o->closeRaw();
2809  }//end foreach
2810 
2811  }//end getSimpleEditKeywords()
2812 
2822  function _getLayoutKeywordsOrder($layout)
2823  {
2824  // Check which of screen or custom keywords are placed before in raw content
2825  // This should be FALSE instead of 0 because making it 0, we mean that it is actually found already
2826  $custom_pos = FALSE;
2827  $screen_pos = FALSE;
2828 
2829  // Defaut order
2830  $layout_keywords_order = Array(
2831  0 => 'screen',
2832  1 => 'custom'
2833  );
2834 
2835  $containers = $layout->getContainers();
2836 
2837  foreach (array_keys($containers) as $key) {
2838 
2839  $container = $containers[$key];
2840  ob_start();
2841  $container->getEditFns()->paint($container, FALSE, FALSE);
2842  $raw_content = ob_get_contents();
2843  ob_end_clean();
2844 
2845  $custom_pos = strpos($raw_content, '%__custom');
2846 
2847  $screen_pos_metadata = strpos($raw_content, '%metadata');
2848  $screen_pos_lookups = strpos($raw_content, '%lookupvalues-');
2849 
2850  if ($screen_pos_metadata !== FALSE) $screen_pos = $screen_pos_metadata;
2851 
2852  if (($screen_pos_lookups !== FALSE) && ($screen_pos_metadata > $screen_pos_lookups)) $screen_pos = $screen_pos_lookups;
2853 
2854  // If any of the keywords are found then exit, as we are checking their first occurance only
2855  if ($custom_pos || $screen_pos) {
2856  break;
2857  }
2858  }
2859 
2860  // Check which of screen or custom keywords are placed before in raw content
2861  // if we just find a custom keyword and no screen keyword we should make sure we
2862  // still place 'custom' before 'screen' in layout_keywords_order
2863  // Bug #4458 Conflicting WYSIWYG's
2864  if (($screen_pos > $custom_pos && $custom_pos !== FALSE) || ($custom_pos !== FALSE && $screen_pos === FALSE)) {
2865  $layout_keywords_order = Array(
2866  0 => 'custom',
2867  1 => 'screen'
2868  );
2869  }
2870 
2871  return $layout_keywords_order;
2872 
2873  }// end function
2874 
2875 }//end class
2876 
2877 ?>