<?php namespace HashOver;

// Copyright (C) 2018-2019 Jacob Barkdull
// This file is part of HashOver.
//
// HashOver is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// HashOver is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with HashOver. If not, see <http://www.gnu.org/licenses/>.


class SourceCode
{
public $files = array (
array (
'type' => 'Script',
'path' => 'admin/blocklist/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/en-us/api/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/en-us/faq/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/en-us/security/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/en-us/settings/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/en-us/setup/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/en-us/technical/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/en-us/use/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/en-us/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/docs/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/example/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/login/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/moderation/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/moderation/threads.php'
),
array (
'type' => 'Script',
'path' => 'admin/settings/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/updates/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/url-queries/index.php'
),
array (
'type' => 'Script',
'path' => 'admin/view-setup.php'
),
array (
'type' => 'Script',
'path' => 'admin/index.php'
),
array (
'type' => 'Script',
'path' => 'api/backend/count-link-ajax.php'
),
array (
'type' => 'Script',
'path' => 'api/backend/latest-ajax.php'
),
array (
'type' => 'Script',
'path' => 'api/count-link.php'
),
array (
'type' => 'Script',
'path' => 'api/json.php'
),
array (
'type' => 'Script',
'path' => 'api/latest.php'
),
array (
'type' => 'Script',
'path' => 'api/rss.php'
),
array (
'type' => 'Class',
'name' => 'Avatars',
'path' => 'backend/classes/avatars.php'
),
array (
'type' => 'Class',
'name' => 'CommentFiles',
'path' => 'backend/classes/commentfiles.php'
),
array (
'type' => 'Class',
'name' => 'CommentParser',
'path' => 'backend/classes/commentparser.php'
),
array (
'type' => 'Class',
'name' => 'CommentsUI',
'path' => 'backend/classes/commentsui.php'
),
array (
'type' => 'Class',
'name' => 'Cookies',
'path' => 'backend/classes/cookies.php'
),
array (
'type' => 'Class',
'name' => 'Crypto',
'path' => 'backend/classes/crypto.php'
),
array (
'type' => 'Class',
'name' => 'Database',
'path' => 'backend/classes/database.php'
),
array (
'type' => 'Class',
'name' => 'DataFiles',
'path' => 'backend/classes/datafiles.php'
),
array (
'type' => 'Class',
'name' => 'DefaultLogin',
'path' => 'backend/classes/defaultlogin.php'
),
array (
'type' => 'Class',
'name' => 'Email',
'path' => 'backend/classes/email.php'
),
array (
'type' => 'Class',
'name' => 'FormUI',
'path' => 'backend/classes/formui.php'
),
array (
'type' => 'Class',
'name' => 'HashOver',
'path' => 'backend/classes/hashover.php'
),
array (
'type' => 'Class',
'name' => 'HTMLTag',
'path' => 'backend/classes/htmltag.php'
),
array (
'type' => 'Class',
'name' => 'JavaScriptBuild',
'path' => 'backend/classes/javascriptbuild.php'
),
array (
'type' => 'Class',
'name' => 'JavaScriptMinifier',
'path' => 'backend/classes/javascriptminifier.php'
),
array (
'type' => 'Class',
'name' => 'Locale',
'path' => 'backend/classes/locale.php'
),
array (
'type' => 'Class',
'name' => 'Login',
'path' => 'backend/classes/login.php'
),
array (
'type' => 'Class',
'name' => 'Markdown',
'path' => 'backend/classes/markdown.php'
),
array (
'type' => 'Class',
'name' => 'Misc',
'path' => 'backend/classes/misc.php'
),
array (
'type' => 'Class',
'name' => 'ParseJSON',
'path' => 'backend/classes/parsejson.php'
),
array (
'type' => 'Class',
'name' => 'ParseSQL',
'path' => 'backend/classes/parsesql.php'
),
array (
'type' => 'Class',
'name' => 'ParseXML',
'path' => 'backend/classes/parsexml.php'
),
array (
'type' => 'Class',
'name' => 'PHPMode',
'path' => 'backend/classes/phpmode.php'
),
array (
'type' => 'Class',
'name' => 'FormData',
'path' => 'backend/classes/formdata.php'
),
array (
'type' => 'Class',
'name' => 'SafeSettings',
'path' => 'backend/classes/safesettings.php'
),
array (
'type' => 'Class',
'name' => 'Sendmail',
'path' => 'backend/classes/sendmail.php'
),
array (
'type' => 'Class',
'name' => 'SensitiveSettings',
'path' => 'backend/classes/sensitivesettings.php'
),
array (
'type' => 'Class',
'name' => 'SessionLogin',
'path' => 'backend/classes/sessionlogin.php'
),
array (
'type' => 'Class',
'name' => 'Settings',
'path' => 'backend/classes/settings.php'
),
array (
'type' => 'Class',
'name' => 'Setup',
'path' => 'backend/classes/setup.php'
),
array (
'type' => 'Class',
'name' => 'SetupChecks',
'path' => 'backend/classes/setupchecks.php'
),
array (
'type' => 'Class',
'name' => 'SMTP',
'path' => 'backend/classes/smtp.php'
),
array (
'type' => 'Class',
'name' => 'SourceSode',
'path' => 'backend/classes/sourcecode.php'
),
array (
'type' => 'Class',
'name' => 'SpamCheck',
'path' => 'backend/classes/spamcheck.php'
),
array (
'type' => 'Class',
'name' => 'Statistics',
'path' => 'backend/classes/statistics.php'
),
array (
'type' => 'Class',
'name' => 'Templater',
'path' => 'backend/classes/templater.php'
),
array (
'type' => 'Class',
'name' => 'Thread',
'path' => 'backend/classes/thread.php'
),
array (
'type' => 'Class',
'name' => 'WriteComments',
'path' => 'backend/classes/writecomments.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/da-dk.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/de-de.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/el-el.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/en-us.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/es-es.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/fa-ir.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/fr-fr.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/ja-jp.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/ko-kr.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/lt-lt.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/nl-nl.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/eo-eo.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/pl-pl.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/pt-br.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/ro-ro.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/ru-ru.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/tr-tr.php'
),
array (
'type' => 'Script',
'path' => 'backend/locales/zh-cn.php'
),
array (
'type' => 'Script',
'path' => 'backend/comment-info.php'
),
array (
'type' => 'Script',
'path' => 'backend/comments-ajax.php'
),
array (
'type' => 'Script',
'path' => 'backend/form-actions.php'
),
array (
'type' => 'Script',
'path' => 'backend/javascript-setup.php'
),
array (
'type' => 'Script',
'path' => 'backend/json-setup.php'
),
array (
'type' => 'Script',
'path' => 'backend/like.php'
),
array (
'type' => 'Script',
'path' => 'backend/load-comments.php'
),
array (
'type' => 'Script',
'path' => 'backend/nocache-headers.php'
),
array (
'type' => 'Script',
'path' => 'backend/php-setup.php'
),
array (
'type' => 'Script',
'path' => 'backend/source-viewer.php'
),
array (
'type' => 'Script',
'path' => 'backend/standard-setup.php'
),
array (
'type' => 'Script',
'path' => 'comments.php'
),
array (
'type' => 'Script',
'path' => 'loader.php'
)
);

// Checks if a given file is a HashOver file
protected function isHashOverFile ($path)
{
// Run through HashOver files array
foreach ($this->files as $file) {
// Check if the given file path matches the current file
if ($path === $file['path']) {
// If so, return true
return true;
}
}

// Otherwise return false
return false;
}

// Sets content type header based on user request
protected function setContentType ($file, $type)
{
// Switch between return types
switch ($type) {
// Display as plain text
case 'text': {
// Set content type header to plain text
header ('Content-type: text/plain; charset=UTF-8');
break;
}

// Display as HTML
case 'html': {
// Set content type header to HTML
header ('Content-type: text/html; charset=UTF-8');
break;
}

// Download source code
case 'download': {
// File name
$file_name = basename ($file);

// Set headers to trigger file download
header ('Content-type: application/octet-stream');
header ('Content-Disposition: attachment; filename="' . $file_name . '"');
header ('Content-Length: ' . filesize ($file));

break;
}

// Default to displaying an error
default: {
// Set content type header to plain text
header ('Content-type: text/plain; charset=UTF-8');
break;
}
}
}

// Format source code based on content type
protected function format ($name, $source, $type)
{
// Switch between return types
switch ($type) {
// Display as HTML
case 'html': {
// Conform HTML highlighting to coding standard
$source = str_replace ("\t", ' ', $source);
$source = highlight_string ($source, true);
$source = str_replace (' ', "&#9;", $source);
$source = str_replace ('&nbsp;', ' ', $source);
$source = str_replace ("\n", '', $source);

// Return highlighted source code
return implode (PHP_EOL, array (
'<!DOCTYPE html>',
'<html lang="en" dir="ltr">',
"\t" . '<head>',
"\t\t" . '<title>' . $name . '</title>',
"\t\t" . '<meta name="robots" content="noindex">',
"\t" . '</head>',
"\t" . '<body>',
"\t\t" . '<pre>' . $source . '</pre>',
"\t" . '</body>',
'</html>'
));
}

// Default to displaying as plain text
default: {
return $source;
}
}
}

// Display source code
public function display ($file, $type = 'text')
{
// Check if the given file is a known HashOver file
if ($this->isHashOverFile ($file) === true) {
// If so, add directory change to file path
$file = '../' . $file;

// Set header for search engines to ignore file
header ('X-Robots-Tag: noindex');

// Set content type header
$this->setContentType ($file, $type);

// Load PHP file
$source = @file_get_contents ($file);

// File name
$name = basename ($file);

// Check if file read successfully
if ($source !== false) {
// If so, display formatted source code
echo $this->format ($name, $source, $type);
} else {
// If not, display error
echo 'Error! Failed to read HashOver file!';
}
} else {
// If not, display error
echo 'Error! Not a known HashOver file!';
}
}
}