Example #1
0
 /**
  * Register a callback for the given event(s)
  *
  * @throws iMSCP_Plugin_Exception
  * @param iMSCP_Events_Manager_Interface $eventsManager
  */
 public function register(iMSCP_Events_Manager_Interface $eventsManager)
 {
     if (!is_xhr()) {
         // Do not act on AJAX request
         $components = $this->getConfigParam('components');
         if ($components) {
             if (is_array($components)) {
                 foreach ($components as $component) {
                     require_once 'Component/' . $component . '.php';
                     $componentClass = "iMSCP_Plugin_DebugBar_Component_{$component}";
                     $component = new $componentClass();
                     if (!$component instanceof iMSCP_Plugin_DebugBar_Component_Interface) {
                         throw new iMSCP_Plugin_Exception('Any DebugBar component must implement the iMSCP_Plugin_DebugBar_Component_Interface interface.');
                     } else {
                         $events = $component->getListenedEvents();
                         if (!empty($events)) {
                             $eventsManager->registerListener($events, $component, $component->getPriority());
                         }
                     }
                     $this->components[] = $component;
                 }
                 $eventsManager->registerListener($this->getListenedEvents(), $this, -100);
             } else {
                 throw new iMSCP_Plugin_Exception('DebugBar plugin: components parameter must be an array containing list of DeburBar components');
             }
         }
     }
 }
Example #2
0
 /**
  * Runs initializer
  *
  * @throws iMSCP_Exception
  * @param string|iMSCP_Config_Handler_File $command Initializer method or an iMSCP_Config_Handler_File object
  * @param iMSCP_Config_Handler_File $config OPTIONAL iMSCP_Config_Handler_File object
  * @return iMSCP_Initializer
  */
 public static function run($command = 'processAll', iMSCP_Config_Handler_File $config = null)
 {
     if (!self::$_initialized) {
         if ($command instanceof iMSCP_Config_Handler_File) {
             $config = $command;
             $command = 'processAll';
         }
         // Overrides _processAll command for CLI interface
         if ($command == 'processAll' && PHP_SAPI == 'cli') {
             $command = 'processCLI';
         } elseif (is_xhr()) {
             $command = 'processAjax';
         }
         $initializer = new self(is_object($config) ? $config : new iMSCP_Config_Handler_File());
         $initializer->{$command}();
     } else {
         throw new iMSCP_Exception('i-MSCP is already fully initialized.');
     }
     return $initializer;
 }
        $html_str = is_xhr() ? '' : ibr_html_heading('claimstatus');
        $html_str .= ibr_disp_status_resp();
    } elseif (isset($_GET['dprfile'])) {
        $html_str = is_xhr() ? '' : ibr_html_heading('claimstatus');
        $html_str .= ibr_disp_dpr_message();
    } elseif (isset($_GET['ebrfile'])) {
        $html_str = is_xhr() ? '' : ibr_html_heading('claimstatus');
        $html_str .= ibr_disp_ebr_message();
    } elseif (isset($_GET['fv997'])) {
        $html_str = is_xhr() ? '' : ibr_html_heading('claimstatus');
        $html_str .= ibr_disp_997_message();
    } elseif (isset($_GET['ackfile'])) {
        $html_str = is_xhr() ? '' : ibr_html_heading('claimstatus');
        $html_str .= ibr_disp_ta1_message();
    } elseif (isset($_GET['batchicn'])) {
        $html_str = is_xhr() ? '' : ibr_html_heading('claimstatus');
        $html_str .= ibr_disp_997_for_batch();
    } elseif (array_key_exists('showlog', $_GET)) {
        $la = filter_input(INPUT_GET, 'showlog', FILTER_SANITIZE_STRING);
        $html_str = $la ? csv_log_html() : "input parameter error<br />";
    } elseif (array_key_exists('archivelog', $_GET)) {
        $la = filter_input(INPUT_GET, 'archivelog', FILTER_SANITIZE_STRING);
        $html_str = $la ? csv_log_archive() : "input parameter error<br />";
    } elseif (array_key_exists('getnotes', $_GET)) {
        $la = filter_input(INPUT_GET, 'getnotes', FILTER_SANITIZE_STRING);
        $html_str = $la ? ibr_history_notes() : "input parameter error<br />";
    } else {
        $html_str = "EDI History: unknown parameter<br />" . PHP_EOL;
        //$html_str .= var_dump($_GET) . PHP_EOL;
    }
} else {
Example #4
0
        write_log(sprintf('New domain alias `%s` has been added by %', $domainAliasName, $_SESSION['user_logged']), E_USER_NOTICE);
        set_page_message(tr('Domain alias successfully scheduled for addition.'), 'success');
    } catch (iMSCP_Exception_Database $e) {
        $db->rollBack();
        throw $e;
    }
    return true;
}
/***********************************************************************************************************************
 * Main
 */
require_once 'imscp-lib.php';
iMSCP_Events_Aggregator::getInstance()->dispatch(iMSCP_Events::onResellerScriptStart);
check_login('reseller');
resellerHasFeature('domain_aliases') && resellerHasCustomers() or showBadRequestErrorPage();
if (is_xhr() && isset($_POST['customer_id'])) {
    echo getJsonDomainsList(clean_input($_POST['customer_id']));
    return;
}
$resellerProps = imscp_getResellerProperties($_SESSION['user_id']);
if ($resellerProps['max_als_cnt'] != 0 && $resellerProps['current_als_cnt'] >= $resellerProps['max_als_cnt']) {
    set_page_message(tr('You have reached the maximum number of domain aliasses allowed by your subscription.'), 'warning');
    redirectTo('users.php');
}
if (!empty($_POST) && addDomainAlias()) {
    redirectTo('alias.php');
}
$tpl = new iMSCP_pTemplate();
$tpl->define_dynamic(array('layout' => 'shared/layouts/ui.tpl', 'page' => 'reseller/alias_add.tpl', 'page_message' => 'layout', 'customer_option' => 'page', 'shared_mount_point_domain' => 'page'));
$tpl->assign(array('TR_PAGE_TITLE' => tr('Reseller / Domains / Add Domain Alias'), 'TR_CUSTOMER_ACCOUNT' => tr('Customer account'), 'TR_DOMAIN_ALIAS' => tr('Domain alias'), 'TR_DOMAIN_ALIAS_NAME' => tr('Domain alias name'), 'TR_DOMAIN_ALIAS_NAME_TOOLTIP' => tr("You must omit 'www'. It will be added automatically."), 'TR_SHARED_MOUNT_POINT' => tr('Shared mount point'), 'TR_SHARED_MOUNT_POINT_TOOLTIP' => tr('Allows to share the mount point of another domain.'), 'TR_URL_FORWARDING' => tr('URL forwarding'), 'TR_URL_FORWARDING_TOOLTIP' => tr('Allows to forward any request made to this domain alias to a specific URL. Be aware that when this option is in use, no Web folder is created for the domain alias.'), 'TR_FORWARD_TO_URL' => tr('Forward to URL'), 'TR_YES' => tr('Yes'), 'TR_NO' => tr('No'), 'TR_HTTP' => 'http://', 'TR_HTTPS' => 'https://', 'TR_FTP' => 'ftp://', 'TR_ADD' => tr('Add'), 'TR_CANCEL' => tr('Cancel')));
generateNavigation($tpl);
Example #5
0
                $actions = tr('n\\a');
        }
        $row['actions'] = $actions;
        $output['aaData'][] = $row;
    }
    return $output;
}
/***********************************************************************************************************************
 * Main
 */
// Include core library
require 'imscp-lib.php';
iMSCP_Events_Aggregator::getInstance()->dispatch(iMSCP_Events::onResellerScriptStart);
check_login('reseller');
resellerHasFeature('domain_aliases') or showBadRequestErrorPage();
if (is_xhr()) {
    header('Cache-Control: no-cache, must-revalidate');
    header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
    header('Content-type: application/json');
    header('Status: 200 OK');
    echo json_encode(reseller_getDatatable());
    exit;
}
/** @var $tpl iMSCP_pTemplate */
$tpl = new iMSCP_pTemplate();
$tpl->define_dynamic(array('layout' => 'shared/layouts/ui.tpl', 'page' => 'reseller/alias.tpl', 'page_message' => 'layout', 'als_add_button' => 'page'));
$tpl->assign(array('TR_PAGE_TITLE' => tr('Reseller / Customers / Domain Aliases'), 'TR_ALIAS_NAME' => tr('Domain alias name'), 'TR_MOUNT_POINT' => tr('Mount point'), 'TR_FORWARD_URL' => tr('Forward URL'), 'TR_STATUS' => tr('Status'), 'TR_CUSTOMER' => tr('Customer'), 'TR_ACTIONS' => tr('Actions'), 'TR_ADD_DOMAIN_ALIAS' => tr('Add domain alias'), 'TR_MESSAGE_DELETE_ALIAS' => tr('Are you sure you want to delete the %s domain alias?', '%s'), 'TR_MESSAGE_DELETE_ALIAS_ORDER' => tr('Are you sure you want to delete the %s domain alias order?', '%s'), 'TR_PROCESSING_DATA' => tr('Processing...')));
iMSCP_Events_Aggregator::getInstance()->registerListener('onGetJsTranslations', function ($e) {
    /** @var $e \iMSCP_Events_Event */
    $e->getParam('translations')->core['dataTable'] = getDataTablesPluginTranslations(false);
});
Example #6
0
 /**
  * Gzip Filter
  *
  * This method can be used both for create standard gz files, and as filter for the ob_start() function to help
  * facilitate sending gzip encoded data to the clients browsers that support the gzip content-coding.
  *
  * According the PHP documentation, when used as filter for the ob_start() function, and if any error occurs, FALSE
  * is returned and then, content is sent to the client browser without compression. Note that FALSE is also
  * returned when the data are already encoded.
  *
  * If used in {@link self::FILTER_FILE} mode and if the $filePath is not specified, the encoded string is returned
  * instead of be written in a file.
  *
  * @param string $data Data to be compressed
  * @param string $filePath File path to be used for gz file creation]
  * @return string|bool Encoded string in gzip file format, FALSE on failure
  */
 public function filter($data, $filePath = '')
 {
     $this->_data = $data;
     // Act as filter for the PHP ob_start function
     if ($this->_mode === self::FILTER_BUFFER) {
         if (ini_get('output_handler') != 'ob_gzhandler' && !ini_get('zlib.output_compression') && !headers_sent() && connection_status() == CONNECTION_NORMAL && $this->_getEncoding() && strcmp(substr($data, 0, 2), "‹")) {
             if ($this->compressionInformation && !is_xhr()) {
                 $statTime = microtime(true);
                 $gzipData = $this->_getEncodedData();
                 $time = round((microtime(true) - $statTime) * 1000, 2);
                 $this->_gzipDataSize = strlen($gzipData);
                 $gzipData = $this->_addCompressionInformation($time);
             } else {
                 $gzipData = $this->_getEncodedData();
                 $this->_gzipDataSize = strlen($gzipData);
             }
             // Send required headers
             $this->_sendHeaders();
         } else {
             return false;
         }
         // Create standard gz file
     } else {
         $gzipData = $this->_getEncodedData();
         if ($filePath != '' && $gzipData !== false) {
             $this->_writeFile($gzipData, $filePath);
         }
     }
     return $gzipData;
 }
Example #7
0
<?php

$tmpl_vars['contact_success'] = false;
if (!empty($_POST['name']) && !empty($_POST['email']) && !empty($_POST['message'])) {
    $time = time();
    $subject = 'Contact via lynx.io contact form';
    $message = <<<EOF
Contacted at {$time}.

From: {$_POST['name']} <{$_POST['email']}>

Body:
{$_POST['message']}
EOF;
    $headers = <<<EOF
From: {$config['email']}
Reply-To: {$_POST['email']}
EOF;
    if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) && mail($config['email'], $subject, $message, $headers)) {
        $tmpl_vars['contact_success'] = true;
    } else {
        $tmpl_vars['contact_failure'] = true;
    }
}
if (is_xhr(true)) {
    $success = $tmpl_vars['contact_success'];
    echo $success ? '"Successfully sent"' : '"Failed to send"';
} else {
    $tmpl_vars['page_title'] = 'Contact';
    $twig->display('contact.twig.html', $tmpl_vars);
}
Example #8
0
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * @link 		http://www.easyscp.net
 * @author 		EasySCP Team
 */
require '../../include/easyscp-lib.php';
check_login(__FILE__);
$cfg = EasySCP_Registry::get('Config');
// Avoid unneeded generation during Ajax request
if (!is_xhr()) {
    $tpl = EasySCP_TemplateEngine::getInstance();
    $template = 'reseller/user_add4.tpl';
    // static page messages
    gen_logged_from($tpl);
    $tpl->assign(array('TR_PAGE_TITLE' => tr('EasySCP - User/Add user'), 'TR_MANAGE_DOMAIN_ALIAS' => tr('Manage domain alias'), 'TR_ADD_ALIAS' => tr('Add domain alias'), 'TR_DOMAIN_NAME' => tr('Domain name'), 'TR_DOMAIN_ACCOUNT' => tr('User account'), 'TR_MOUNT_POINT' => tr('Directory mount point'), 'TR_DOMAIN_IP' => tr('Domain IP'), 'TR_DMN_HELP' => tr("You do not need 'www.' EasySCP will add it on its own."), 'TR_FORWARD' => tr('Forward to URL'), 'TR_ADD' => tr('Add alias'), 'TR_DOMAIN_ALIAS' => tr('Domain alias'), 'TR_STATUS' => tr('Status'), 'TR_ADD_USER' => tr('Add user'), 'TR_GO_USERS' => tr('Done'), 'TR_ENABLE_FWD' => tr("Enable Forward"), 'TR_ENABLE' => tr("Enable"), 'TR_DISABLE' => tr("Disable"), 'TR_PREFIX_HTTP' => 'http://', 'TR_PREFIX_HTTPS' => 'https://', 'TR_PREFIX_FTP' => 'ftp://'));
    gen_reseller_mainmenu($tpl, 'reseller/main_menu_users_manage.tpl');
    gen_reseller_menu($tpl, 'reseller/menu_users_manage.tpl');
    if (isset($_SESSION['dmn_id']) && $_SESSION['dmn_id'] !== '') {
        $domain_id = $_SESSION['dmn_id'];
        $reseller_id = $_SESSION['user_id'];
        $query = "\n\t\t\tSELECT\n\t\t\t\tdomain_id, status\n\t\t\tFROM\n\t\t\t\tdomain\n\t\t\tWHERE\n\t\t\t\tdomain_id = ?\n\t\t\tAND\n\t\t\t\tdomain_created_id = ?\n\t\t;";
        $result = exec_query($sql, $query, array($domain_id, $reseller_id));
        if ($result->recordCount() == 0) {
            set_page_message(tr('User does not exist or you do not have permission to access this interface!'), 'warning');
            // Back to the users page
Example #9
0
function autherz($flag, $redirect = false)
{
    if (!$flag) {
        if (is_xhr()) {
            echo "expired";
        } else {
            $goto = $redirect ? $redirect : $_SERVER['HTTP_HOST'];
            header("Location: http://{$redirect}");
        }
        exit;
    }
}
Example #10
0
<?php

$slug = $matches[2];
// Get comments
if (!empty($_GET['timestamp']) || is_xhr(true)) {
    $timestamp = (int) $_GET['timestamp'];
    if ($timestamp < time() - 68400) {
        echo '"Invalid time"';
        exit;
    }
    $newComments = array();
    foreach (get_comments($slug) as $comment) {
        if ($comment->date > $timestamp) {
            $newComments[] = array('author' => $comment->author, 'website' => $comment->website, 'date' => date('jS M Y \\a\\t h:i:s A', $comment->date), 'text' => $comment->text);
        }
    }
    echo json_encode($newComments);
    exit;
}
if (is_readable('cache/articles/' . $slug . '.json')) {
    $info = file_get_contents('cache/articles/' . $slug . '.json');
    $info = json_decode($info, true);
    $raw_body = file_get_contents('articles/' . $slug . '.md');
    if ($raw_body === $info['raw_body']) {
        if (is_readable('authors/' . $info['author'] . '.json')) {
            $author = file_get_contents('authors/' . $info['author'] . '.json');
            $info['author'] = json_decode($author);
        } else {
            unset($info['author']);
        }
        $tmpl_vars['article'] = $info;
Example #11
0
/**
 * check for valid user login
 *
 * @param string $fName Full file path (ie. the magic __FILE__ constant value)
 */
function check_login($fName = null)
{
    // session-type check:
    if (!check_user_login()) {
        if (is_xhr()) {
            header('HTTP/1.0 403 Forbidden');
            exit;
        }
        user_goto('/index.php');
    }
    if (!is_null($fName)) {
        // TODO: Prüfen ob das so ok ist. Das '\\' wird bei Windows Pfaden benötigt.
        // $levels = explode('/', realpath(dirname($fName)));
        // $levels = explode('\\', realpath(dirname($fName)));
        // $level = $levels[count($levels) - 1];
        $level = basename(dirname($fName));
        $userType = $_SESSION['user_type'] == 'user' ? 'client' : $_SESSION['user_type'];
        if ($userType != $level) {
            if ($userType != 'admin' && (!isset($_SESSION['logged_from']) || $_SESSION['logged_from'] != 'admin')) {
                $userLoggued = isset($_SESSION['logged_from']) ? $_SESSION['logged_from'] : $_SESSION['user_logged'];
                write_log('Warning! user |' . $userLoggued . '| requested |' . tohtml($_SERVER['REQUEST_URI']) . '| with REQUEST_METHOD |' . $_SERVER['REQUEST_METHOD'] . '|');
            }
            user_goto('/index.php');
        }
    }
}
Example #12
0
    }
    return $ret;
}
/***********************************************************************************************************************
 * Main
 */
// Include core library
require_once 'imscp-lib.php';
iMSCP_Events_Aggregator::getInstance()->dispatch(iMSCP_Events::onClientScriptStart);
check_login('user');
customerHasFeature('ftp') or showBadRequestErrorPage();
$mainDmnProps = get_domain_default_props($_SESSION['user_id']);
$mainDmnId = $mainDmnProps['domain_id'];
$mainDmnName = $mainDmnProps['domain_name'];
$ftpAccountLimit = $mainDmnProps['domain_ftpacc_limit'];
if (is_xhr() && isset($_POST['domain_type'])) {
    echo json_encode(ftp_getDomainList($mainDmnName, $mainDmnId, clean_input($_POST['domain_type'])));
    exit;
} elseif (!empty($_POST)) {
    // Check for ftp account limit (only on new account submission to avoid too many query each time the page
    // is displayed
    $nbFtpAccounts = get_customer_running_ftp_acc_cnt($_SESSION['user_id']);
    if ($ftpAccountLimit && $nbFtpAccounts >= $ftpAccountLimit) {
        set_page_message(tr('FTP account limit reached.'), 'error');
        redirectTo('ftp_accounts.php');
    }
    if (ftp_addAccount($mainDmnName)) {
        redirectTo('ftp_accounts.php');
    }
}
/** @var $cfg iMSCP_Config_Handler_File */
Example #13
0
/**
 * Check login
 *
 * @param string $userLevel User level (admin|reseller|user)
 * @param bool $preventExternalLogin If TRUE, external login is disallowed
 */
function check_login($userLevel = '', $preventExternalLogin = true)
{
    do_session_timeout();
    $auth = iMSCP_Authentication::getInstance();
    if (!$auth->hasIdentity()) {
        $auth->unsetIdentity();
        // Ensure deletion of all entity data
        if (is_xhr()) {
            header('HTTP/1.0 403 Forbidden');
            exit;
        }
        redirectTo('/index.php');
    }
    /** @var $cfg iMSCP_Config_Handler_File */
    $cfg = iMSCP_Registry::get('config');
    $identity = $auth->getIdentity();
    if ($cfg->MAINTENANCEMODE && $identity->admin_type != 'admin' && (!isset($_SESSION['logged_from_type']) || $_SESSION['logged_from_type'] != 'admin')) {
        $auth->unsetIdentity();
        redirectTo('/index.php');
    }
    // Check user level
    if (!empty($userLevel) && ($userType = $identity->admin_type) != $userLevel) {
        if ($userType != 'admin' && (!isset($_SESSION['logged_from']) || $_SESSION['logged_from'] != 'admin')) {
            $loggedUser = isset($_SESSION['logged_from']) ? $_SESSION['logged_from'] : $identity->admin_name;
            write_log('Warning! user |' . $loggedUser . '| requested |' . tohtml($_SERVER['REQUEST_URI']) . '| with REQUEST_METHOD |' . $_SERVER['REQUEST_METHOD'] . '|', E_USER_WARNING);
        }
        redirectTo('/index.php');
    }
    // prevent external login / check for referer
    if ($preventExternalLogin && !empty($_SERVER['HTTP_REFERER'])) {
        // Extracting hostname from referer URL
        // Note2: We remove any braket in referer (ipv6 issue)
        $refererHostname = str_replace(array('[', ']'), '', parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST));
        // The URL does contains the host element ?
        if (!is_null($refererHostname)) {
            // Note1: We don't care about the scheme, we only want make parse_url() happy
            // Note2: We remove any braket in hostname (ipv6 issue)
            $http_host = str_replace(array('[', ']'), '', parse_url("http://{$_SERVER['HTTP_HOST']}", PHP_URL_HOST));
            // The referer doesn't match the panel hostname ?
            if (!in_array($refererHostname, array($http_host, $_SERVER['SERVER_NAME']))) {
                set_page_message(tr('Request from foreign host was blocked.'), 'info');
                # Quick fix for #96 (will be rewritten ASAP)
                isset($_SERVER['REDIRECT_URL']) ?: ($_SERVER['REDIRECT_URL'] = '');
                if (!(substr($_SERVER['SCRIPT_FILENAME'], (int) -strlen($_SERVER['REDIRECT_URL']), strlen($_SERVER['REDIRECT_URL'])) == $_SERVER['REDIRECT_URL'])) {
                    redirectToUiLevel();
                }
            }
        }
    }
    // If all goes fine update session and lastaccess
    $_SESSION['user_login_time'] = time();
    exec_query('UPDATE login SET lastaccess = ? WHERE session_id = ?', array($_SESSION['user_login_time'], session_id()));
}
Example #14
0
/**
 * Show 404 error page
 *
 * @return void
 */
function showNotFoundErrorPage()
{
    /** @var $cfg iMSCP_Config_Handler_File */
    $cfg = iMSCP_Registry::get('config');
    $filePath = $cfg->GUI_ROOT_DIR . '/public/errordocs/404.html';
    header("Status: 404 Not Found");
    $response = '';
    if (isset($_SERVER['HTTP_ACCEPT'])) {
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'text/html') !== false || strpos($_SERVER['HTTP_ACCEPT'], 'application/xhtml') !== false) && !is_xhr()) {
            $response = file_get_contents($filePath);
        } elseif (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false) {
            header("Content-type: application/json");
            $response = json_encode(array('code' => 404, 'message' => 'Not Found'));
        } elseif (strpos($_SERVER['HTTP_ACCEPT'], 'application/xmls') !== false) {
            header("Content-type: text/xml;charset=utf-8");
            $response = '<?xml version="1.0" encoding="utf-8"?>';
            $response = $response . '<response><code>404</code>';
            $response = $response . '<message>Not Found</message></response>';
        } elseif (!is_xhr()) {
            include $filePath;
        }
    } elseif (!is_xhr()) {
        $response = file_get_contents($filePath);
    }
    if ($response != '') {
        echo $response;
    }
    exit;
}
Example #15
0
<?php

if (!is_xhr(true) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo 'Please don\'t access this page directly.';
    exit;
}
$slug = $matches[2];
if (empty($slug) || !is_readable('articles/' . $slug . '.md')) {
    echo 'Article not found.';
    exit;
}
if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['text'])) {
    echo 'Please specify all required forms.';
    exit;
}
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
    echo 'Invalid email address.';
    exit;
}
if (!empty($_POST['website'])) {
    $website = $_POST['website'];
    if (!filter_var($website, FILTER_VALIDATE_URL)) {
        echo 'Invalid website.';
        exit;
    }
} else {
    $website = '';
}
if (is_readable('articles/comments/' . $slug . '.json')) {
    $comments = file_get_contents('articles/comments/' . $slug . '.json');
    $comments = json_decode($comments);