Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
report_links_edit_fns.inc
1 <?php
18 require_once SQ_CORE_PACKAGE_PATH.'/report/report_edit_fns.inc';
19 
32 {
33 
34 
39  function __construct()
40  {
41  parent::__construct();
42  $this->static_screens['details']['force_unlock'] = '0';
43 
44  }//end constructor
45 
46 
58  function generateReport(&$job, &$step_data, $prefix)
59  {
60  require_once SQ_FUDGE_PATH.'/general/text.inc';
61  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
62  $owner = $GLOBALS['SQ_SYSTEM']->am->getAsset($job->_running_vars['assetid'], 'report_links');
63 
64  if (!isset($job->_running_vars['results'])) {
65  $list_content_types = $GLOBALS['SQ_SYSTEM']->am->getChildren($this->getRootAssetid($owner), 'content_type', FALSE);
66  $list_page_redirects = $GLOBALS['SQ_SYSTEM']->am->getChildren($this->getRootAssetid($owner), 'page_redirect', FALSE);
67  $job->_running_vars['todo'] = $list_content_types + $list_page_redirects;
68  $job->_running_vars['done'] = Array();
69  $job->_running_vars['results'] = Array();
70 
71  if (!is_dir($owner->data_path)) {
72  if (!create_directory($owner->data_path)) {
73  trigger_localised_error('CMS0005', E_USER_WARNING);
74  return FALSE;
75  }
76  }
77  $temp_file = fopen($owner->data_path.'/report.tmp', 'w');
78  if ($temp_file === FALSE) {
79  trigger_localised_error('RPRT0000', E_USER_WARNING);
80  return FALSE;
81  }
82  fwrite($temp_file, '<?xml version="1.0" encoding="'.SQ_CONF_DEFAULT_CHARACTER_SET.'"?>'."\n");
83  fwrite($temp_file, "<links>\n");
84  } else {
85  $temp_file = fopen($owner->data_path.'/report.tmp', 'a');
86  if ($temp_file === FALSE) {
87  trigger_localised_error('RPRT0000', E_USER_WARNING);
88  return FALSE;
89  }
90  }
91  if (!empty($job->_running_vars['todo'])) {
92  $array_keys = array_keys($job->_running_vars['todo']);
93  $assetid = array_shift($array_keys);
94  $asset_type = $job->_running_vars['todo'][$assetid][0]['type_code'];
95  unset($job->_running_vars['todo'][$assetid]);
96  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid, $asset_type);
97 
98  if ($asset_type == 'content_type_nest_content') {
99  $step_data['message'] = translate('cms_report_links_skipping_nest_content', $assetid);
100  }
101  // skip thoese with unwanted status
102  else if (isset($asset->status) && !in_array($asset->status,$owner->attr('statuses'))) {
103  $step_data['message'] = translate('cms_report_links_skipping_unwanted_status', $assetid);
104  }
105  else {
106  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid, $asset_type);
107 
108  if (!is_null($asset)) {
109  if (($asset instanceof Page_Redirect)) {
110  // Look for Page_Redirect for links
111  $step_data['message'] = translate('cms_report_links_generating');
112 
113  $content = '';
114  $match = $asset->attr('redirect_url');
115  $confirm_internal = $asset->getRedirectAsset();
116  $validated_results = FALSE;
117 
118  if (!is_null($confirm_internal)) {
119  // If no redirect_url, then an internal link
120  if ($GLOBALS['SQ_SYSTEM']->am->assetExists($confirm_internal->id)) {
121  // Because this is a special way of handling links with page redirect
122  // We need to match the results as if the results have validated
123  // Therefore the $match value is needed for the XML tp parse the correct asset
124  $link_type = 'internal';
125  $validated_results = Array('valid' => '1', 'description' => '');
126  $match = './?a='.$confirm_internal->id;
127  } else {
128  $link_type = 'internal';
129  $validated_results = Array('valid' => '1', 'description' => translate('cms_report_links_asset_not_exist', $confirm_internal->id));
130  $match = './?a='.$confirm_internal->id;
131  }
132  } else {
133  $results = '';
134  preg_match('|^\./\?a=([0-9]+)#?([^$]*)?|',$match, $results);
135 
136  if (!empty($results)) {
137  $link_type = 'internal';
138  $validated_results = $this->validateInternalLink($results);
139  } else {
140  if (strpos(strtolower($match), 'mailto') === 0) {
141  $link_type = 'mailto';
142  $match = preg_replace('/mailto:/i','',$match);
143  list($match) = explode('?',$match);
144  $match = trim($match);
145  $match = ltrim($match, '/');
146  $validated_results = $this->validateEmailLink($match);
147  } else {
148  $link_type = 'external';
149  $validated_results = $this->validateExternalLink($match);
150  }
151  }
152 
153  }
154 
155  if ($validated_results !== FALSE) {
156 
157  $link_info = Array (
158  'type' => $link_type,
159  'url' => $match,
160  );
161  $content = $this->_addReportContent($content,$link_info,$validated_results);
162 
163  if (!empty($content)) {
164  $content = "\t".'<asset assetid="'.$asset->id.'" name="'.htmlSpecialChars($asset->name).'" short_name="'.htmlSpecialChars($asset->short_name).'" type_code="'.$asset->type().'" status="'.$asset->status.'">'."\n".$content."\t".'</asset>'."\n";
165  fwrite($temp_file, $content);
166  }
167  }
168 
169  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($asset);
170  unset($asset);
171  } else {
172  // Finally, scan the HTML for links
173  $step_data['message'] = translate('cms_report_links_generating');
174 
175  $content = '';
176  $wysiwyg_html = $asset->attr('html');
177 
178  $master_matches = Array();
179  preg_match_all('%(href|src)=[\'"]([^\'\s"]*)%', $wysiwyg_html, $master_matches);
180  $matches = $master_matches[2];
181  foreach ($matches as $match) {
182  // skip keywords
183  $keywords = retrieve_keywords_replacements($match);
184  if (count($keywords) == 1 && $match == '%'.$keywords[0].'%') {
185  continue;
186  }
187 
188  if (!$match) continue;
189  $link_valid = '0';
190  $link_description = '';
191  $link_type = '';
192  $results = Array();
193  preg_match('|^\./\?a=([0-9]+)#?([^$]*)?|',$match, $results);
194 
195 
196  $validated_results = FALSE;
197  if (!empty($results)) {
198  $link_type = 'internal';
199  $validated_results = $this->validateInternalLink($results);
200  } else {
201  if (strpos(strtolower($match), 'mailto') === 0) {
202  $link_type = 'mailto';
203  $match = preg_replace('/mailto:/i','',$match);
204  list($match) = explode('?',$match);
205  $match = trim($match);
206  $validated_results = $this->validateEmailLink($match);
207  } else {
208  $link_type = 'external';
209  $validated_results = $this->validateExternalLink($match);
210  }
211  }
212 
213  if ($validated_results === FALSE) continue;
214 
215  $link_info = Array (
216  'type' => $link_type,
217  'url' => $match,
218  );
219  $content = $this->_addReportContent($content,$link_info,$validated_results);
220  }//end foreach
221 
222  if (!empty($content)) {
223  $content = "\t".'<asset assetid="'.$asset->id.'" name="'.htmlSpecialChars($asset->name).'" short_name="'.htmlSpecialChars($asset->short_name).'" type_code="'.$asset->type().'" status="'.$asset->status.'">'."\n".$content."\t".'</asset>'."\n";
224  fwrite($temp_file, $content);
225  }
226 
227  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($asset);
228  unset($asset);
229  }//end else
230  } else {
231  $step_data['message'] = translate('cms_report_links_skipping_asset', $assetid);
232  $job->_addError(translate('cms_report_links_asset_not_exist', $assetid));
233  }
234 
235  }//end else nest content cell
236 
237  // add this assetid to the done array so we dont do it again
238  $job->_running_vars['done'][] = $assetid;
239  }//end if
240 
241  if (empty($job->_running_vars['todo'])) {
242  $step_data['percent_done'] = 100;
243  $step_data['complete'] = TRUE;
244  $job->_running_vars['complete'] = TRUE;
245 
246  $GLOBALS['SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
247  $user = $GLOBALS['SQ_SYSTEM']->am->getAsset($job->_running_vars['userid']);
248  // update the who/when attribute
249  $owner->setAttrValue('generated_date', $job->_running_vars['generated_date']);
250  $owner->setAttrValue('generated_user', $user->name.' (#'.$user->id.')');
251  // reset to empty string, so that the 'Report Broken Link Now' button can be printed/enabled
252  $owner->setAttrValue('report_info', '');
253  $owner->saveAttributes();
254  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
255 
256  // move the temp file to become the real report XML file
257  fwrite($temp_file, '</links>');
258  if (!copy($owner->data_path.'/report.tmp', $owner->data_path.'/report.xml')) {
259  trigger_localised_error('RPRT0001', E_USER_WARNING);
260  return FALSE;
261  }
262  if (!unlink($owner->data_path.'/report.tmp')) {
263  trigger_localised_error('RPRT0002', E_USER_WARNING);
264  }
265  // send broken link notification, if enabled
266  if ($owner->attr('report_broken_links')) {
267  $owner->reportBrokenLink();
268  }
269 
270  } else {
271  $total = count($job->_running_vars['todo']) + count($job->_running_vars['done']);
272  $step_data['percent_done'] = (count($job->_running_vars['done']) / $total) * 100;
273  $step_data['complete'] = FALSE;
274  }
275 
276  fclose($temp_file);
277  return TRUE;
278 
279  }//end generateReport()
280 
281 
292  function _addReportContent($content,$link_info,$results=Array('valid'=>'0','description'=>''))
293  {
294  $content .= "\t\t".'<link type="'.$link_info['type'].'" valid="'.$results['valid'].'">'."\n";
295  $content .= "\t\t\t".'<html><![CDATA['.$link_info['url'].']]></html>'."\n";
296  $content .= "\t\t\t".'<description><![CDATA['.$results['description'].']]></description>'."\n";
297  $content .= "\t\t".'</link>'."\n";
298 
299  return $content;
300 
301  }//end _addReportContent()
302 
303 
318  function validateInternalLink($link)
319  {
320  $asset = NULL;
321  $assetid = $link[1];
322  if ($assetid) {
323  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid, '', TRUE);
324  }
325 
326  if (is_null($asset)) {
327  // the asset was invalid
328  $description = translate('cms_report_links_point_invalid_assetid');
329  $valid = '0';
330  } else if ($GLOBALS['SQ_SYSTEM']->am->assetInTrash($assetid, TRUE)) {
331  // the asset is in the trash
332  $description = translate('cms_report_links_point_to_trash');
333  $valid = '0';
334  } else if (!empty($link[2])) {
335  $contents = Array();
336  $editable_contents = $GLOBALS['SQ_SYSTEM']->am->getEditableContents($assetid);
337  if (is_array($editable_contents)) {
338  $contents = $editable_contents;
339  }
340 
341  $anchorExists = FALSE;
342 
343  // check if we are looking for an interface for this asset
344  if (preg_match('/\/_admin|\/_edit/', $link[2], $matches)) {
345  $anchorExists = TRUE;
346  } else if (preg_match('/^\?(.+=.*)*/', $link[2], $matches)) {
347  $anchorExists = TRUE;
348  } else {
349  // otherwise lets traul the contents for a matching anchor
350 
351  foreach ($contents as $content) {
352  if (preg_match('/<a\s+(name|id)="#?'.$link[2].'"(\s+(name|id)="#?'.$link[2].'")?(\s+href="[^"]+")?>/', $content, $matches)) {
353  $anchorExists = TRUE;
354  break;
355  }
356  }
357  }
358 
359  if (!$anchorExists) {
360  $valid = '0';
361  $description = translate('cms_report_links_anchor_not_exist', $link[2]);
362  } else {
363  $valid = '1';
364  $description = '';
365  }
366  } else {
367  $valid = '1';
368  $description = '';
369  }
370  if (!is_null($asset)) {
371  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($asset);
372  }
373 
374  return Array('valid' => $valid, 'description' => $description);
375 
376  }//end validateInternalLink()
377 
378 
387  function validateExternalLink($url)
388  {
389  // ignore bookmarks
390  if (substr($url, 0, 1) == '#') return FALSE;
391 
392  // ignore potential simple edit query string element
393  // e.g. ./?SQ_ACTION=logout or ?asset_ei_screen=metadata
394  if (strcmp(substr($url, 0, 3), './?') == 0 || substr($url, 0, 1) == '?') {
395  return Array('valid' => 1, 'description' => '');
396  }
397 
398  $validated_results = Array(
399  'valid' => '0',
400  'description' => '',
401  );
402 
403  $url_parts = @parse_url($url);
404 
405  if (empty($url_parts['scheme'])) {
406  $validated_results['description'] = translate('cms_report_links_missing_protocol');
407  $validated_results['valid'] = '0';
408  } else if (empty($url_parts['host'])) {
409  $validated_results['description'] = translate('cms_report_links_missing_hostname');
410  $validated_results['valid'] = '0';
411  } else if ($url_parts['scheme'] != 'http') {
412  $validated_results['description'] = translate('cms_report_links_cannot_test_protocol');
413  $validated_results['valid'] = '1';
414  } else {
415  if (empty($url_parts['path'])) {
416  $url_parts['path'] = '/';
417  }
418  if (empty($url_parts['port'])) {
419  $url_parts['port'] = '80';
420  }
421 
422  $url_path = $url_parts['path'];
423  if (!empty($url_parts['query'])) {
424  $url_path .= '?'.$url_parts['query'];
425  }
426 
427  require_once(SQ_INCLUDE_PATH.'/general_occasional.inc');
428  $socket = openSocketConnection($url_parts, $errno, $errstr, TRUE, 15);
429  if (!SQ_PA_ENABLED || !$socket) {
430  // if proxy authentication is not enabled, or fopen fails, do the old trick
431  $socket = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, 15);
432  if ($socket) {
433  fwrite ($socket, 'HEAD '.$url_path." HTTP/1.0\r\nHost: ".$url_parts['host']."\r\n\r\n");
434  }
435  }
436 
437  if (!$socket) {
438  $validated_results['description'] = translate('cms_report_links_invalid_url');
439  $validated_results['valid'] = '0';
440  } else {
441  stream_set_timeout($socket, 5);
442  $response = fgets($socket);
443  $headers = fgets($socket);
444  $response = trim($response);
445  $headers = trim($headers);
446  $finished = (empty($headers)) ? TRUE : FALSE;
447  while (!$finished) {
448  $next_header = fgets($socket);
449  $next_header = trim($next_header);
450  if (empty($next_header)) {
451  $finished = TRUE;
452  } else {
453  $headers .= $next_header."\r\n";
454  }//end if
455  }//end while
456  $info = stream_get_meta_data($socket);
457 
458  if (preg_match('|405 method not allowed|i', $response) || preg_match('|404 not found|i', $response)) {
459  // Special case need a GET to double check
460  $newsocket = fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, 15);
461  if ($newsocket) {
462  fwrite($newsocket, 'GET '.$url_path." HTTP/1.0\r\nHost: ".$url_parts['host']."\r\n\r\n");
463  }
464 
465  stream_set_timeout($newsocket, 5);
466  $newresponse = fgets($newsocket);
467  $newheaders = fgets($newsocket);
468  $newresponse = trim($newresponse);
469  $newheaders = trim($newheaders);
470  $finished = (empty($newheaders)) ? TRUE : FALSE;
471  while (!$finished) {
472  $next_header = fgets($newsocket);
473  $next_header = trim($next_header);
474  if (empty($next_header)) {
475  $finished = TRUE;
476  } else {
477  $newheaders .= $next_header."\r\n";
478  }//end if
479  }//end while
480  $newinfo = stream_get_meta_data($newsocket);
481 
482  $validated_results = $this->_checkResponse($newheaders, $newresponse, $newinfo);
483 
484  fclose($newsocket);
485  } else {
486  $validated_results = $this->_checkResponse($headers, $response, $info);
487  }//end else
488 
489  fclose($socket);
490  }//end else
491 
492  }//end else
493 
494  return $validated_results;
495 
496  }//end validateExternalLink()
497 
498 
509  function _checkResponse($headers, $response, $info)
510  {
511  if (preg_match('|200 ok|i', $response)) {
512  $description = '';
513  $valid = '1';
514  } else if (preg_match('|302 found|i', $response)) {
515  $description = '';
516  $valid = '1';
517  } else if (preg_match('|304 not modified|i', $response)) {
518  $description = '';
519  $valid = '1';
520  } else if (preg_match('|404 not found|i', $response)) {
521  $description = translate('cms_report_links_404');
522  $valid = '0';
523  } else if (preg_match('|407 proxy authentication required|i', $response)) {
524  $description = translate('cms_report_links_407');
525  $valid = '0';
526  } else if (preg_match('|301 moved|i', $response)) {
527  $valid = '1';
528  preg_match('|Location:\s*(.+)\r|i', $headers, $matches);
529  if (isset($matches[1])) {
530  $description = translate('cms_report_links_301_with_new_link', $matches[1]);
531  } else {
532  $description = translate('cms_report_links_301');
533  }
534  } else if (preg_match('|302 moved|i', $response)) {
535  // should this
536  $valid = '1';
537  preg_match('|Location:\s*(.+)\r|i', $headers, $matches);
538  if (isset($matches[1])) {
539  $description = translate('cms_report_links_302_with_new_link', $matches[1]);
540  } else {
541  $description = translate('cms_report_links_302');
542  }
543  // IIS Specific error codes
544  } else if (preg_match('|202 accepted|i', $response)) {
545  $description = '';
546  $valid = '1';
547  } else if (preg_match('|301 moved permanently|i', $response)) {
548  $valid = '1';
549  preg_match('|Location:\s*(.+)\r|i', $headers, $matches);
550  if (isset($matches[1])) {
551  $description = translate('cms_report_links_301_with_new_link', $matches[1]);
552  } else {
553  $description = translate('cms_report_links_301');
554  }
555  } else if (preg_match('|301 permanent redirect|i', $response)) {
556  $valid = '1';
557  preg_match('|Location:\s*(.+)\r|i', $headers, $matches);
558  if (isset($matches[1])) {
559  $description = translate('cms_report_links_301_with_new_link', $matches[1]);
560  } else {
561  $description = translate('cms_report_links_301');
562  }
563  } else if (preg_match('|302 object moved|i', $response)) {
564  // should this
565  $valid = '1';
566  preg_match('|Location:\s*(.+)\r|i', $headers, $matches);
567  if (isset($matches[1])) {
568  $description = translate('cms_report_links_302_with_new_link', $matches[1]);
569  } else {
570  $description = translate('cms_report_links_302');
571  }
572  } else if (preg_match('|307 temporary redirect|i', $response)) {
573  $valid = '1';
574  preg_match('|Location:\s*(.+)\r|i', $headers, $matches);
575  if (isset($matches[1])) {
576  $description = translate('cms_report_links_307_with_new_link', $matches[1]);
577  } else {
578  $description = translate('cms_report_links_307');
579  }
580  } else if (preg_match('|400 bad request|i', $response)) {
581  $description = translate('cms_report_links_400');
582  $valid = '0';
583  } else if (preg_match('|401 access denied|i', $response)) {
584  $description = translate('cms_report_links_401');
585  $valid = '0';
586  } else if (preg_match('|401 unauthorized|i', $response)) {
587  $description = translate('cms_report_links_401');
588  $valid = '0';
589  } else if (preg_match('|403 forbidden|i', $response)) {
590  $description = translate('cms_report_links_403');
591  $valid = '0';
592  } else if (preg_match('|403 forbidden|i', $response)) {
593  $description = translate('cms_report_links_403');
594  $valid = '0';
595  } else if (preg_match('|404 page not available|i', $response)) {
596  $description = translate('cms_report_links_404');
597  $valid = '0';
598  } else if (preg_match('|406 client browser does not|i', $response)) {
599  $description = translate('cms_report_links_406');
600  $valid = '0';
601  } else if (preg_match('|408 request timed out|i', $response)) {
602  $description = translate('cms_report_links_408');
603  $valid = '0';
604  } else if (preg_match('|412 precondition failed|i', $response)) {
605  $description = translate('cms_report_links_412');
606  $valid = '0';
607  } else if ($info['timed_out']) {
608  $description = translate('cms_report_links_server_timeout');
609  $valid = '0';
610  } else {
611  //remove non ascii chars from response
612  $response = preg_replace('/[^(\x20-\x7F)]*/','',$response);
613  $description = translate('cms_report_links_unknown_response', $response);
614  $valid = '0';
615  }
616 
617  // Format the results
618  $validated_results['valid'] = $valid;
619  $validated_results['description'] = $description;
620 
621  // Return the results
622  return $validated_results;
623 
624  }//end _checkResponse()
625 
626 
635  function validateEmailLink($mailto)
636  {
637  require_once SQ_FUDGE_PATH.'/general/www.inc';
638  if (!valid_email($mailto)) {
639  $description = translate('cms_report_links_invalid_email');
640  $valid = '0';
641  } else {
642  $description = '';
643  $valid = '1';
644  }
645 
646  return Array('valid' => $valid, 'description' => $description);
647 
648  }//end validateEmailLink()
649 
650 
661  function paintReport(&$asset, &$o, $prefix)
662  {
663  $reported_links = $asset->parseReport();
664  $display_options = $asset->attr('display_options');
665 
666  // TODO: this translation has a 'note' prefix that is supposed to look like
667  // a field header... could this be set up as a field?
668  if (SQ_IN_BACKEND || SQ_IN_LIMBO) {
669  echo translate('cms_report_links_current');
670  }
671  $o->closeSection();
672 
673  if ($display_options['internal_section'] == TRUE) {
674  $o->openSection('Internal Links');
675  $o->openField('');
676  if (empty($reported_links['internal'])) {
677  echo 'No internal links were found';
678  } else {
679  ?>
680  <table class="sq-backend-table" style="border: 1px solid #DDDDDD;" border="0">
681  <tr>
682  <th colspan="3" class="sq-backend-table-header" style="width: 226px;"><?php echo translate('found_in') ?></th>
683  <th colspan="3" class="sq-backend-table-header" style="width: 226px;"><?php echo translate('linking_to') ?></th>
684  <th class="sq-backend-table-header"><?php echo translate('comments'); ?></th>
685  </tr>
686  <?php
687  foreach ($reported_links['internal'] as $assetid => $links) {
688  foreach ($links as $link) {
689  $from_info = $this->_getAssetReportInfo($assetid);
690  $from_name = (strlen($from_info['name']) < 40) ? $from_info['name'] : ellipsisize($from_info['name'], 40);
691 
692  $to = NULL;
693  if ($link['data']) {
694  $to = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['data'], '', TRUE);
695  }
696  if (is_null($to)) {
697  $to_type = '';
698  $to_string = translate('unknown_asset_id', $link['data']);
699  $to_bg = '';
700  $to_status = '';
701  $to_name = '';
702  } else {
703  $to_type = $to->type();
704  $to_name = (strlen($to->name) < 40) ? $to->name : ellipsisize($to->name, 40);
705  $to_string = '<span title="'.$to->name.'"> [#'.$to->id.'] '.$to_name.'</span>';
706  $to_bg = get_asset_status_icon($to->status);
707  $to_status = get_status_description($to->status);
708  }
709 
710  ?>
711  <tr>
712  <!-- ASSET STATUS -->
713  <td class="sq-backend-table-cell" style="width: 120px; padding-top: 7px; padding-right: 0px;">
714  <?php echo $from_info['bg']; ?> <?php echo $from_info['status']; ?>
715  </td>
716 
717  <!-- ASSET ICON -->
718  <td class="sq-backend-table-cell" style="width: 16px; padding-right: 0px; padding-left: 0px;">
719  <?php
720  if (!empty($from_info['type'])) {
721  ?>
722  <span title="<?php echo ucwords(str_replace('_', ' ', $from_info['type'])); ?>">
723  <?php echo get_asset_type_icon($from_info['type']); ?>
724  </span>
725  <?php
726  }
727  ?>
728  </td>
729 
730  <!-- ASSET NAME -->
731  <td class="sq-backend-table-cell" style="width: 260px; padding-right: 1px; padding-top:6px; text-align: left;">
732  <a href="<?php echo $from_info['backend_url']; ?>" title="<?php echo translate('edit_this_asset'); ?>">[#<?php echo $from_info['assetid']; ?>] <?php echo $from_name ?></a>
733  </td>
734 
735  <!-- LINKED STATUS -->
736  <td class="sq-backend-table-cell" style="width: 16px; padding-top: 7px; padding-right: 0px;">
737  <?php echo $to_bg; ?><?php echo $to_status; ?>
738  </td>
739 
740  <!-- LINKED ICON -->
741  <td class="sq-backend-table-cell" style="width: 16px; padding-right: 0px; padding-left: 0px;">
742  <?php
743  if (!empty($to_type)) {
744  echo get_asset_type_icon($to_type);
745  }
746  ?>
747  </td>
748 
749  <!-- LINKED NAME -->
750  <td class="sq-backend-table-cell" style="width: 190px; padding-right: 1px; padding-top:6px; text-align: left;">
751  <?php echo $to_string; ?>
752  </td>
753 
754  <!-- COMMENT -->
755  <td class="sq-backend-table-cell">
756  <?php
757  if (!$link['valid']) {
758  echo '<span style="color: #007EFA;"><b>';
759  }
760  echo $link['description'];
761  if (!$link['valid']) echo '</b></span>';
762  ?>
763  </td>
764  </tr>
765  <?php
766  }//end foreach link
767  }//end foreach asset links
768  ?>
769  </table>
770  <?php
771  }//end else
772  $o->closeField();
773  $o->closeSection();
774  }//end if internal section is true
775 
776  if ($display_options['external_section'] == TRUE) {
777  $o->openSection(translate('external_links'));
778  $o->openField('');
779  if (empty($reported_links['external'])) {
780  echo translate('cms_report_links_no_external_links');
781  } else {
782  $ast_info = $GLOBALS['SQ_SYSTEM']->am->getAssetInfo(array_keys($reported_links['external']));
783  ?>
784  <table class="sq-backend-table">
785  <tr>
786  <th colspan="3" class="sq-backend-table-header" style="width: 226px;"><?php echo translate('found_in'); ?></th>
787  <th class="sq-backend-table-header" style="width: 274px;"><?php echo translate('url'); ?></th>
788  <th class="sq-backend-table-header"><?php echo translate('comments'); ?></th>
789  </tr>
790  <?php
791  foreach ($reported_links['external'] as $assetid => $links) {
792  foreach ($links as $link) {
793  $from_info = $this->_getAssetReportInfo($assetid);
794  $from_name = (strlen($from_info['name']) < 40) ? $from_info['name'] : ellipsisize($from_info['name'], 40);
795 
796  $name = (strlen($link['data']) < 50) ? $link['data'] : ellipsisize($link['data'], 50);
797  $to_string = '<a href="'.$link['data'].'" target="_blank" title="'.$link['data'].'">'.$name.'</a>';
798  ?>
799  <tr>
800  <!-- ASSET STATUS -->
801  <td class="sq-backend-table-cell" style="width: 120px; padding-top: 7px; padding-right: 0px;">
802  <?php echo $from_info['bg']; ?> <?php echo $from_info['status']; ?>
803  </td>
804 
805  <!-- ASSET ICON -->
806  <td class="sq-backend-table-cell" style="width: 16px; padding-right: 0px; padding-left: 0px;">
807  <?php
808  if (!empty($from_info['type'])) {
809  ?>
810  <span title="<?php echo ucwords(str_replace('_', ' ', $from_info['type'])); ?>">
811  <?php echo get_asset_type_icon($from_info['type']); ?>
812  </span>
813  <?php
814  }
815  ?>
816  </td>
817 
818  <!-- ASSET NAME -->
819  <td class="sq-backend-table-cell" style="width: 190px; padding-right: 1px; padding-top:6px; text-align: left;">
820  <a href="<?php echo $from_info['backend_url']; ?>" title="<?php echo translate('edit_this_asset') ?>">[#<?php echo (int) $from_info['assetid']; ?>] <?php echo $from_name; ?></a>
821  </td>
822 
823  <!-- URL -->
824  <td class="sq-backend-table-cell" style="width: 226px; padding-right: 1px; padding-top:6px; text-align:left;">
825  <?php echo $to_string; ?>
826  </td>
827 
828  <!-- COMMENTs -->
829  <td class="sq-backend-table-cell">
830  <?php
831  if (!$link['valid']) {
832  echo '<span style="color: #007EFA;"><b>';
833  }
834  echo $link['description'];
835  if (!$link['valid']) echo '</b></span>';
836  ?>
837  </td>
838  </tr>
839  <?php
840  }//end foreach link
841  }//end foreach asset links
842  ?>
843  </table>
844  <?php
845  }//end else
846  $o->closeField();
847  $o->closeSection();
848  }//end if external section is true
849 
850  if ($display_options['email_section'] == TRUE) {
851  $o->openSection(translate('cms_report_links_email_links'));
852  $o->openField('');
853  if (empty($reported_links['mailto'])) {
854  echo translate('cms_report_links_no_email_links');
855  } else {
856  ?>
857  <table class="sq-backend-table">
858  <tr>
859  <th colspan="3" class="sq-backend-table-header" style="width: 226px;"><?php echo translate('found_in'); ?></th>
860  <th class="sq-backend-table-header" style="width: 274px;"><?php echo translate('email'); ?></th>
861  <th class="sq-backend-table-header"><?php echo translate('comments'); ?></th>
862  </tr>
863  <?php
864  foreach ($reported_links['mailto'] as $assetid => $links) {
865  foreach ($links as $link) {
866  $from_info = $this->_getAssetReportInfo($assetid);
867  $to_string = $link['data'];
868  $name = (strlen($from_info['name']) < 40) ? $from_info['name'] : ellipsisize($from_info['name'], 40);
869  ?>
870  <tr>
871 
872  <!-- ASSET STATUS -->
873  <td class="sq-backend-table-cell" style="width: 120px; padding-top: 7px; padding-right: 0px;">
874  <?php echo $from_info['bg']; ?> <?php echo $from_info['status']; ?>
875  </td>
876 
877  <!-- ASSET ICON -->
878  <td class="sq-backend-table-cell" style="width: 16px; padding-right: 0px; padding-left: 0px;">
879  <?php
880  if (!empty($from_info['type'])) {
881  ?>
882  <span title="<?php echo ucwords(str_replace('_', ' ', $from_info['type'])); ?>">
883  <?php echo get_asset_type_icon($from_info['type']); ?>
884  </span>
885  <?php
886  }
887  ?>
888  </td>
889 
890  <!-- ASSET NAME -->
891  <td class="sq-backend-table-cell" style="width: 190px; padding-right: 1px; padding-top:6px; text-align: left;">
892  <a href="<?php echo $from_info['backend_url']; ?>" title="<?php echo translate('edit_this_asset'); ?>">[#<?php echo (int) $from_info['assetid']; ?>] <?php echo $name; ?></a>
893  </td>
894 
895  <!-- ADDRESS -->
896  <td class="sq-backend-table-cell" style="width: 226px; padding-right: 1px; padding-top:6px;">
897  <?php echo $to_string; ?>
898  </td>
899 
900  <!-- COMMENTS -->
901  <td class="sq-backend-table-cell">
902  <?php
903  if (!$link['valid']) {
904  echo '<span style="color: #007EFA;"><b>';
905  }
906  echo $link['description'];
907  if (!$link['valid']) echo '</b></span>';
908  ?>
909  </td>
910  </tr>
911  <?php
912  }//end foreach link
913  }//end foreach asset links
914  ?>
915  </table>
916  <?php
917  }//end else
918  $o->closeField();
919  $o->closeSection();
920  }//end if email_section is true
921 
922  }//end paintReport()
923 
924 
934  function _getAssetReportInfo($assetid)
935  {
936  $asset = NULL;
937  if ($assetid) {
938  $asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($assetid, '', TRUE);
939  }
940  if (is_null($asset)) {
941  $asset_type = '';
942  $asset_name = 'Unknown asset #'.$assetid;
943  $asset_short_name = 'Unknown asset #'.$assetid;
944  $asset_string = 'Unknown asset #'.$assetid;
945  $asset_bg = 'FFFFFF';
946  $asset_status = '';
947  $asset_status_code = 0;
948  $asset_url = '';
949  $asset_preview_url = '';
950  } else {
951  $dependants = $GLOBALS['SQ_SYSTEM']->am->getDependantParents($asset->id);
952  // It faults here if there is only one dependant
953  $first_dep = array_pop($dependants);
954  if (!empty($first_dep)) {
955  $parent = $GLOBALS['SQ_SYSTEM']->am->getAsset($first_dep);
956  } else {
957  $parent = NULL;
958  }
959  if (!is_null($parent)) {
960  $asset_type = $parent->type();
961  $asset_name = $parent->name;
962  $asset_short_name = $parent->short_name;
963  $asset_bg = get_asset_status_icon($parent->status);
964  $asset_status = get_status_description($parent->status);
965  $asset_status_code = $parent->status;
966  $assetid = $parent->id;
967  $asset_url = $parent->getBackendHref();
968  $asset_preview_url = $parent->getURL();
969  } else {
970  $asset_type = $asset->type();
971  $asset_name = $asset->name;
972  $asset_short_name = $asset->short_name;
973  $asset_bg = get_asset_status_icon($asset->status);
974  $asset_status = get_status_description($asset->status);
975  $asset_status_code = $asset->status;
976  $asset_url = $asset->getBackendHref();
977  $asset_preview_url = $asset->getURL();
978  }
979 
980  include_once SQ_FUDGE_PATH.'/general/general.inc';
981  $asset_string = ellipsisize($asset_name, 40);
982 
983  $asset_string = '
984  <a href="'.$asset_preview_url.'" target="_blank" title="'.$asset_name.'">'.$asset_string.'</a>';
985  }//end else
986 
987  return Array(
988  'assetid' => $assetid,
989  'name' => $asset_name,
990  'short_name' => $asset_short_name,
991  'type' => $asset_type,
992  'type_code' => $asset_type,
993  'string' => $asset_string,
994  'bg' => $asset_bg,
995  'status' => $asset_status,
996  'status_code' => $asset_status_code,
997  'backend_url' => $asset_url,
998  );
999 
1000  }//end _getAssetReportInfo()
1001 
1002 
1013  function paintDisplayOptions(&$asset, &$o, $prefix)
1014  {
1015  $write_access = $asset->writeAccess('attributes');
1016  $tick = sq_web_path('lib').'/web/images/tick.gif';
1017  $cross = sq_web_path('lib').'/web/images/cross.gif';
1018  $current_settings = $asset->attr('display_options');
1019 
1020  ?>
1021  <script type="text/javascript">
1022  var prefix = '<?php echo $prefix; ?>';
1023 
1024  // Disables a sections child options, if the top option is deselected
1025  function change_section(section, obj) {
1026  var start = prefix + '_' + section + '_';
1027  document.getElementById(start + 'working').disabled = obj.checked ? false : true;
1028  document.getElementById(start + 'broken').disabled = obj.checked ? false : true;
1029  }
1030  </script>
1031 
1032  <table class="sq-backend-table" style="width: 300px;">
1033  <tr>
1034  <th class="sq-backend-table-header" colspan="2"><?php echo translate('cms_report_links_internal_links'); ?></th>
1035  </tr>
1036  <tr>
1037  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_section', 'Internal'); ?></td>
1038  <td class="sq-backend-table-cell">
1039  <?php
1040  $value = $current_settings['internal_section'];
1041  if ($write_access) {
1042  check_box($prefix.'_internal_section', '1', $value, 'change_section("internal", this)');
1043  } else {
1044  ?>
1045  <img src="<?php echo $value ? $tick : $cross; ?>" />
1046  <?php
1047  }
1048  ?>
1049  </td>
1050  </tr>
1051  <tr>
1052  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_broken'); ?></td>
1053  <td class="sq-backend-table-cell">
1054  <?php
1055  $value = $current_settings['internal_broken'];
1056  if ($write_access) {
1057  check_box($prefix.'_internal_broken', '1', $value, '', $current_settings['internal_section'] == FALSE ? 'disabled' : '');
1058  } else {
1059  ?>
1060  <img src="<?php echo $value ? $tick : $cross; ?>" />
1061  <?php
1062  }
1063  ?>
1064  </td>
1065  </tr>
1066  <tr>
1067  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_working'); ?></td>
1068  <td class="sq-backend-table-cell">
1069  <?php
1070  $value = $current_settings['internal_working'];
1071  if ($write_access) {
1072  check_box($prefix.'_internal_working', '1', $value, '', $current_settings['internal_section'] == FALSE ? 'disabled' : '');
1073  } else {
1074  ?>
1075  <img src="<?php echo $value ? $tick : $cross; ?>" />
1076  <?php
1077  }
1078  ?>
1079  </td>
1080  </tr>
1081  <tr>
1082  <th class="sq-backend-table-header" colspan="2"><?php echo translate('cms_report_links_external_links'); ?></th>
1083  </tr>
1084  <tr>
1085  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_section', 'External'); ?></td>
1086  <td class="sq-backend-table-cell">
1087  <?php
1088  $value = $current_settings['external_section'];
1089  if ($write_access) {
1090  check_box($prefix.'_external_section', '1', $value, 'change_section("external", this)');
1091  } else {
1092  ?>
1093  <img src="<?php echo $value ? $tick : $cross; ?>" />
1094  <?php
1095  }
1096  ?>
1097  </td>
1098  </tr>
1099  <tr>
1100  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_broken'); ?></td>
1101  <td class="sq-backend-table-cell">
1102  <?php
1103  $value = $current_settings['external_broken'];
1104  if ($write_access) {
1105  check_box($prefix.'_external_broken', '1', $value, '', $current_settings['external_section'] == FALSE ? 'disabled' : '');
1106  } else {
1107  ?>
1108  <img src="<?php echo $value ? $tick : $cross; ?>" />
1109  <?php
1110  }
1111  ?>
1112  </td>
1113  </tr>
1114  <tr>
1115  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_working'); ?></td>
1116  <td class="sq-backend-table-cell">
1117  <?php
1118  $value = $current_settings['external_working'];
1119  if ($write_access) {
1120  check_box($prefix.'_external_working', '1', $value, '', $current_settings['external_section'] == FALSE ? 'disabled' : '');
1121  } else {
1122  ?>
1123  <img src="<?php echo $value ? $tick : $cross; ?>" />
1124  <?php
1125  }
1126  ?>
1127  </td>
1128  </tr>
1129  <tr>
1130  <th class="sq-backend-table-header" colspan="2"><?php echo translate('cms_report_links_email_links'); ?></th>
1131  </tr>
1132  <tr>
1133  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_section', 'Email'); ?></td>
1134  <td class="sq-backend-table-cell">
1135  <?php
1136  $value = $current_settings['email_section'];
1137  if ($write_access) {
1138  check_box($prefix.'_email_section', '1', $value, 'change_section("email", this)');
1139  } else {
1140  ?>
1141  <img src="<?php echo $value ? $tick : $cross; ?>" />
1142  <?php
1143  }
1144  ?>
1145  </td>
1146  </tr>
1147  <tr>
1148  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_broken'); ?></td>
1149  <td class="sq-backend-table-cell">
1150  <?php
1151  $value = $current_settings['email_broken'];
1152  if ($write_access) {
1153  check_box($prefix.'_email_broken', '1', $value, '', $current_settings['email_section'] == FALSE ? 'disabled' : '');
1154  } else {
1155  ?>
1156  <img src="<?php echo $value ? $tick : $cross; ?>" />
1157  <?php
1158  }
1159  ?>
1160  </td>
1161  </tr>
1162  <tr>
1163  <td class="sq-backend-table-cell" style="padding-left: 30px;"><?php echo translate('cms_report_links_display_working'); ?></td>
1164  <td class="sq-backend-table-cell">
1165  <?php
1166  $value = $current_settings['email_working'];
1167  if ($write_access) {
1168  check_box($prefix.'_email_working', '1', $value, '', $current_settings['email_section'] == FALSE ? 'disabled' : '');
1169  } else {
1170  ?>
1171  <img src="<?php echo $value ? $tick : $cross; ?>" />
1172  <?php
1173  }
1174  ?>
1175  </td>
1176  </tr>
1177 
1178  </table>
1179 
1180  <?php
1181  return $write_access;
1182 
1183  }//end paintDisplayOptions()
1184 
1185 
1196  function processDisplayOptions(&$asset, &$o, $prefix)
1197  {
1198  $write_access = $asset->writeAccess('attributes');
1199  if (!$write_access) return $write_access;
1200  $display_options = $asset->attr('display_options');
1201 
1202  // These conditions below ensure that the elements retain their values if they are disabled
1203  $display_options['internal_section'] = isset($_POST[$prefix.'_internal_section']);
1204  if ($display_options['internal_section']) {
1205  $display_options['internal_broken'] = isset($_POST[$prefix.'_internal_broken']);
1206  $display_options['internal_working'] = isset($_POST[$prefix.'_internal_working']);
1207  }
1208 
1209  $display_options['external_section'] = isset($_POST[$prefix.'_external_section']);
1210  if ($display_options['external_section']) {
1211  $display_options['external_broken'] = isset($_POST[$prefix.'_external_broken']);
1212  $display_options['external_working'] = isset($_POST[$prefix.'_external_working']);
1213  }
1214 
1215  $display_options['email_section'] = isset($_POST[$prefix.'_email_section']);
1216  if ($display_options['email_section']) {
1217  $display_options['email_broken'] = isset($_POST[$prefix.'_email_broken']);
1218  $display_options['email_working'] = isset($_POST[$prefix.'_email_working']);
1219  }
1220 
1221  $asset->setAttrValue('display_options', $display_options);
1222  return TRUE;
1223 
1224  }//end processDisplayOptions()
1225 
1236  function paintStatusSelection(&$asset, &$o, $prefix)
1237  {
1238  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
1239  $write_access = $asset->writeAccess('attributes');
1240 
1241  $current = $asset->attr('statuses');
1242 
1243  if ($write_access) {
1244  require_once SQ_LIB_PATH.'/html_form/html_form.inc';
1245  $statuses = get_constant_values('SQ_STATUS');
1246 
1247  $options = Array();
1248  foreach ($statuses as $constant => $value) {
1249  $options[$value] = get_status_description($value);
1250  }
1251 
1252  combo_box($prefix.'_statuses', $options, TRUE, $current);
1253  } else {
1254  if (empty($current)) {
1255  echo translate('cms_report_links_no_status_selected');
1256  } else {
1257  ?><ul style="margin: 1px 15px;"><?php
1258  foreach ($current as $status) {
1259  echo '<li>';
1260  echo get_asset_status_icon($status);
1261  echo get_status_description($status);
1262  echo '</li>';
1263  }
1264  ?></ul><?php
1265  }
1266  }
1267  return $write_access;
1268  }//end paintStatusSelection()
1269 
1270 
1281  function processStatusSelection(&$asset, &$o, $prefix)
1282  {
1283  // need to have write access to make any changes
1284  if (!$asset->writeAccess('attributes')) return FALSE;
1285 
1286  $statuses = Array();
1287  if (isset($_POST[$prefix.'_statuses'])) {
1288  foreach ($_POST[$prefix.'_statuses'] as $status) {
1289  $statuses[] = $status;
1290  }
1291  $statuses = array_unique($statuses);
1292  }
1293 
1294  return $asset->setAttrValue('statuses', $statuses);
1295  }//end processStatusSelection()
1296 
1307  function paintExport(&$asset, &$o, $prefix)
1308  {
1309  if (!$asset->writeAccess('attributes')) return FALSE;
1310 
1311  echo hidden_field($prefix.'_export_switch', '0');
1312 
1313  $enabled = FALSE;
1314  $report_path = $asset->data_path.'/report.xml';
1315  if (file_exists($report_path)) $enabled = TRUE;
1316  $extras = '';
1317 
1318  // we're going to disable the button if no report is available
1319  if (!$enabled) $extras = 'disabled="disabled"';
1320 
1321  echo normal_button($prefix.'_export', translate('download_file'), 'this.form.'.$prefix.'_export_switch.value = 1; this.form.submit(); SQ_FORM_SUBMITTED = false; this.form.'.$prefix.'_export_switch.value = 0; return true;', $extras);
1322 
1323  return TRUE;
1324 
1325  }//end paintExport()
1326 
1327 
1340  function processExport(&$asset, &$o, $prefix)
1341  {
1342  if (!$_POST[$prefix.'_export_switch']) return TRUE;
1343  if (headers_sent()) {
1344  trigger_localised_error('CORE0273', E_USER_WARNING);
1345  } else {
1346  require_once SQ_FUDGE_PATH.'/csv/csv.inc';
1347  $csv = new CSV();
1348  $csv->setFilename(str_replace(' ', '_', $asset->name).'_report.csv');
1349  $csv->setDeliminator(',');
1350 
1351  $am = $GLOBALS['SQ_SYSTEM']->am;
1352 
1353  $logs = Array();
1354 
1355  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
1356  $report_path = $asset->data_path.'/report.xml';
1357 
1358  if (!is_file($report_path)) {
1359  echo 'This report has not been generated';
1360  return;
1361  }
1362 
1363  try {
1364  $root = new SimpleXMLElement($report_path, LIBXML_NOCDATA, TRUE);
1365  } catch (Exception $e) {
1366  throw new Exception('Unable to parse report file "'.$report_path.'": '.$e->getMessage());
1367  return;
1368  }
1369 
1370  $headers = Array();
1371  $empty_headers = TRUE;
1372  $top_headers = TRUE;
1373  $display_options = $asset->attr('display_options');
1374 
1375  foreach ($root->asset as $asset_node) {
1376  $persistent_values = Array();
1377  $parent_ast_info = $this->_getAssetReportInfo((int) $asset_node->attributes()->assetid);
1378  // Have to initialise the headers
1379  $attribute_list = Array('assetid', 'name', 'short_name', 'type_code', 'status');
1380  if ($top_headers) {
1381  $headers = $attribute_list;
1382  }
1383 
1384  foreach ($attribute_list as $attr) {
1385  // the xml data might not be the data we want to export
1386  if (isset($parent_ast_info[$attr])) {
1387  $value = array_get_index($parent_ast_info, $attr);
1388  if ($attr == 'status') {
1389  // use the numerical representation of assets status
1390  $value = array_get_index($parent_ast_info, 'status_code');
1391  }
1392  }
1393  // Need to setup the persistent values for each of the nodes (like source asset, type etc)
1394  $persistent_values[] = $value;
1395  }
1396  $top_headers = FALSE;
1397 
1398  foreach ($asset_node->link as $link) {
1399  $valid = (int) $link->attributes()->valid;
1400  $type = (string) $link->attributes()->type;
1401  $html = (string) $link->html;
1402  $description = (string) $link->description;
1403 
1404  $display_link = TRUE;
1405  switch ($type) {
1406  case 'internal':
1407  if (!$display_options['internal_section']) {
1408  $display_link = FALSE;
1409  } else {
1410  if ($valid) {
1411  if (!$display_options['internal_working']) {
1412  $display_link = FALSE;
1413  }
1414  } else {
1415  if (!$display_options['internal_broken']) {
1416  $display_link = FALSE;
1417  }
1418  }
1419  }
1420  break;
1421  case 'external':
1422  if (!$display_options['external_section']) {
1423  $display_link = FALSE;
1424  } else {
1425  if ($valid) {
1426  if (!$display_options['external_working']) {
1427  $display_link = FALSE;
1428  }
1429  } else {
1430  if (!$display_options['external_broken']) {
1431  $display_link = FALSE;
1432  }
1433  }
1434  }
1435  break;
1436  case 'mailto':
1437  if (!$display_options['email_section']) {
1438  $display_link = FALSE;
1439  } else {
1440  if ($valid) {
1441  if (!$display_options['email_working']) {
1442  $display_link = FALSE;
1443  }
1444  } else {
1445  if (!$display_options['email_broken']) {
1446  $display_link = FALSE;
1447  }
1448  }
1449  }
1450  break;
1451  default:
1452  break;
1453  }//end switch
1454 
1455  if ($display_link) {
1456  $row = $persistent_values;
1457  if ($empty_headers) $headers[] = 'type';
1458  $row[] = $type;
1459  if ($empty_headers) $headers[] = 'valid';
1460  $row[] = $valid;
1461 
1462  if ($empty_headers) $headers[] = 'html';
1463  $row[] = $html;
1464  if ($empty_headers) $headers[] = 'description';
1465  $row[] = $description;
1466 
1467  $logs[] = $row;
1468  $empty_headers = FALSE;
1469  }
1470  }
1471  }//end foreach
1472 
1473  foreach ($headers as $id => $value) {
1474  $headers[$id] = ucwords(str_replace('_', ' ', $value));
1475  }
1476 
1477  if (!empty($logs)) $csv->setFieldHeaders($headers);
1478 
1479  $csv->setValues($logs);
1480 
1481  // export with keyed fields
1482  $csv->export(TRUE);
1483  exit(0);
1484  }//end else
1485 
1486  return TRUE;
1487 
1488  }//end processExport()
1489 
1490 
1501  function paintFutureRegenerate(&$asset, &$o, $prefix)
1502  {
1503  $cron_mgr = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cron_manager');
1504  $GLOBALS['SQ_SYSTEM']->am->includeAsset('cron_job_regenerate_report');
1505  $rl_jobs = $cron_mgr->getJobs('cron_job_regenerate_report');
1506  $job_count = count($rl_jobs);
1507  for ($k = 0; $k < $job_count; $k++) {
1508  // only include jobs for this link report asset
1509  if ($rl_jobs[$k]->attr('asset') != $asset->id) {
1510  unset($rl_jobs[$k]);
1511  }
1512  }
1513  if (!empty($rl_jobs)) {
1514 
1515  $o->openField(translate('cms_report_links_future_regen_section'), 'new_line');
1516 
1517  ?>
1518  <table class="sq-backend-table">
1519  <tr>
1520  <td class="sq-backend-table-header"><?php echo translate('when'); ?></td>
1521  <td class="sq-backend-table-header"><?php echo translate('status'); ?></td>
1522  <td class="sq-backend-table-header"><?php echo translate('run_as'); ?></td>
1523  <td align="center" class="sq-backend-table-header" style="text-align: center;"><?php
1524  if ($asset->writeAccess('attributes')) {
1525  echo translate('delete_question');
1526  }
1527  ?></td>
1528  </tr>
1529  <?php
1530  foreach ($rl_jobs as $rl_job) {
1531  ?>
1532  <tr>
1533  <td class="sq-backend-table-cell">
1534  <?php echo translate('cms_report_links_future_regen_cron_info', $rl_job->id, $rl_job->readableWhen()); ?>
1535  </td>
1536  <td class="sq-backend-table-cell">
1537  <?php
1538  if ($rl_job->attr('long') && $rl_job->attr('running')) {
1539  echo translate('cms_report_links_future_regen_running');
1540  }
1541  ?>
1542  </td>
1543  <td class="sq-backend-table-cell">
1544  <?php
1545  $user = $rl_job->getRunningUser();
1546  echo get_asset_tag_line($user->id);
1547  unset($user);
1548  ?>
1549  </td>
1550  <td align="center" class="sq-backend-table-cell">
1551  <?php
1552  if ($rl_job->canDelete() && $asset->writeAccess('attributes')) {
1553  check_box($prefix.'_remove_rl[]', $rl_job->id);
1554  } else {
1555  echo '&nbsp;';
1556  }
1557  ?>
1558  </td>
1559  </tr>
1560  <?php
1561  }//end foreach
1562  ?>
1563  </table>
1564  <?php
1565 
1566  }//end if
1567 
1568  require_once SQ_FUDGE_PATH.'/general/datetime.inc';
1569  $cron_job = new Cron_Job_Regenerate_Report();
1570  $edit_fns = $cron_job->getEditFns();
1571 
1572 
1573  $o->openField(translate('cms_report_links_future_regen_field'), 'new_line');
1574  if ($asset->writeAccess('attributes')) {
1575  $cron_epoc = (int)$cron_mgr->attr('epoch');
1576  $cron_refresh = (int)$cron_mgr->attr('refresh_time');
1577  if ($cron_epoc > 0 && $cron_refresh > 0) {
1578  $edit_fns->paintInLineBackend($cron_job, $o, $prefix.'_new_rl');
1579  $o->note(translate('cron_manager_next_run', $cron_mgr->readableRefreshTime(), readable_datetime($cron_mgr->timeOfNextRun())));
1580  } else {
1581  echo translate('cron_manager_not_configured_regen');
1582  }
1583  } else {
1584  echo translate('cms_report_links_future_regen_lock');
1585  }
1586  $o->closeField();
1587 
1588  return TRUE;
1589 
1590  }//end paintFutureRegenerate()
1591 
1592 
1603  function processFutureRegenerate(&$asset, &$o, $prefix)
1604  {
1605  $cron_mgr = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cron_manager');
1606  $GLOBALS['SQ_SYSTEM']->am->includeAsset('cron_job_regenerate_report');
1607 
1608  if (!is_null($cron_mgr)) {
1609  $rl_jobs = $cron_mgr->getJobs('cron_job_regenerate_report');
1610  $job_count = count($rl_jobs);
1611  for ($k = 0; $k < $job_count; $k++) {
1612  // only include jobs for this link report asset
1613  if ($rl_jobs[$k]->attr('asset') != $asset->id) {
1614  unset($rl_jobs[$k]);
1615  }
1616  }
1617  if (!empty($_POST[$prefix.'_remove_rl'])) {
1618  if ($GLOBALS['SQ_SYSTEM']->am->acquireLock($cron_mgr->id, 'links')) {
1619  foreach ($rl_jobs as $rl_job) {
1620  if (in_array($rl_job->id, $_POST[$prefix.'_remove_rl'])) {
1621  if ($cron_mgr->removeJob($rl_job)) {
1622  $is_updated = TRUE;
1623  }
1624  }// end if
1625  }// end for
1626 
1627  $GLOBALS['SQ_SYSTEM']->am->releaseLock($cron_mgr->id, 'links');
1628 
1629  } else {
1630  trigger_localised_error('SYS0232', E_USER_NOTICE);
1631  }// end if
1632  }// end if
1633 
1634  $cron_epoc = (int)$cron_mgr->attr('epoch');
1635  $cron_refresh = (int)$cron_mgr->attr('refresh_time');
1636  if ($cron_epoc > 0 && $cron_refresh > 0) {
1637  if ($asset->writeAccess('attributes')) {
1638  $rl = new Cron_Job_Regenerate_Report();
1639  $edit_fns = $rl->getEditFns();
1640 
1641  $new_rl = $prefix.'_new_rl';
1642  if (isset($new_rl)) {
1643  if ($edit_fns->processInLineBackend($rl, $o, $new_rl)) {
1644  $rl->setAttrValue('long', TRUE);
1645  $rl->setAttrValue('asset', $asset->id);
1646  $rl->saveAttributes();
1647  } else {
1648  return FALSE;
1649  }
1650  } else {
1651  return FALSE;
1652  }
1653 
1654  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
1655  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
1656  if ($cron_mgr->addJob($rl, $GLOBALS['SQ_SYSTEM']->user)) {
1657  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
1658  $is_updated = TRUE;
1659  } else {
1660  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
1661  }
1662  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
1663 
1664  }// end if
1665  }//end if
1666 
1667  }//end if
1668 
1669  }//end processFutureRegenerate()
1670 
1671 
1682  function paintReportBrokenLink(&$asset, &$o, $prefix)
1683  {
1684  if (!$asset->writeAccess('attributes')) return FALSE;
1685  echo hidden_field($prefix.'_report_broken', '0');
1686 
1687  $enabled = FALSE;
1688  $report_path = $asset->data_path.'/report.xml';
1689  $report_info = $asset->attr('report_info');
1690  // if report not generated, or already sent notification, then disable this button
1691  if (file_exists($report_path) && empty($report_info)) {
1692  $enabled = TRUE;
1693  }
1694  $extras = '';
1695 
1696  if (!$enabled) $extras = 'disabled="disabled"';
1697 
1698  echo normal_button($prefix.'_report_broken_button', translate('cms_report_links_broken_button'), 'this.form.'.$prefix.'_report_broken.value = 1; this.form.submit();', $extras);
1699  if (!$report_info) {
1700  $o->note(translate('cms_report_links_broken_note'));
1701  } else {
1702  $o->note($asset->attr('report_info'));
1703  }
1704 
1705  return TRUE;
1706 
1707  }//end paintReportBrokenLink()
1708 
1709 
1722  function processReportBrokenLink(&$asset, &$o, $prefix)
1723  {
1724  if (!$_POST[$prefix.'_report_broken']) return TRUE;
1725 
1726  return $asset->reportBrokenLink();
1727 
1728  }//end processReportBrokenLink()
1729 
1730 
1731 }//end class
1732 
1733 ?>