Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
site_edit_fns.inc
1 <?php
19 require_once SQ_CORE_PACKAGE_PATH.'/folder/folder_edit_fns.inc';
20 
33 {
38  protected $protos = Array('http', 'https');
39 
40 
45  function __construct()
46  {
47  parent::__construct();
48  $this->static_screens['details']['lock_type'] = 'attr_links';
49  unset($this->static_screens['dependants']);
50 
51  }//end constructor
52 
53 
64  public function paintURLs(Site $asset, Backend_Outputter $o, $prefix)
65  {
66  ?>
67  <table border="0" cellspacing="0" cellpadding="3" id="urls_<?php echo $prefix; ?>-table" class="sq-backend-table" style="width: auto">
68  <thead>
69  <tr>
70  <th>URL</th>
71  <?php
72  foreach ($this->protos as $protocol) {
73  ?><th><?php echo strtoupper($protocol) ?></th><?php
74  }
75 
76  $all_contexts = $GLOBALS['SQ_SYSTEM']->getAllContexts();
77  if (count($all_contexts) > 1) {
78  ?><th>Base Context</th><?php
79  }
80  ?>
81  </tr>
82  </thead>
83  <tbody id="urls_<?php echo $prefix; ?>">
84  <?php
85 
86  $urls = $asset->getSiteURLs();
87  $wa = $asset->writeAccess('lookups');
88 
89  $urlids = Array();
90 
91  for (reset($urls); NULL !== ($urlid = key($urls)); next($urls)) {
92  $this->_paintURL($o, $prefix, $urlid, $urls[$urlid], $wa);
93  $urlids[] = $urlid;
94  }//end for
95 
96  $last_id = 0;
97  if (count($urlids) > 0) {
98  $last_id = $urlids[count($urlids)-1];
99  }
100 
101  if ($wa) {
102  // paint a nice blank version
103  $this->_paintURL($o, $prefix, ++$last_id, Array('url' => '', 'protocols' => Array()), TRUE);
104  $urlids[] = $last_id;
105 
106  // let's be a bit nice about this, and when they submit confirm that they know what they are doing
107  $o->addOnSubmit('if (!site_url_check()) return false;');
108 
109  }//end if
110 
111 
112  ?>
113  </tbody>
114  </table>
115  <script language="JavaScript" type="text/javascript">
116 
117  var site_url_protos = new Array("<?php echo implode('","', $this->protos); ?>");
118  var site_url_urlids = new Array("<?php echo implode('","', $urlids); ?>");
119 
120  var optionList = document.getElementById('urls_<?php echo $prefix; ?>');
121  var inputs = optionList.getElementsByTagName('TR');
122 
123  function expandList(el) {
124  var lastId = site_url_urlids[site_url_urlids.length-1];
125  lastId++;
126  var lastInput = inputs[inputs.length-1];
127  var newInput = lastInput.cloneNode(true);
128 
129 
130 
131  // get parent tr
132  var parentTr = el.parentNode.parentNode;
133  if (lastInput != parentTr || (inputs.length > 1 && inputs[inputs.length-2].getElementsByTagName('INPUT')[0].value == '')) {
134  return;
135  }
136 
137  newInput.getElementsByTagName('INPUT')[0].value = '';
138  newInput.getElementsByTagName('INPUT')[0].id = '<?php echo $prefix; ?>' + '_urls['+lastId+'][url]';
139  newInput.getElementsByTagName('INPUT')[0].name = '<?php echo $prefix; ?>' + '_urls['+lastId+'][url]';
140 
141  // protocols
142  var prot = 0;
143  for (var i = 1; i < newInput.getElementsByTagName('INPUT').length; i++) {
144  newInput.getElementsByTagName('INPUT')[i].id = '<?php echo $prefix; ?>' + '_urls['+lastId+'][protocols]['+prot+']';
145  newInput.getElementsByTagName('INPUT')[i].name = '<?php echo $prefix; ?>' + '_urls['+lastId+'][protocols]['+prot+']';
146  prot++;
147  }
148 
149  // Base context, if it's there
150  if (newInput.getElementsByTagName('SELECT').length > 0) {
151  newInput.getElementsByTagName('SELECT')[0].value = 0;
152  newInput.getElementsByTagName('SELECT')[0].id = '<?php echo $prefix; ?>' + '_urls['+lastId+'][base_contextid]';
153  newInput.getElementsByTagName('SELECT')[0].name = '<?php echo $prefix; ?>' + '_urls['+lastId+'][base_contextid]';
154  }
155 
156  site_url_urlids.push(lastId);
157  optionList.appendChild(newInput);
158 
159  }
160 
161  function site_url_check() {
162 
163  for (var j = 0; j < site_url_urlids.length; j++) {
164  var urlid = site_url_urlids[j];
165 
166  // if there isn't any value in the url box, it doesn't matter
167  var url = get_form_element_value("<?php echo $prefix; ?>_urls[" + urlid + "][url]");
168  if (url.length) {
169  var found = false;
170  for (var i = 0; i < site_url_protos.length; i++) {
171  if (document.getElementById("<?php echo $prefix; ?>_urls[" + urlid + "][protocols][" + i + "]").checked) {
172  found = true;
173  break;
174  }
175  }//end if
176 
177  // if nothing is checked, confirm deletion
178  if (!found) {
179  // if they don't want to delete, abort submit
180  if (!confirm(js_translate('must_select_at_least_one_protocol', url))) {
181  return false;
182  }
183  }
184 
185  // remove all the protocols
186  } else {
187  for (var i = 0; i < site_url_protos.length; i++) {
188  var proto = get_form_element("<?php echo $prefix; ?>_urls[" + urlid + "][protocols][" + i + "]");
189  proto.checked = false;
190  }//end if
191 
192  }//end if
193 
194  }//end for
195 
196  return true;
197 
198  }//end site_url_check();
199 
200  </script>
201  <?php
202 
203  return $wa;
204 
205  }//end paintURLs()
206 
207 
220  protected function _paintURL(Backend_Outputter $o, $prefix, $i, Array $url_info, $write_access)
221  {
222  $all_contexts = $GLOBALS['SQ_SYSTEM']->getAllContexts();
223  ?>
224  <tr>
225  <td class="sq-backend-table-cell">
226  <?php
227  if ($write_access) {
228  text_box($prefix.'_urls['.$i.'][url]', $url_info['url'], 40, '', FALSE, 'onFocus="expandList(this);"');
229  } else {
230  echo '<strong>'.$url_info['url'].'</strong>';
231  }
232  ?>
233  </td>
234  <?php
235  for ($k = 0; $k < count($this->protos); $k++) {
236  ?>
237  <td class="sq-backend-table-cell" style="text-align: center">
238  <?php
239  if ($write_access) {
240  check_box($prefix.'_urls['.$i.'][protocols]['.$k.']', $this->protos[$k], !empty($url_info[$this->protos[$k]]));
241  } else {
242  ?>
243  <img src="<?php echo sq_web_path('lib'); ?>/web/images/<?php echo empty($url_info[$this->protos[$k]]) ? 'cross' : 'tick'; ?>.gif" width="15" height="15" />
244  <?php
245  }
246  ?>
247  </td>
248  <?php
249  }//end for
250 
251  if (count($all_contexts) > 1) {
252  ?><td class="sq-backend-table-cell"><?php
253  // If the base context hasn't been saved yet, use the default
254  if (array_key_exists('base_contextid', $url_info) === FALSE) {
255  $url_info['base_contextid'] = 0;
256  }
257 
258  // If the context no longer exists, revert back to default
259  if (array_key_exists($url_info['base_contextid'], $all_contexts) === FALSE) {
260  $url_info['base_contextid'] = 0;
261  }
262 
263  if ($write_access === TRUE) {
264  $options = Array();
265  foreach ($all_contexts as $contextid => $context_data) {
266  $options[$contextid] = $context_data['name'];
267  }
268  combo_box($prefix.'_urls['.$i.'][base_contextid]', $options, FALSE, $url_info['base_contextid']);
269  } else {
270  echo $all_contexts[$url_info['base_contextid']]['name'];
271  }
272  ?></td><?php
273  }//end if multiple contexts exist
274  ?>
275  </tr>
276  <?php
277 
278  }//end _paintURL()
279 
280 
292  public function processURLs(Site $asset, Backend_Outputter $o, $prefix, $updatelookups=TRUE)
293  {
294  if (empty($_POST[$prefix.'_urls'])) return FALSE;
295 
296  $post = $_POST[$prefix.'_urls'];
297 
298  $urls = Array();
299  for (reset($post); NULL !== ($urlid = key($post)); next($post)) {
300 
301  $url = trim($post[$urlid]['url']);
302 
303  // check to see if user has provided 'http://' or 'https://' in the url provided
304  // might have to warn them about the it
305  if(preg_match('/^http(s)?:/', $url)) {
306  trigger_localised_error('CORE0303', E_USER_WARNING, $url);
307  return FALSE;
308  }
309 
310  // if there is a url or some selected protocols, then let's save it
311  if ($url && !empty($post[$urlid]['protocols'])) {
312  $urls[$urlid] = Array(
313  'url' => $post[$urlid]['url'],
314  'base_contextid' => array_get_index($post[$urlid], 'base_contextid', 0),
315  );
316  for ($k = 0; $k < count($this->protos); $k++) {
317  $urls[$urlid][$this->protos[$k]] = (int) in_array($this->protos[$k], $post[$urlid]['protocols']);
318  }
319  }
320 
321  }
322  $run_hipo = FALSE;
323  $old_urls = $asset->getSiteURLs();
324  switch ($asset->saveWebURLs($urls)) {
325  case 0:
326  return FALSE;
327  break;
328  case 2:
329  $run_hipo = TRUE;
330  break;
331  }
332 
333  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
334  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
335  $db = MatrixDAL::getDb();
336 
337  foreach ($urls as $urlid => $url_data) {
338  // Skip the new URL
339  if (!isset($old_urls[$urlid]) || $old_urls[$urlid]==$url_data) {
340  continue;
341  }
342 
343  $run_hipo = TRUE;
344 
345  // update the root url in the asset url table to the new url
346  try {
347  $bind_vars = Array (
348  'url' => strip_url($urls[$urlid]['url']),
349  'urlid' => $urlid,
350  );
351  $result = MatrixDAL::executeQuery('site', 'updateUrl', $bind_vars);
352  } catch (Exception $e) {
353  throw new Exception('Unable to update URL: '.strip_url($urls[$urlid]['url']).' for urlid: '.$urlid.' due to database error: '.$e->getMessage());
354  }
355 
356  // update any urls that use this url in the lookup and lookup value tables
357  foreach (Array('sq_ast_lookup_value', 'sq_ast_lookup') as $tablename) {
358  // Skip if the url was not changed
359  if ($urls[$urlid]['url'] == $old_urls[$urlid]['url']) {
360  continue;
361  }
362  $sql = 'UPDATE
363  '.$tablename.'
364  SET
365  url = :url || SUBSTR(url, :substr_arg)
366  WHERE
367  (url LIKE :old_url_like OR url LIKE :old_url_like_slash)';
368 
369 
370  if ($tablename == 'sq_ast_lookup') {
371  $sql .= ' AND root_urlid = :urlid';
372  } else if ($tablename == 'sq_ast_lookup_value') {
373  $sql .= ' AND url IN (
374  SELECT
375  v.url
376  FROM
377  sq_ast_lookup l
378  INNER JOIN
379  sq_ast_lookup_value v ON ((l.url = v.url) OR (l.url || \'/\' = v.url))
380  WHERE
381  l.root_urlid = :urlid
382  )';
383  }
384  try {
385  $query = MatrixDAL::preparePdoQuery($sql);
386  MatrixDAL::bindValueToPdo($query, 'url', $urls[$urlid]['url']);
387  MatrixDAL::bindValueToPdo($query, 'old_url_like', $old_urls[$urlid]['url'].'%');
388  MatrixDAL::bindValueToPdo($query, 'old_url_like_slash', $old_urls[$urlid]['url'].'%/');
389  MatrixDAL::bindValueToPdo($query, 'substr_arg', strlen($old_urls[$urlid]['url'])+1);
390  MatrixDAL::bindValueToPdo($query, 'urlid', $urlid);
391  $result = MatrixDAL::execPdoQuery($query);
392  } catch (Exception $e) {
393  throw new Exception('Unable to update this old URL: '.$old_urls[$urlid]['url'].' with this new URL: '.$urls[$urlid]['url'].' due to database error: '.$e->getMessage());
394  }
395  }
396  }//end foreach
397 
398  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
399  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
400 
401  flush();
402 
404  if ($run_hipo && $updatelookups) {
405  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
406  $vars = Array('assetids' => Array($asset->id));
407  $hh->queueHipo('hipo_job_update_lookups', $vars);
408  }
410 
411  return TRUE;
412 
413  }//end processURLs()
414 
415 
426  public function paintIndexPage(Site $asset, Backend_Outputter $o, $prefix)
427  {
428  return $this->paintNoticeLinkedAsset($asset, 'index');
429 
430  }//end paintIndexPage()
431 
432 
443  public function processIndexPage(Site $asset, Backend_Outputter $o, $prefix)
444  {
445  return $this->processNoticeLinkedAsset($asset, 'index');
446 
447  }//end processIndexPage()
448 
449 
460  public function paintArchivedPage(Site $asset, Backend_Outputter $o, $prefix)
461  {
462  return $this->paintNoticeLinkedAsset($asset, 'archive');
463 
464  }//end paintIndexPage()
465 
466 
477  public function processArchivedPage(Site $asset, Backend_Outputter $o, $prefix)
478  {
479  return $this->processNoticeLinkedAsset($asset, 'archive');
480 
481  }//end processIndexPage()
482 
483 
494  public function paintForbiddenPage(Site $asset, Backend_Outputter $o, $prefix)
495  {
496  return $this->paintNoticeLinkedAsset($asset, 'forbidden');
497 
498  }//end paintForbiddenPage()
499 
500 
511  public function processForbiddenPage(Site $asset, Backend_Outputter $o, $prefix)
512  {
513  return $this->processNoticeLinkedAsset($asset, 'forbidden');
514 
515  }//end processForbiddenPage()
516 
517 
528  public function paintNotFoundPage(Site $asset, Backend_Outputter $o, $prefix)
529  {
530  return $this->paintNoticeLinkedAsset($asset, 'not_found');
531 
532  }//end paintNotFoundPage()
533 
534 
545  public function processNotFoundPage(Site $asset, Backend_Outputter $o, $prefix)
546  {
547  return $this->processNoticeLinkedAsset($asset, 'not_found');
548 
549  }//end processNotFoundPage()
550 
551 
562  public function paintNotFoundPageDesign(Site $asset, Backend_Outputter $o, $prefix)
563  {
564  return $this->paintNoticeLinkedAsset($asset, 'not_found_design', Array('design' => 'D'));
565 
566  }//end paintNotFoundPageDesign()
567 
568 
579  public function processNotFoundPageDesign(Site $asset, Backend_Outputter $o, $prefix)
580  {
581  return $this->processNoticeLinkedAsset($asset, 'not_found_design');
582 
583  }//end processNotFoundPageDesign()
584 
585 
596  public function paintNotFoundPagePaintLayout(Site $asset, Backend_Outputter $o, $prefix)
597  {
598  return $this->paintNoticeLinkedAsset($asset, 'not_found_layout', Array('paint_layout_page' => 'D'));
599 
600  }//end paintNotFoundPagePaintLayout()
601 
602 
613  public function processNotFoundPagePaintLayout(Site $asset, Backend_Outputter $o, $prefix)
614  {
615  return $this->processNoticeLinkedAsset($asset, 'not_found_layout');
616 
617  }//end processNotFoundPagePaintLayout()
618 
619 
630  public function paintAuthURLs(Site $asset, Backend_Outputter $o, $prefix)
631  {
632  $db = MatrixDAL::getDb();
633  $write_access = $asset->writeAccess('lookups');
634 
635  try {
636  $bind_vars = Array('assetid' => $asset->id);
637  $urls = MatrixDAL::executeAssoc('site', 'getUrlsFromAssetId', $bind_vars);
638  } catch (Exception $e) {
639  throw new Exception('Unable to get URLs for asset: '.$asset->id.' due to database error: '.$e->getMessage());
640  }
641 
642  $combo_box_urls = Array();
643 
644  foreach ($urls as $urlid => $url) {
645  $combo_box_urls[$url['urlid']] = $url['url'];
646  }
647 
648  $combo_box_from = $combo_box_urls;
649 
650  // We will cache the body of the table, and only print the table out
651  // if we have a redirect worth painting
652  $paint_table = FALSE;
653 
654  ob_start();
655 
656  foreach ($urls as $urlid => $url) {
657  if (!empty($url['auth_urlid'])) {
658  $paint_table = TRUE;
659  $auth_urlid = $url['auth_urlid'];
660  unset($combo_box_from[$urlid]);
661  ?>
662  <tr>
663  <td><?php echo $url['url'] ?></td>
664  <td><?php
665  if ($write_access) {
666  combo_box($prefix.'auth_url[change]['.$url['urlid'].']', $combo_box_urls, FALSE, $url['auth_urlid']);
667  } else {
668  for ($i=0; $i<count($urls); $i++) {
669  if ($urls[$i]['urlid'] === $auth_urlid)
670  echo $urls[$i]['url'];
671  }
672  }
673  ?></td>
674  <?php if ($write_access) {
675  ?>
676  <td><?php echo check_box($prefix.'auth_url[delete]['.$url['urlid'].']') ?></td>
677  <?php
678  }
679  ?>
680  </tr>
681 
682  <?php
683  }
684  }
685 
686  $body = ob_get_clean();
687 
688  $o->openSection(translate('core_site_current_redirects'));
689  $o->openField('');
690 
691  if ($paint_table) {
692  ?>
693  <table class="sq-backend-table">
694  <tr>
695  <th><?php echo translate('old_url') ?></th>
696  <th><?php echo translate('new_url') ?></th>
697  <?php if ($write_access) {
698  ?><th>Delete?</th><?php
699  }
700  ?>
701  </tr>
702  <?php
703  echo $body;
704  ?>
705  </table>
706  <?php
707  } else {
708  ?><em>No redirects currently exist</em><?php
709  }
710 
711  $o->closeField();
712  $o->closeSection();
713 
714  if ($write_access) {
715 
716  // Now the "add" section
717  $combo_box_from = Array('' => '-- Select URL --') + $combo_box_from;
718  $combo_box_urls = Array('' => '-- Select URL --') + $combo_box_urls;
719 
720  $o->openSection(translate('core_site_add_redirect'));
721 
722  $o->openField(translate('from'));
723  combo_box($prefix.'auth_url[from]', $combo_box_from);
724  $o->closeField();
725 
726  $o->openField(translate('to'));
727  combo_box($prefix.'auth_url[to]', $combo_box_urls);
728  $o->closeField();
729 
730  $o->closeSection();
731 
732  }
733 
734  return $write_access;
735 
736  }//end paintAuthURLs()
737 
738 
749  public function processAuthURLs(Site $asset, Backend_Outputter $o, $prefix)
750  {
751  if (!$asset->writeAccess('lookups')) return FALSE;
752 
753  $db = MatrixDAL::getDb();
754 
755  try {
756  $bind_vars = Array('assetid' => $asset->id);
757  $urls = MatrixDAL::executeAssoc('site', 'getUrlsFromAssetId', $bind_vars);
758  // transform
759  $transformed_urls = Array();
760  foreach ($urls as $key => $value) {
761  if (isset($value['urlid'])) {
762  $transformed_urls[$value['urlid']] = $value['auth_urlid'];
763  }
764  }
765  $urls = $transformed_urls;
766 
767  } catch (Exception $e) {
768  throw new Exception('Unable to get authentication redirect URLs for asset: '.$asset->id.' due to database error: '.$e->getMessage());
769  }
770  $changed_urlids = Array();
771 
772  $auth_urls = $_REQUEST[$prefix.'auth_url'];
773 
774  // All this includes security checks to make sure the passed request
775  // data are at least well-formed
776  if (!is_array($auth_urls)) return FALSE;
777 
778  if (isset($auth_urls['change'])) {
779  if (!is_array($auth_urls['change'])) return FALSE;
780 
781  foreach ($auth_urls['change'] as $from => $to) {
782  if (!is_numeric($to)) return FALSE;
783  $urls[$from] = (int)$to;
784  $changed_urlids[$from] = TRUE;
785  }
786  }
787 
788  if (isset($auth_urls['delete'])) {
789  if (!is_array($auth_urls['delete'])) return FALSE;
790 
791  foreach ($auth_urls['delete'] as $from => $value) {
792  $urls[$from] = NULL;
793  $changed_urlids[$from] = TRUE;
794  }
795  }
796 
797  if (!empty($auth_urls['from']) && !empty($auth_urls['to'])) {
798  if (!is_numeric($auth_urls['from'])) return FALSE;
799  if (!is_numeric($auth_urls['to'])) return FALSE;
800 
801  $urls[(int)$auth_urls['from']] = (int)$auth_urls['to'];
802  $changed_urlids[(int)$auth_urls['from']] = TRUE;
803  }
804 
805  if ($this->_isCircularReference($urls)) {
806  // Cannot update private URLs, the submitted set-up would cause a
807  // redirect loop
808  trigger_localised_error('CORE0269', E_USER_WARNING);
809  return FALSE;
810  } else {
811  // determine if there are any new or deleted urls, we are only interested in the deleted ones
812  if (isset($_POST[$prefix.'_urls'])) {
813  $processed_urls = $_POST[$prefix.'_urls'];
814  $current_urls = $asset->getSiteURLs();
815  $diff_urls = array_values(array_diff(array_keys($processed_urls), array_keys($current_urls)));
816  }
817 
818  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
819  $db = MatrixDAL::getDb();
820  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
821 
822  // save them
823  foreach (array_keys($changed_urlids) as $urlid) {
824  if (isset($diff_urls) && !in_array($urls[$urlid], $diff_urls)) {
825  try {
826  $bind_vars = Array (
827  'auth_urlid' => $urls[$urlid],
828  'urlid' => $urlid,
829  );
830  $results = MatrixDAL::executeQuery('site', 'updateAuthUrlId', $bind_vars);
831  } catch (Exception $e) {
832  throw new Exception('Unable to update auth_urlid for urlid: '.$urlid.' due to database error: '.$e->getMessage());
833  }
834  }
835  }
836 
837  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
838  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
839  return TRUE;
840  }
841 
842  }//end processAuthURLs()
843 
844 
870  protected function _isCircularReference(Array $urls)
871  {
872  foreach (array_keys($urls) as $from) {
873  $current_from = $from;
874  $seen = Array();
875  $complete = FALSE;
876  $circular = FALSE;
877 
878  while (!$complete && !$circular) {
879  $seen[] = $current_from;
880 
881  // Get the next step in the list
882  $current_from = array_get_index($urls, $current_from, NULL);
883 
884  if (empty($current_from)) $complete = TRUE;
885 
886  // Have we already seen this
887  if (array_search($current_from, $seen) !== FALSE) {
888  $circular = TRUE;
889  }
890 
891  }//end while
892 
893  // We found a circular reference
894  if ($circular) return TRUE;
895 
896  }//end foreach
897 
898  // No circular reference detected
899  return FALSE;
900 
901  }//end _isCircularReference()
902 
903 
904 }//end class
905 
906 ?>