mirror of
https://github.com/gtbu/Typesetter-5.3-p8.git
synced 2024-11-25 07:39:13 +01:00
304 lines
7.1 KiB
PHP
304 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace gp\special;
|
|
|
|
defined('is_running') or die('Not an entry point...');
|
|
|
|
|
|
class Missing extends \gp\special\Base{
|
|
|
|
public $datafile;
|
|
public $error_data = array();
|
|
public $requested;
|
|
|
|
|
|
public function Init(){
|
|
|
|
$this->datafile = '_site/error_data';
|
|
$this->error_data = \gp\tool\Files::Get($this->datafile,'error_data');
|
|
|
|
$this->error_data += array(
|
|
'redirects' => array(
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
public function __construct($args){
|
|
global $langmessage;
|
|
|
|
parent::__construct($args);
|
|
$this->Init();
|
|
|
|
$this->requested = $this->page->requested;
|
|
}
|
|
|
|
public function RunScript(){
|
|
$cmd = \gp\tool::GetCommand();
|
|
$this->RunCommands($cmd);
|
|
}
|
|
|
|
public function DefaultDisplay(){
|
|
|
|
if( $this->page->gp_index !== 'special_missing' ){
|
|
$this->CheckRedirect();
|
|
$this->CheckSimilar();
|
|
}
|
|
|
|
$this->Get404();
|
|
}
|
|
|
|
/**
|
|
* Redirect the request if a redirection entry matches the requested page
|
|
*
|
|
*/
|
|
public function CheckRedirect(){
|
|
|
|
if( is_null($this->requested) ){
|
|
return;
|
|
}
|
|
|
|
$parts = explode('/',$this->requested);
|
|
$first_part = array_shift($parts);
|
|
|
|
if( !isset($this->error_data['redirects'][$first_part]) ){
|
|
return;
|
|
}
|
|
|
|
|
|
$target = $this->error_data['redirects'][$first_part]['target'];
|
|
|
|
$target = $this->GetTarget($target);
|
|
|
|
if( $target === false ){
|
|
return;
|
|
}
|
|
|
|
if( !empty($parts) && is_string($target) ){
|
|
$target .= '/'.implode('/',$parts);
|
|
}
|
|
|
|
$code = $this->error_data['redirects'][$first_part]['code'];
|
|
\gp\tool::Redirect($target,$code);
|
|
}
|
|
|
|
/**
|
|
* Redirect the request if the requested page closely matches an existing page
|
|
* If it's just a difference of case, then the similarity will be 100%
|
|
*
|
|
*/
|
|
public function CheckSimilar(){
|
|
global $config;
|
|
|
|
$requested = trim($this->requested,'/');
|
|
$similar = $this->SimilarTitleArray($requested);
|
|
$first_title = key($similar);
|
|
$first_percent = current($similar);
|
|
|
|
if( $config['auto_redir'] > 0 && $first_percent >= $config['auto_redir'] ){
|
|
$redirect = \gp\tool::GetUrl($first_title,http_build_query($_GET),false);
|
|
\gp\tool::Redirect($redirect);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Translate the $target url to a url that can be used with Header() or in a link
|
|
*
|
|
* @param string $target The user supplied value for redirection
|
|
* @param boolean $get_final If true, GetTarget() will check for additional redirection and $target existence before returning the url. Maximum of 10 redirects.
|
|
* @return string|false
|
|
*/
|
|
public function GetTarget($target,$get_final = true){
|
|
global $gp_index;
|
|
static $redirects = 0;
|
|
|
|
if( empty($target) ){
|
|
return \gp\tool::GetUrl('');
|
|
}
|
|
|
|
if( !$this->isGPLink($target) ){
|
|
return $target;
|
|
}
|
|
|
|
if( !$get_final ){
|
|
return \gp\tool::GetUrl($target);
|
|
}
|
|
|
|
|
|
//check for more redirects
|
|
if( isset($this->error_data['redirects'][$target]) ){
|
|
$redirects++;
|
|
if( $redirects > 10 ){
|
|
return false;
|
|
}
|
|
|
|
$target = $this->error_data['redirects'][$target]['target'];
|
|
return $this->GetTarget($target);
|
|
}
|
|
|
|
|
|
//check for target existence
|
|
if( isset($gp_index[$target]) ){
|
|
return \gp\tool::GetUrl($target);
|
|
}
|
|
|
|
$scripts = \gp\admin\Tools::AdminScripts();
|
|
if( isset($scripts[$target]) ){
|
|
return \gp\tool::GetUrl($target);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function isGPLink($target){
|
|
//has a url scheme (aka protocol)
|
|
$reg = '#^[a-zA-Z][a-zA-Z0-9\+\.\-]+:#';
|
|
if( preg_match($reg,$target,$matches) ){
|
|
return false;
|
|
}
|
|
|
|
//strings beginning with / could be gplinks, they could also links to non-cms managed pages
|
|
// we could do additional testing, but we could never be certain what the user intent is
|
|
if( strpos($target,'/') === 0 ){
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
public function Get404(){
|
|
global $langmessage,$page;
|
|
|
|
\gp\tool\Output::AddHeader('Not Found',true,404);
|
|
$page->head .= '<meta name="robots" content="noindex,nofollow" />'; //this isn't getting to the template because $page isn't available yet
|
|
|
|
//message for admins
|
|
if( \gp\tool::LoggedIn() ){
|
|
if( $this->requested && \gp\tool::SpecialOrAdmin($this->requested) === false ){
|
|
$with_spaces = htmlspecialchars($this->requested);
|
|
$link = \gp\tool::GetUrl('Admin/Menu/Ajax','cmd=AddHidden&redir=redir&title='.rawurlencode($this->requested)).'" title="'.$langmessage['create_new_file'].'" data-cmd="gpabox';
|
|
$message = sprintf($langmessage['DOESNT_EXIST'],$with_spaces,$link);
|
|
msg($message);
|
|
}
|
|
}
|
|
|
|
echo '<div class="GPAREA filetype-special_missing">';
|
|
//Contents of 404 page
|
|
$wrap = \gp\tool\Output::ShowEditLink('Admin/Missing');
|
|
if( $wrap ){
|
|
echo \gp\tool\Output::EditAreaLink($edit_index,'Admin/Missing',$langmessage['edit'],'cmd=edit404',' title="'.$langmessage['404_Page'].'" ');
|
|
echo '<div class="editable_area" id="ExtraEditArea'.$edit_index.'">'; // class="edit_area" added by javascript
|
|
}
|
|
|
|
echo self::Get404Output();
|
|
|
|
if( $wrap ){
|
|
echo '</div>';
|
|
}
|
|
echo '</div>';
|
|
}
|
|
|
|
/**
|
|
* Return the custom 404 page content if it exists, otherwise return the default content
|
|
*
|
|
*/
|
|
public function Get404Output(){
|
|
|
|
if( isset($this->error_data['404_TEXT']) ){
|
|
$text = $this->error_data['404_TEXT'];
|
|
}else{
|
|
$text = self::DefaultContent();
|
|
}
|
|
|
|
return str_replace('{{Similar_Titles}}',$this->SimilarTitles(),$text);
|
|
}
|
|
|
|
/**
|
|
* Get a comma separated list of links to titles similar to the requested page
|
|
* @return string
|
|
*
|
|
*/
|
|
public function SimilarTitles(){
|
|
|
|
$similar = $this->SimilarTitleArray($this->requested);
|
|
$similar = array_slice($similar,0,7,true);
|
|
$result = '';
|
|
|
|
foreach($similar as $title => $percent_similar){
|
|
if ( $title === key($similar) || $percent_similar > 10 ) {
|
|
$result .= \gp\tool::Link_Page($title).', ';
|
|
}
|
|
}
|
|
|
|
return rtrim($result,', ');
|
|
}
|
|
|
|
|
|
/**
|
|
* Get a list of existing titles similar to the requested page
|
|
* @param string $title of requested page
|
|
* @return array of similar titles reverse-numerical sorted by similarity (percent)
|
|
*
|
|
*/
|
|
public function SimilarTitleArray($title){
|
|
global $gp_index, $gp_titles;
|
|
|
|
$similar_titles = [];
|
|
$lower = str_replace(' ','_',strtolower($title));
|
|
|
|
foreach($gp_index as $title => $index){
|
|
|
|
//skip 'special_missing' page
|
|
if( $index == 'special_missing' ){
|
|
continue;
|
|
}
|
|
|
|
//skip private pages when not logged-in
|
|
if( !\gp\tool::LoggedIn() && isset($gp_titles[$index]['vis']) ){
|
|
continue;
|
|
}
|
|
|
|
similar_text($lower,mb_strtolower($title),$percent);
|
|
$similar_titles[$index] = [
|
|
'title' => $title,
|
|
'percent' => $percent,
|
|
];
|
|
}
|
|
|
|
uasort($similar_titles, function($a, $b) {
|
|
return $b['percent'] - $a['percent'];
|
|
});
|
|
|
|
$similar_titles = \gp\tool\Plugins::Filter('SimilarTitles', [$similar_titles]);
|
|
|
|
$similar = [];
|
|
foreach( $similar_titles as $similar_title ){
|
|
$similar[$similar_title['title']] = $similar_title['percent'];
|
|
}
|
|
|
|
return $similar;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returnt the default content of the 404 page
|
|
*
|
|
*/
|
|
public function DefaultContent(){
|
|
global $langmessage;
|
|
$text = '<h2>'.$langmessage['Not Found'].'</h2>';
|
|
$text .= '<p>';
|
|
$text .= $langmessage['OOPS_TITLE'];
|
|
$text .= '</p>';
|
|
$text .= '<p>';
|
|
$text .= '<b>'.$langmessage['One of these titles?'].'</b>';
|
|
$text .= '<div class="404_suggestions">{{Similar_Titles}}</div>';
|
|
$text .= '</p>';
|
|
return $text;
|
|
}
|
|
|
|
}
|