/opt/forum/system/Db/Db.php
$logDatabase = 'read database';
$this->reader = new \mysqli(
$sqlCredentials['host'],
$sqlCredentials['username'],
$sqlCredentials['password'],
$sqlCredentials['database'],
$sqlCredentials['port'],
$sqlCredentials['socket']
);
$error = $this->reader->connect_error;
$errno = $this->reader->connect_errno;
}
else
{
$logDatabase = 'write database';
parent::real_connect(
$sqlCredentials['host'],
$sqlCredentials['username'],
$sqlCredentials['password'],
$sqlCredentials['database'],
$sqlCredentials['port'],
$sqlCredentials['socket']
);
$error = mysqli_connect_error();
$errno = $this->connect_errno;
}
$this->log( "Connected to the " . $logDatabase, ( $read and $this->connectionDetails['readDatabase'] ) ? 'read' : 'write' );
if( $error )
{
throw new \IPS\Db\Exception( $error, $errno );
}
/opt/forum/system/Db/Db.php
$logDatabase = 'read database';
$this->reader = new \mysqli(
$sqlCredentials['host'],
$sqlCredentials['username'],
$sqlCredentials['password'],
$sqlCredentials['database'],
$sqlCredentials['port'],
$sqlCredentials['socket']
);
$error = $this->reader->connect_error;
$errno = $this->reader->connect_errno;
}
else
{
$logDatabase = 'write database';
/* Connect */
parent::real_connect(
$sqlCredentials['host'],
$sqlCredentials['username'],
$sqlCredentials['password'],
$sqlCredentials['database'],
$sqlCredentials['port'],
$sqlCredentials['socket']
);
$error = mysqli_connect_error();
$errno = $this->connect_errno;
}
/* Store a log entry so we can track */
$this->log( "Connected to the " . $logDatabase, ( $read and $this->connectionDetails['readDatabase'] ) ? 'read' : 'write' );
/* If the connection failed, throw an exception */
if( $error )
{
throw new \IPS\Db\Exception( $error, $errno );
}
/opt/forum/system/Db/Db.php
*
* @param bool $read Is this a read query (i.e. connect to reader)?
* @return void
*/
public function checkConnection( $read = FALSE )
{
/* If we aren't using read/write separation, we only have one connection */
if( !$this->connectionDetails['readDatabase'] )
{
$read = FALSE;
}
/* Have we already connected? */
if( $this->connections[ $read ? 'read' : 'write' ] === TRUE )
{
return;
}
/* Connect */
$this->_establishConnection( $read );
/* And then flag that the connection was successful */
$this->connections[ $read ? 'read' : 'write' ] = TRUE;
}
/**
* @brief Charset
*/
public $charset = 'utf8';
/**
* @brief Collation
*/
public $collation = 'utf8_unicode_ci';
/**
* @brief Binary Collation
*/
public $binaryCollation = 'utf8_bin';
/opt/forum/system/Db/Db.php
$result = $this->query( $query, $log, $read );
$this->returnQuery = $return;
return $result;
}
/**
* Run Prepared SQL Statement
*
* @param string $query SQL Statement
* @param array $_binds Variables to bind
* @param bool $read If TRUE and read/write separation is in use, will use the "read" connection
* @return \mysqli_stmt
*/
public function preparedQuery( $query, array $_binds, $read=FALSE )
{
/* Make sure we're connected */
$this->checkConnection( ( $read AND $this->readWriteSeparation ) );
/* Init Bind object */
$bind = new Db\Bind();
/* Sort out subqueries */
$binds = array();
$i = 0;
for ( $j = 0; $j < \strlen( $query ); $j++ )
{
if ( $query[ $j ] == '?' )
{
if ( array_key_exists( $i, $_binds ) )
{
if ( $_binds[ $i ] instanceof \IPS\Db\Select )
{
$query = \substr( $query, 0, $j ) . $_binds[ $i ]->query . \substr( $query, $j + 1);
$j += \strlen( $_binds[ $i ]->query );
foreach ( $_binds[ $i ]->binds as $_bind )
{
/opt/forum/system/Db/Select.php
/* Move to the first result */
$this->rewind();
/* Return it */
if ( !$this->valid() )
{
throw new \UnderflowException;
}
return $this->current();
}
/**
* Run the query
*
* @return void
*/
protected function runQuery()
{
/* Run the query */
$this->stmt = $this->db->preparedQuery( $this->query, array_merge( $this->joinBinds, $this->binds ), !$this->useWriteServer );
/* Populate $this->row which we read into */
$this->row = array();
$params = array();
$meta = $this->stmt->result_metadata();
if ( !$meta )
{
throw new \IPS\Db\Exception( $this->db->errno ? $this->db->error : "No result metadata - possible table crash", $this->db->errno ?: -1, NULL, $this->query, array_merge( $this->joinBinds, $this->binds ) );
}
while ( $field = $meta->fetch_field() )
{
if ( $this->multiDimensional )
{
$params[] = &$this->row[ $field->table ][ $field->name ];
}
else
{
$params[] = &$this->row[ $field->name ];
/opt/forum/system/Db/Select.php
*/
protected $valueField = NULL;
/**
* @brief Value Table
*/
protected $valueTable = NULL;
/**
* Set key field
*
* @param string $column Column to treat as the key
* @param string|NULL $table The table, if this is a multidimensional select
* @return \IPS\Db\Select
*/
public function setKeyField( $column, $table=NULL )
{
if ( !$this->stmt )
{
$this->runQuery();
}
if ( \is_string( $column ) )
{
if ( $this->multiDimensional )
{
if ( !isset( $this->columns[ $table ] ) or !\in_array( $column, $this->columns[ $table ] ) )
{
throw new \InvalidArgumentException;
}
}
else
{
if ( !\in_array( $column, $this->columns ) )
{
throw new \InvalidArgumentException;
}
}
}
/opt/forum/system/Developer/Developer.php
public function __construct( \IPS\Application $app )
{
$this->app = $app;
}
/**
* @brief Last updates
*/
protected static $lastUpdates = NULL;
/**
* Sync development data for an application
*
* @return void
*/
public function synchronize()
{
if ( static::$lastUpdates === NULL )
{
static::$lastUpdates = iterator_to_array( \IPS\Db::i()->select( '*', 'core_dev' )->setKeyField('app_key') );
}
/* Get versions */
$versions = array_keys( json_decode( file_get_contents( \IPS\ROOT_PATH . "/applications/{$this->app->directory}/data/versions.json" ), TRUE ) );
$latestVersion = array_pop( $versions );
$updated = FALSE;
/* A brand new app won't have a latest version */
if( $latestVersion )
{
/* If we don't have a record for this app, assume we're up to date */
if ( !isset( static::$lastUpdates[ $this->app->directory ] ) )
{
$content = NULL;
if( file_exists( \IPS\ROOT_PATH . "/applications/{$this->app->directory}/setup/upg_{$latestVersion}/queries.json" ) )
{
$content = file_get_contents( \IPS\ROOT_PATH . "/applications/{$this->app->directory}/setup/upg_{$latestVersion}/queries.json" );
}
/opt/forum/system/Developer/Developer.php
*/
protected static $devDirs = array( 'css', 'email', 'html', 'img', 'js' );
/**
* @brief Array of multitons
*/
protected static $multitons = array();
/**
* Synchronises development data between installations
*
* @return void
*/
public static function sync()
{
$updated = FALSE;
foreach ( \IPS\Application::applications() as $app )
{
$thisAppUpdated = static::load( $app->directory )->synchronize();
$updated = $updated ?: $thisAppUpdated;
}
if( $updated )
{
\IPS\Plugin\Hook::writeDataFile();
/* Update JS cache bust */
\IPS\Settings::i()->changeValues( array( 'javascript_updated' => time() ) );
}
}
/**
* Stores objects
*
* @param string $app Application key
* @return object \IPS\Developer
*/
public static function load( $app )
{
/opt/forum/system/Dispatcher/Front.php
header( "Retry-After: 300"); #5 minutes
}
/* show the default upgrading page if the custom one doesn#t exist */
if ( !file_exists( \IPS\ROOT_PATH . '/' . \IPS\UPGRADING_PAGE ) )
{
$path = ( \defined( 'CP_DIRECTORY' ) ) ? CP_DIRECTORY . '/upgrade/upgrading.html' : 'admin/upgrade/upgrading.html';
require \IPS\ROOT_PATH . '/' . $path;
}
else
{
require \IPS\ROOT_PATH . '/' . \IPS\UPGRADING_PAGE;
}
exit;
}
/* Sync stuff when in developer mode */
if ( \IPS\IN_DEV )
{
\IPS\Developer::sync();
}
/* Base CSS */
static::baseCss();
/* Base JS */
static::baseJs();
/* Perform some legacy URL conversions - Need to do this before checking furl in case app name has changed */
static::convertLegacyParameters();
/* Get the current page, if any */
if ( isset( Request::i()->page ) and is_numeric( Request::i()->page ) )
{
$this->currentPage = \IPS\Request::i()->page;
}
else if ( isset( Request::i()->url()->hiddenQueryString['page'] ) and is_numeric( Request::i()->url()->hiddenQueryString['page'] ) and $page = Request::i()->url()->hiddenQueryString['page'] )
{
$this->currentPage = $page;
}
/tmp/IpRateLimiter_dispatcher_front.phpHUr8lM
"Rate limited IP: $ip\n" .
"User Agent: " . (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'none') . "\n" .
"URL: " . \IPS\Request::i()->url(),
\ENT_DISALLOWED | \ENT_QUOTES
),
'rate_limit'
);
}
}
} catch (\Exception $e) {
// Fail gracefully
\IPS\Log::log($e, 'rate_limit_error');
} finally {
if (isset($redis)) {
$redis->close();
}
}
}
parent::init();
}
/**
* Display ban page and exit
*/
protected static function ipRateLimitBanPage() {
// Oh dear
http_response_code(429); // Too many requests
include(\IPS\ROOT_PATH . '/rate_limited.html');
exit;
}
}
/tmp/DispatcherFront.phpBRJCTN
<?php namespace IPS\Dispatcher; //<?php class lmgsys_hook_dispatcher_front extends \IPS\Dispatcher\Front {}
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
exit;
}
class selfservice_hook_DispatcherFront extends lmgsys_hook_dispatcher_front {
public function init() {
parent::init();
if (
($deletion = \IPS\selfservice\AccountDeletion\PendingDeletion::loadActiveForMember(\IPS\Member::loggedIn()))
&& !($this->application->directory === 'selfservice' && $this->module->key === 'accountdeletion' && $this->controller === 'deletion')
&& !($this->application->directory === 'core' && \in_array($this->controller, ['contact', 'privacy', 'guidelines', 'login']))) {
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimalNoHome';
\IPS\Output::i()->sidebar['enabled'] = false;
\IPS\Output::i()->sendOutput(
\IPS\Theme::i()->getTemplate('global', 'core')->globalTemplate(
\IPS\Member::loggedIn()->language()->addToStack('selfservice_deletion_pending_title'),
\IPS\Theme::i()->getTemplate('deletion', 'selfservice', 'front')
->queuedForDeletion(\IPS\Http\Url::internal(
'app=selfservice&module=accountdeletion&controller=deletion&do=cancel')
->setQueryString('id', $deletion->id)
->csrf())),
403);
}
}
}
/tmp/DispatcherFront.phpum3sJX
<?php namespace IPS\Dispatcher; //<?php
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
exit;
}
class hook1399 extends selfservice_hook_DispatcherFront // \IPS\Dispatcher\Front
{
public function init() {
parent::init();
if (
isset(\IPS\Request::i()->fromNotification) &&
\IPS\Login::compareHashes(
hash_hmac("sha256", \IPS\Request::i()->fromNotification, \IPS\Settings::i()->site_secret_key . 'notification'),
\IPS\Request::i()->notificationToken) &&
\IPS\Member::loggedIn()->member_id) {
\IPS\Db::i()->update(
'core_notifications',
array('read_time' => time()),
array('`member`=? AND id=?', \IPS\Member::loggedIn()->member_id, \IPS\Request::i()->fromNotification));
\IPS\Member::loggedIn()->recountNotifications();
}
}
}
/opt/forum/system/Dispatcher/Dispatcher.php
}
}
}
if( $_redirect === TRUE )
{
/* conf_global.php does not exist, forward to installer - we'll do this manually to avoid any code in Output.php that anticipates the installation already being complete (such as setting CSP header in __construct()) */
$url = ( \IPS\Request::i()->isSecure() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . rtrim( \dirname( $_SERVER['SCRIPT_NAME'] ), '/' );
header( "HTTP/1.1 307 Temporary Redirect" );
foreach( \IPS\Output::getNoCacheHeaders() as $headerKey => $headerValue )
{
header( "{$headerKey}: {$headerValue}" );
}
header( "Location: {$url}/" . \IPS\CP_DIRECTORY . "/install/" );
exit;
}
}
static::$instance->init();
}
return static::$instance;
}
/**
* @brief Controller Classname
*/
protected $classname;
/**
* @brief Controller instance
*/
public $dispatcherController;
/**
* Init
*
* @return void
* @throws \DomainException
/opt/forum/index.php
<?php
/**
* @brief Public bootstrap
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 18 Feb 2013
*/
\define('REPORT_EXCEPTIONS', TRUE);
$_SERVER['SCRIPT_FILENAME'] = __FILE__;
require_once 'init.php';
\IPS\Dispatcher\Front::i()->run();