Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
site.inc
1 <?php
18 require_once SQ_CORE_PACKAGE_PATH.'/folder/folder.inc';
19 
31 class Site extends Folder
32 {
33 
34 
41  function __construct($assetid=0)
42  {
43  parent::__construct($assetid);
44 
45  }//end constructor
46 
47 
54  public function lockTypes()
55  {
56  $lock_types = parent::lockTypes();
57  $lock_types['attr_links'] = ($lock_types['attributes'] | $lock_types['links']);
58  return $lock_types;
59 
60  }//end lockTypes()
61 
62 
72  public function getWebPaths($url=FALSE)
73  {
74  // because we never have paths, we can only return the urls
75  return Array();
76 
77  }//end getWebPaths()
78 
79 
89  public function addWebPath($url)
90  {
91  return FALSE;
92 
93  }//end addWebPath()
94 
95 
105  public function deleteWebPath($url)
106  {
107  return FALSE;
108 
109  }//end deleteWebPath()
110 
111 
122  public function delete($release_lock=TRUE)
123  {
124  $this->_tmp['deleting_site'] = TRUE;
125  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
126  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
127 
128  if (!$this->saveWebURLs(Array())) {
129  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
130  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
131  return FALSE;
132  }
133 
134  if (!parent::delete($release_lock)) {
135  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
136  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
137  return FALSE;
138  }
139 
140  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
141  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
142  $this->_tmp['deleting_site'] = FALSE;
143 
144  return TRUE;
145 
146  }//end delete()
147 
148 
155  public function getSiteURLs()
156  {
157  $db = MatrixDAL::getDb();
158 
159  if (!isset($this->_tmp['urls_info'])) {
160  $sql = 'SELECT urlid, url, http, https, base_contextid
161  FROM '.SQ_TABLE_RUNNING_PREFIX.'ast_url
162  ';
163  $where = 'assetid = :assetid';
164  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where);
165  $sql .= $where.' ORDER BY urlid';
166 
167  try {
168  $query = MatrixDAL::preparePdoQuery($sql);
169  MatrixDAL::bindValueToPdo($query, 'assetid', $this->id);
170  $result_x = MatrixDAL::executePdoGroupedAssoc($query);
171 
172  // TODO: DAL always , whereas I THINK this depends on PEAR DB's
173  // ability to - so need to convert - need better way of doing this...
174  $result = Array();
175  foreach ($result_x as $key => $row) {
176  $result[$key] = $row[0];
177  }
178  unset($result_x);
179  } catch (Exception $e) {
180  throw new Exception('Unable to get applied schemas for asset ID #'.$this->id.' due to database error: '.$e->getMessage());
181  }
182 
183  $this->_tmp['urls_info'] = $result;
184 
185  }//end if not cached
186 
187  return $this->_tmp['urls_info'];
188 
189  }//end getSiteURLs()
190 
191 
202  public function saveWebURLs(Array $save_urls)
203  {
204  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
205  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
206  $db = MatrixDAL::getDb();
207  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
208 
209  $updated = FALSE;
210  $processed_urlids = Array();
211  $current_urls = $this->getSiteURLs();
212  $system_root_urls = explode("\n", SQ_CONF_SYSTEM_ROOT_URLS);
213 
214  for (reset($save_urls); NULL !== ($save_urlid = key($save_urls)); next($save_urls)) {
215  // If for some reason there is no base context ID yet defined, set it to zero (default)
216  $save_urls[$save_urlid]['base_contextid'] = array_get_index($save_urls[$save_urlid], 'base_contextid', 0);
217 
218  $curr_urlid = $save_urlid;
219 
220  // strip any extra slashes
221  $save_urls[$save_urlid]['url'] = strip_url($save_urls[$save_urlid]['url'], TRUE);
222 
224  $paths = explode('/', $save_urls[$save_urlid]['url']);
225  // remove the domain
226  array_shift($paths);
227 
228  foreach ($paths as $path) {
229  $clean_paths = make_valid_web_paths(Array($path));
230  $clean_path = (empty($clean_paths)) ? '' : $clean_paths[0];
231  if ($path != $clean_path) {
232  if ($clean_path != '') {
233  trigger_localised_error('CORE0080', $save_urls[$save_urlid]['url'], $path, $clean_path, E_USER_WARNING);
234  } else {
235  trigger_localised_error('CORE0124', $save_urls[$save_urlid]['url'], $path, E_USER_WARNING);
236  }
237 
238  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
239  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
240  return FALSE;
241  }
242  }
243 
245 
246  $found_root_url = FALSE;
247  foreach ($system_root_urls as $root_url) {
248  if (substr($save_urls[$save_urlid]['url'], 0, strlen($root_url)) == $root_url) {
249  $found_root_url = TRUE;
250  break;
251  }
252  }
253 
254  if (!$found_root_url) {
255  trigger_localised_error('CORE0082', E_USER_WARNING, $save_urls[$save_urlid]['url']);
256  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
257  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
258  return FALSE;
259  }
260 
262 
263  $found = FALSE;
264  for (reset($current_urls); NULL !== ($i = key($current_urls)); next($current_urls)) {
265  if ($save_urls[$save_urlid]['url'] == $current_urls[$i]['url']) {
266  $found = TRUE;
267  break;
268  }
269  }
270 
271  // We don't have it. Does anyone else?
272  if (!$found) {
273  $asset = $GLOBALS['SQ_SYSTEM']->am->getAssetFromURL(NULL, $save_urls[$save_urlid]['url'], TRUE, TRUE);
274  if (!is_null($asset)) {
275  trigger_localised_error('CORE0081', E_USER_WARNING, $save_urls[$save_urlid]['url'], $asset->name, $asset->id);
276 
277  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
278  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
279  return FALSE;
280  }
281  }
282 
283  // are we an existing or an new one
284  if (isset($current_urls[$save_urlid])) {
285  // we are an existing one
286  if ($current_urls[$save_urlid]['url'] != $save_urls[$save_urlid]['url'] ||
287  $current_urls[$save_urlid]['http'] != $save_urls[$save_urlid]['http'] ||
288  $current_urls[$save_urlid]['https'] != $save_urls[$save_urlid]['https'] ||
289  $current_urls[$save_urlid]['base_contextid'] != $save_urls[$save_urlid]['base_contextid']) {
290 
291  $sql = 'UPDATE
292  sq_ast_url
293  SET
294  url = :url,
295  http = :http,
296  https = :https,
297  base_contextid = :base_contextid
298  WHERE
299  urlid = :urlid
300  AND assetid = :assetid';
301 
302  try {
303  $query = MatrixDAL::preparePdoQuery($sql);
304  MatrixDAL::bindValueToPdo($query, 'url', $save_urls[$save_urlid]['url']);
305  MatrixDAL::bindValueToPdo($query, 'http', $save_urls[$save_urlid]['http']);
306  MatrixDAL::bindValueToPdo($query, 'https', $save_urls[$save_urlid]['https']);
307  MatrixDAL::bindValueToPdo($query, 'base_contextid', $save_urls[$save_urlid]['base_contextid']);
308  MatrixDAL::bindValueToPdo($query, 'urlid', $save_urlid);
309  MatrixDAL::bindValueToPdo($query, 'assetid', $this->id);
310  MatrixDAL::execPdoQuery($query);
311  $updated = TRUE;
312  } catch (Exception $e) {
313  throw new Exception('Unable to update URLs for asset "'.$this->name.'" (#'.$this->id.') due to database error: '.$e->getMessage());
314  }
315  }
316 
317  } else {
318  // we are not going to insert same url
319  foreach ($current_urls as $url) {
320  if($save_urls[$save_urlid]['url'] === $url['url']) {
321  trigger_localised_error('CORE0081', E_USER_WARNING, $save_urls[$save_urlid]['url'], $this->name, $this->id);
322  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
323  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
324  return FALSE;
325  }
326  }
327 
328  // we are a new one
329  $curr_urlid = MatrixDAL::executeOne('core', 'seqNextVal', Array('seqName' => 'sq_ast_url_seq'));
330 
331  $sql = 'INSERT INTO
332  sq_ast_url
333  (
334  urlid,
335  assetid,
336  url,
337  http,
338  https,
339  base_contextid
340  )
341  VALUES
342  (
343  :urlid,
344  :assetid,
345  :url,
346  :http,
347  :https,
348  :base_contextid
349  )';
350 
351  try {
352  $query = MatrixDAL::preparePdoQuery($sql);
353  MatrixDAL::bindValueToPdo($query, 'url', $save_urls[$save_urlid]['url']);
354  MatrixDAL::bindValueToPdo($query, 'http', $save_urls[$save_urlid]['http']);
355  MatrixDAL::bindValueToPdo($query, 'https', $save_urls[$save_urlid]['https']);
356  MatrixDAL::bindValueToPdo($query, 'urlid', $curr_urlid);
357  MatrixDAL::bindValueToPdo($query, 'assetid', $this->id);
358  MatrixDAL::bindValueToPdo($query, 'base_contextid', $save_urls[$save_urlid]['base_contextid']);
359  MatrixDAL::execPdoQuery($query);
360  $updated = TRUE;
361  } catch (Exception $e) {
362  throw new Exception('Unable to insert URLs for asset "'.$this->name.'" (#'.$this->id.') due to database error: '.$e->getMessage());
363  }
364 
365  }//end if save_urlid
366 
367  $current_urls[$curr_urlid] = $save_urls[$save_urlid];
368  $processed_urlids[] = $curr_urlid;
369 
370  }//end for save_urls
371 
372  $delete_urlids = array_diff(array_keys($current_urls), $processed_urlids);
373 
374  foreach ($delete_urlids as $urlid) {
375  // remove all the old URLs
376  $sql = 'DELETE FROM
377  sq_ast_url
378  WHERE
379  urlid = :urlid';
380 
381  try {
382  $query = MatrixDAL::preparePdoQuery($sql);
383  MatrixDAL::bindValueToPdo($query, 'urlid', $urlid);
384  MatrixDAL::execPdoQuery($query);
385  } catch (Exception $e) {
386  throw new Exception('Unable to delete URLs from asset "'.$this->name.'" (#'.$this->id.') due to database error: '.$e->getMessage());
387  }
388 
389  // remove corresponding authentication redirects
390  try {
391  $bind_vars = Array('old_auth_urlid' => $urlid, 'new_auth_urlid' => NULL);
392  MatrixDAL::executeQuery('site', 'changeAuthUrlId', $bind_vars);
393  } catch (Exception $e) {
394  throw new Exception('Unable to remove authentication redirect for auth_urlid: '.$urlid.' due to database error: '.$e->getMessage());
395  }
396  $updated = TRUE;
397  }
398 
399  unset($this->_tmp['urls_info']);
400 
401  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
402  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
403  if ($updated) return 2;
404  return 1;
405 
406  }//end saveWebURLs()
407 
408 
418  public function _morphCleanup($new_type_code)
419  {
420  $current_urls = $this->getSiteURLs();
421  if (!empty($current_urls)) {
422  if (!$this->saveWebURLs(Array())) return FALSE;
423  }
424  return TRUE;
425 
426  }//end _morphCleanup()
427 
428 
436  public function updateLookups()
437  {
438  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
439  $db = MatrixDAL::getDb();
440  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
441 
442  unset($this->_tmp['lookups']);
443  unset($this->_tmp['url']);
444  unset($this->_tmp['href']);
445 
446  if (!isset($this->_tmp['deleting_site'])) {
447  $this->_tmp['deleting_site'] = FALSE;
448  }
449 
450  // get all the lookup information that we have set (i.e. no inherited values), ignoring designs as they are set on every url
451  $lookup_values = $this->getLookupValues(FALSE, $prefix='design::', FALSE);
452  $our_edit_layouts = $this->getLookupValues(FALSE, 'layout::');
453 
454  // remove all normal and override lookup values for this site
455  $sql = 'DELETE FROM
456  sq_ast_lookup_value
457  WHERE
458  url IN
459  (
460  (SELECT
461  url
462  FROM
463  sq_ast_lookup l
464  WHERE
465  assetid = :assetid_1)
466  UNION
467  (SELECT
468  url || \'/\'
469  FROM
470  sq_ast_lookup l
471  WHERE
472  assetid = :assetid_2)
473  ) ';
474 
475  try {
476  $query = MatrixDAL::preparePdoQuery($sql);
477  MatrixDAL::bindValueToPdo($query, 'assetid_1', $this->id);
478  MatrixDAL::bindValueToPdo($query, 'assetid_2', $this->id);
479  MatrixDAL::execPdoQuery($query);
480  } catch (Exception $e) {
481  throw new Exception('Unable to remove existing lookups for Site asset "'.$this->name.'" (#'.$this->id.') due to database error: '.$e->getMessage());
482  }
483 
484  // remove lookup information for this asset
485  $sql = 'DELETE FROM
486  sq_ast_lookup
487  WHERE
488  assetid = :assetid';
489 
490  try {
491  $query = MatrixDAL::preparePdoQuery($sql);
492  MatrixDAL::bindValueToPdo($query, 'assetid', $this->id);
493  MatrixDAL::execPdoQuery($query);
494  } catch (Exception $e) {
495  throw new Exception('Unable to remove existing lookups for Site asset "'.$this->name.'" (#'.$this->id.') due to database error: '.$e->getMessage());
496  }
497 
498  $our_design_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($this->id, SQ_LINK_NOTICE, 'design', FALSE);
499  $design_lookups = Array();
500  foreach ($our_design_links as $link) {
501  if (preg_match('/^design::(system|user)::(.*)$/', $link['value'])) {
502  $design_lookups[$link['value']] = $link['minorid'];
503  }
504  }
505  $override_design_lookups = Array();
506  // look for overrides and overwrite the array in these places
507  foreach ($our_design_links as $link) {
508  if (preg_match('/^override::design::(system|user)::(.*)$/', $link['value'])) {
509  $name = preg_replace('/^override::(.*)$/', '$1', $link['value']);
510  $override_design_lookups[$name] = $link['minorid'];
511  }
512  }
513  unset($our_design_links);
514 
515  $our_layout_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($this->id, SQ_LINK_NOTICE, 'paint_layout_page', FALSE);
516  $paint_layouts = Array();
517  foreach ($our_layout_links as $link) {
518  if (preg_match('/^paint_layout::(system|user)::.*$/', $link['value'])) {
519  $paint_layouts[$link['value']] = Array(
520  'value' => $link['minorid'],
521  );
522  }
523  }
524  // override layouts take priority over normal, inheritable layouts
525  $override_paint_layouts = Array();
526  foreach ($our_layout_links as $link) {
527  if (preg_match('/^override::paint_layout::system::.*$/', $link['value'])) {
528  $name = preg_replace('/^override::(.*)$/', '$1', $link['value']);
529  $override_paint_layouts[$name] = Array(
530  'value' => $link['minorid'],
531  );
532  }
533  }
534  unset($link);
535  unset($our_layout_links);
536 
537  // edit layouts applied to the asset
538  $edit_layouts = Array();
539  foreach($our_edit_layouts as $layout_url => $layouts) {
540  foreach($layouts as $name => $layout_data) {
541  if (!isset($edit_layouts[$name])) {
542  $edit_layouts[$name] = $layout_data['value'];
543  }//end if
544  }//end foreach
545  }//end foreach
546  unset($our_edit_layouts);
547 
548  $urls = $this->getSiteURLs();
549  $current_urls = Array();
550  // if we have urls then do some url inserting
551  for (reset($urls); NULL !== ($urlid = key($urls)); next($urls)) {
552  $current_urls[] = $urls[$urlid]['url'];
553  // merge old paint layout lookup values with design values for inserting into the lookup_value table later
554  // i.e. designs are set on an asset basis, not on a URL basis like paint layouts
555  foreach ($design_lookups as $design_name => $value) {
556  $lookup_values[$urls[$urlid]['url']][$design_name]['value'] = $value;
557  }
558  foreach ($override_design_lookups as $override_design_name => $value) {
559  $lookup_values[$urls[$urlid]['url'].'/'][$override_design_name]['value'] = $value;
560  }
561 
562  if (!isset($lookup_values[$urls[$urlid]['url']])) {
563  // insert an entry so paint layout values are also checked even if we don't have a design set
564  $lookup_values[$urls[$urlid]['url']] = '';
565  }
566  if (!isset($lookup_values[$urls[$urlid]['url'].'/'])) {
567  // insert an entry so override paint layout values are also checked even if we don't have an override design set
568  $lookup_values[$urls[$urlid]['url'].'/'] = '';
569  }
570 
571  // merge in edit layout lookup values
572  foreach($edit_layouts as $layout_name => $value) {
573  if (!isset($lookup_values[$urls[$urlid]['url']][$layout_name])) {
574  $lookup_values[$urls[$urlid]['url']][$layout_name]['value'] = $value;
575  }
576  }
577 
578  $sql = 'INSERT INTO
579  sq_ast_lookup
580  (
581  url,
582  assetid,
583  http,
584  https,
585  root_urlid
586  )
587  VALUES
588  (
589  :url,
590  :assetid,
591  :http,
592  :https,
593  :urlid
594  )';
595 
596  try {
597  $query = MatrixDAL::preparePdoQuery($sql);
598  MatrixDAL::bindValueToPdo($query, 'url', $urls[$urlid]['url']);
599  MatrixDAL::bindValueToPdo($query, 'assetid', $this->id);
600  MatrixDAL::bindValueToPdo($query, 'http', ($this->force_secure === '1') ? '0' : $urls[$urlid]['http']);
601  MatrixDAL::bindValueToPdo($query, 'https', $urls[$urlid]['https']);
602  MatrixDAL::bindValueToPdo($query, 'urlid', $urlid);
603  MatrixDAL::execPdoQuery($query);
604  } catch (Exception $e) {
605  throw new Exception('Unable to insert lookups for Site asset "'.$this->name.'" (#'.$this->id.') due to database error: '.$e->getMessage());
606  }
607  }
608 
609  // If theres no lookup entry, do not insert value for it (See bug #3796)
610  if (!empty($urls)) {
611 
612  // merge in asset based paint layout values if they do not already exist
613  foreach ($lookup_values as $url => $data) {
614 
615  //Bug #5251, filter out lookup values for old urls
616  if (!in_array(rtrim($url, '/'), $current_urls)) {
617  unset($lookup_values[$url]);
618  continue;
619  }
620 
621  if (preg_match('/.+\/$/', $url)) {
622  // override layout
623  foreach ($override_paint_layouts as $name => $value) {
624  if (empty($data)) {
625  $lookup_values[$url][$name] = $value;
626  } else if (!in_array($name, array_keys($data))) {
627  $lookup_values[$url][$name] = $value;
628  }
629  }
630  } else {
631  // normal layout
632  foreach ($paint_layouts as $name => $value) {
633  if (empty($data)) {
634  $lookup_values[$url][$name] = $value;
635  } else if (!in_array($name, array_keys($data))) {
636  $lookup_values[$url][$name] = $value;
637  }
638  }
639  }
640  }
641 
642  // insert lookup values
643  foreach ($lookup_values as $url => $data) {
644  // calculate the depth of the url
645  $exploded_url = explode('/', $url);
646  $depth = count($exploded_url)-1;
647 
648  if (!empty($data)) {
649  foreach ($data as $layout_name => $value) {
650  $sql = 'INSERT INTO
651  sq_ast_lookup_value
652  (
653  url,
654  name,
655  value,
656  depth
657  )
658  VALUES
659  (
660  :url,
661  :name,
662  :value,
663  :depth
664  )';
665 
666  try {
667  $query = MatrixDAL::preparePdoQuery($sql);
668  MatrixDAL::bindValueToPdo($query, 'url', $url);
669  MatrixDAL::bindValueToPdo($query, 'name', $layout_name);
670  MatrixDAL::bindValueToPdo($query, 'value', $value['value']);
671  MatrixDAL::bindValueToPdo($query, 'depth', $depth);
672  MatrixDAL::execPdoQuery($query);
673  } catch (Exception $e) {
674  throw new Exception('Unable to insert lookup values for Site asset "'.$this->name.'" (#'.$this->id.') due to database error: '.$e->getMessage());
675  }
676  }
677  }
678  }
679  } // End if empty urls
680 
681  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
682  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
683  return TRUE;
684 
685  }//end updateLookups()
686 
687 
696  public function describeLink($linkid)
697  {
698  $link = $GLOBALS['SQ_SYSTEM']->am->getLinkById($linkid);
699  switch (strtolower($link['value'])) {
700  case 'index' :
701  return translate('core_site_index_page');
702  break;
703  case 'not_found' :
704  return translate('core_site_not_found_page');
705  break;
706  case 'archive' :
707  return translate('core_site_archive_page');
708  break;
709  default :
710  return parent::describeLink($linkid);
711  break;
712  }
713 
714  }//end describeLink()
715 
716 
724  public function printFrontend()
725  {
726  // check that the user has read access to the site
727  if (!$this->readAccess()) {
728  $GLOBALS['SQ_SYSTEM']->paintLogin(translate('login'), translate('cannot_access_asset', $this->name));
729  return;
730  }
731 
732  $index_page = $this->getSpecialPage('index');
733  if (is_null($index_page)) {
734  if (SQ_IN_LIMBO) {
735  // no index page is set & we are in LIMBO.
736  $asset_url = strip_url($this->getURL(NULL, TRUE), TRUE);
737  $design_name = $this->getCurrentDesignName();
738  $result = $GLOBALS['SQ_SYSTEM']->am->getDesignFromURL($asset_url, $design_name);
739  if (!empty($result)) {
740  // if site has design then print LIMBO
741  $this->paintAsset($this);
742  return;
743  }
744  }
745  trigger_localised_error('CORE0065', E_USER_NOTICE, $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($this->type(), 'name'), $this->name, $this->id);
746  return;
747  }
748 
749  $this->paintAsset($index_page);
750 
751  }//end printFrontend()
752 
753 
760  public function printBody()
761  {
762  $index_page = $this->getSpecialPage('index');
763  if (!is_null($index_page)) $index_page->printBody();
764 
765  return;
766 
767  }//end printBody()
768 
769 
784  public function paintAsset(Asset $asset, $design=NULL, $layout=NULL)
785  {
786  if (is_null($asset)) return;
787 
788  // check that the user has read access to the index page
789  if (!$asset->readAccess()) {
790  $GLOBALS['SQ_SYSTEM']->paintLogin(translate('login'), translate('cannot_access_asset', $this->name));
791  return;
792  }
793 
794  if ($asset->charset) {
795  header("Content-type: text/html; charset=$this->charset");
796  } else {
797  header('Content-type: text/html; charset='.SQ_CONF_DEFAULT_CHARACTER_SET);
798  }
799 
800  if ($asset->languages) {
801  header("Content-language: $this->languages");
802  }
803 
804  // Validate the overriding design, if any
805  if (!is_null($design)) {
806  $design_info = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo($design->id, Array('design'), FALSE);
807  if (empty($design_info)) {
808  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($design);
809  unset($design);
810  $design = NULL;
811  }
812  }
813 
814  $asset_url = strip_url($asset->getURL(NULL, TRUE), TRUE);
815  if (is_null($design)) {
816  $url = strip_url($this->getURL(), TRUE);
817  $design_name = $this->getCurrentDesignName();
818  $result = $GLOBALS['SQ_SYSTEM']->am->getDesignFromURL($asset_url, $design_name);
819 
820  if (empty($result)) {
821  $db = MatrixDAL::getDb();
822  // try and find the default design used by the asset we are painting (i.e. not our default design)
823  $sql = 'SELECT lv.value as designid, a.type_code
824  FROM '.SQ_TABLE_RUNNING_PREFIX.'ast_lookup l
825  INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast_lookup_value lv ON l.url = lv.url
826  INNER JOIN '.SQ_TABLE_RUNNING_PREFIX.'ast a ON lv.value = a.assetid
827  ';
828  $where ='l.assetid = :assetid
829  AND lv.url LIKE :url
830  AND lv.name = :lookup_name';
831  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'lv');
832  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'l');
833  $where = $GLOBALS['SQ_SYSTEM']->constructRollbackWhereClause($where, 'a');
834 
835  $sql .= $where;
836  $sql = db_extras_modify_limit_clause($sql, MatrixDAL::getDbType(), 1);
837 
838  try {
839  $query = MatrixDAL::preparePdoQuery($sql);
840  MatrixDAL::bindValueToPdo($query, 'assetid', $this->id);
841  MatrixDAL::bindValueToPdo($query, 'url', $url.'%');
842  MatrixDAL::bindValueToPdo($query, 'lookup_name', 'design::system::frontend');
843  $result = MatrixDAL::executePdoAssoc($query);
844  if (!empty($result)) $result = $result[0];
845  } catch (Exception $e) {
846  throw new Exception('Unable to get default design for asset: '.$asset->id.' due to database error: '.$e->getMessage());
847  }
848  }
849 
850  // we have found the design to use
851  if ($result) {
852  $design = $GLOBALS['SQ_SYSTEM']->am->getAsset($result['designid'], $result['type_code']);
853  }
854  }//end if
855 
856  global $ASSET_LINEAGE;
857  if (!empty($asset_url)) {
858  $ASSET_LINEAGE = $GLOBALS['SQ_SYSTEM']->am->getLineageFromUrl(NULL, $asset_url);
859  }
860 
861  // ignore current url, use assetid as cache key, to globally cache the 404 page
862  if($this->attr('not_found_page_cache_globally') == TRUE) {
863  $cm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cache_manager');
864  $cm->global_cache = TRUE;
865  }
866 
867  if (!is_null($design)) {
868  if (SQ_IN_LIMBO) {
869  $this->printFrontendAsset($this, $design);
870  } else {
871  // if there is an appopriate paint layout for the index page, tell the system to use it
872  if (!is_null($layout)) {
873  // Validate the overriding paint layout, if any
874  $layout_info = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo($layout->id, Array('paint_layout_page'));
875  if (!empty($layout_info)) {
876  $layout_id = $layout->id;
877  }
878  }
879  if (empty($layout_id)) {
880  $layout_name = $this->getCurrentPaintLayoutName();
881  $layout_id = $GLOBALS['SQ_SYSTEM']->am->getValueFromURL($asset_url, $layout_name);
882  }
883  if ($layout_id) {
884  $GLOBALS['SQ_SYSTEM']->setGlobalDefine('SQ_PAINT_LAYOUT_ID', $layout_id);
885  }
886  $this->printFrontendAsset($asset, $design);
887  }
888  } else {
889  // we can't find a design, oh well let's just print out our body
890  $asset->printBody();
891  }
892 
893  if($this->attr('not_found_page_cache_globally') === TRUE) {
894  $cm->global_cache = FALSE;
895  }
896 
897  }//end paintAsset()
898 
899 
908  public function initLimbo()
909  {
910  if (isset($_GET['limbo_assetid']) && $_GET['limbo_assetid'] == $this->id) {
911  // print this site's limbo instead of the index page
912  parent::initLimbo();
913  } else {
914  $index_page = $this->getSpecialPage('index');
915  if (is_null($index_page)) {
916  parent::initLimbo();
917  return;
918  }
919 
920  $GLOBALS['SQ_SYSTEM']->backend->out->addFormActionGetVar('limbo_assetid', $index_page->id, TRUE);
921  $GLOBALS['SQ_SYSTEM']->backend->out->addFormActionGetVar('assetid', $index_page->id);
922  $GLOBALS['SQ_SYSTEM']->backend->out->addHiddenField('backend_assetid', $index_page->id);
923  $index_page->initLimbo();
924  }
925 
926  }//end initLimbo()
927 
928 
937  public function getSpecialPageLink($page)
938  {
939  switch ($page) {
940  case 'index' :
941  case 'not_found' :
942  case 'not_found_design':
943  case 'not_found_layout':
944  case 'archive' :
945  return $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_NOTICE, '', TRUE, $page);
946  break;
947 
948  default :
949  trigger_localised_error('CORE0075', E_USER_WARNING, $page);
950  return Array();
951  }
952 
953  }//end getSpecialPageLink()
954 
955 
964  public function getSpecialPage($page)
965  {
966  $link = $this->getSpecialPageLink($page);
967  if (empty($link)) {
968  $null = NULL;
969  return $null;
970  }
971 
972  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
973  return $asset;
974 
975  }//end getSpecialPage()
976 
977 
986  public function getSiteNetwork()
987  {
988  $null = NULL;
989 
990  $network_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($this->id, SQ_SC_LINK_SIGNIFICANT, 'site_network', FALSE, 'minor');
991  if (empty($network_links)) return $null;
992 
993  $site_network = $GLOBALS['SQ_SYSTEM']->am->getAsset($network_links[0]['majorid'], $network_links[0]['major_type_code']);
994  return $site_network;
995 
996  }//end getSiteNetwork()
997 
998 
1008  public function getNetworkPrimaryURL()
1009  {
1010  $site_network = $this->getSiteNetwork();
1011  if (is_null($site_network)) return '';
1012  return $site_network->getPrimaryURL();
1013 
1014  }//end getNetworkPrimaryURL()
1015 
1016 
1031  function getKeywordReplacement($keyword)
1032  {
1033  $replacement = NULL;
1034 
1035  // Remove any modifiers from keyword - no need to get context here,
1036  // since the only keywords we are giving (index, not found, archived
1037  // page asset IDs) are saved in links, which aren't contextable
1038  $full_keyword = $keyword;
1039  $keyword = parse_keyword($keyword, $modifiers);
1040 
1041  $keyword_name = substr($keyword, 6);
1042  if (0 === strpos($keyword_name, 'index_id') || 0 === strpos($keyword_name, 'not_found_id') || 0 === strpos($keyword_name, 'archive_id') ) {
1043  $keyword_name = substr($keyword_name, 0, -3);
1044  $asset = $this->getSpecialPage($keyword_name);
1045  if (!is_null($asset)) $replacement = $asset->id;
1046  }
1047 
1048  if ($replacement !== NULL) {
1049  if (count($modifiers) > 0) {
1050  apply_keyword_modifiers($replacement, $modifiers, Array('assetid' => $this->id));
1051  }
1052  } else {
1053  // Use full keyword, so modifiers still get used
1054  $replacement = parent::getKeywordReplacement($full_keyword);
1055  }
1056 
1057  return $replacement;
1058 
1059  }//end getKeywordReplacement()
1060 
1061 
1062 
1077  public function getEffectiveLastUpdatedTime($assetids)
1078  {
1079  $index_link = $this->getSpecialPageLink('index');
1080  if (empty($index_link) === FALSE) {
1081  $assetids[] = $index_link['minorid'];
1082  }
1083 
1084  return parent::getEffectiveLastUpdatedTime($assetids);
1085 
1086  }//end getEffectiveLastUpdatedTime()
1087 
1088 }//end class
1089 
1090 ?>