Version 4.0.13.1

This commit is contained in:
Neo committed 2025-12-19 04:57:54 -08:00
1 parent f9e857d255
commit c6a86f0d9b
7517 files changed
+597400 -668041

No files matched your search

@@ -0,0 +1,243 @@
<?php
/**
* @brief AJAX actions
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 04 Apr 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* AJAX actions
*/
class _ajax extends \IPS\Dispatcher\Controller
{
/**
* Find Member
*
* @retun void
*/
public function findMember()
{
$results = array();
$input = mb_strtolower( \IPS\Request::i()->input );
$where = array( "name LIKE CONCAT('%', ?, '%')" );
$binds = array( $input );
if ( \IPS\Dispatcher::i()->controllerLocation === 'admin' )
{
$where[] = "email LIKE CONCAT('%', ?, '%')";
$binds[] = $input;
if ( is_numeric( \IPS\Request::i()->input ) )
{
$where[] = "member_id=?";
$binds[] = intval( \IPS\Request::i()->input );
}
}
/* Build the array item for this member after constructing a record */
/* The value should be just the name so that it's inserted into the input properly, but for display, we wrap it in the group *fix */
foreach ( \IPS\Db::i()->select( '*', 'core_members', array_merge( array( implode( ' OR ', $where ) ), $binds ), 'LENGTH(name) ASC', array( 0, 20 ) ) as $row )
{
$member = \IPS\Member::constructFromData( $row );
$results[] = array(
'id' => $member->member_id,
'value' => $member->name,
'name' => \IPS\Dispatcher::i()->controllerLocation == 'admin' ? $member->group['prefix'] . htmlentities( $member->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . $member->group['suffix'] : htmlentities( $member->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'extra' => \IPS\Dispatcher::i()->controllerLocation == 'admin' ? $member->email : $member->groupName,
'photo' => (string) $member->photo,
);
}
\IPS\Output::i()->json( $results );
}
/**
* Returns boolean in json indicating whether the supplied username already exists
*
* @return void
*/
public function usernameExists()
{
$result = array( 'result' => 'ok' );
/* The value comes urlencoded so we need to decode so length is correct (and not using a percent-encoded value) */
$name = urldecode( \IPS\Request::i()->input );
/* Check is valid */
if ( !$name )
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('form_required') );
}
elseif ( mb_strlen( $name ) > \IPS\Settings::i()->max_user_name_length )
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack( 'form_maxlength', FALSE, array( 'pluralize' => array( \IPS\Settings::i()->max_user_name_length ) ) ) );
}
elseif ( \IPS\Settings::i()->username_characters and !preg_match( '/^[' . str_replace( '\-', '-', preg_quote( \IPS\Settings::i()->username_characters, '/' ) ) . ']*$/i', $name ) )
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('form_bad_value') );
}
/* Check if it exists */
else
{
foreach ( \IPS\Login::handlers( TRUE ) as $k => $handler )
{
if ( $handler->usernameIsInUse( $name ) === TRUE )
{
if ( \IPS\Member::loggedIn()->isAdmin() )
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('member_name_exists_admin', FALSE, array( 'sprintf' => array( $k ) ) ) );
}
else
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('member_name_exists') );
}
}
}
}
/* Check it's not banned */
if ( $result == array( 'result' => 'ok' ) )
{
foreach( \IPS\Db::i()->select( 'ban_content', 'core_banfilters', array("ban_type=?", 'name') ) as $bannedName )
{
if( preg_match( '/^' . str_replace( '\*', '.*', preg_quote( $bannedName, '/' ) ) . '$/i', $name ) )
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('form_name_banned') );
}
}
}
\IPS\Output::i()->json( $result );
}
/**
* Returns boolean in json indicating whether the supplied email already exists
*
* @return void
*/
public function emailExists()
{
$result = array( 'result' => 'ok' );
/* The value comes urlencoded so we need to decode so length is correct (and not using a percent-encoded value) */
$email = urldecode( \IPS\Request::i()->input );
/* Check is valid */
if ( !$email )
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('form_required') );
}
elseif ( filter_var( $email, FILTER_VALIDATE_EMAIL ) === FALSE )
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('form_bad_value') );
}
/* Check if it exists */
else
{
foreach ( \IPS\Login::handlers( TRUE ) as $k => $handler )
{
if ( $handler->emailIsInUse( $email ) === TRUE )
{
if ( \IPS\Member::loggedIn()->isAdmin() )
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('member_email_exists_admin', FALSE, array( 'sprintf' => array( $k ) ) ) );
}
else
{
$result = array( 'result' => 'fail', 'message' => \IPS\Member::loggedIn()->language()->addToStack('member_email_exists') );
}
}
}
}
\IPS\Output::i()->json( $result );
}
/**
* Get state/region list for country
*
* @return void
*/
public function states()
{
$states = array();
if ( array_key_exists( \IPS\Request::i()->country, \IPS\GeoLocation::$states ) )
{
$states = \IPS\GeoLocation::$states[ \IPS\Request::i()->country ];
}
\IPS\Output::i()->json( $states );
}
/**
* Top Contributors
*
* @retun void
*/
public function topContributors()
{
/* How many? */
$limit = intval( ( isset( \IPS\Request::i()->limit ) and \IPS\Request::i()->limit < 20 ) ? \IPS\Request::i()->limit : 5 );
/* What timeframe? */
$where = array( array( 'member_received > 0' ) );
$timeframe = 'all';
if ( isset( \IPS\Request::i()->time ) and \IPS\Request::i()->time != 'all' )
{
switch ( \IPS\Request::i()->time )
{
case 'week':
$where[] = array( 'rep_date>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1W' ) )->getTimestamp() );
$timeframe = 'week';
break;
case 'month':
$where[] = array( 'rep_date>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) )->getTimestamp() );
$timeframe = 'month';
break;
case 'year':
$where[] = array( 'rep_date>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1Y' ) )->getTimestamp() );
$timeframe = 'year';
break;
}
$topContributors = iterator_to_array( \IPS\Db::i()->select( 'core_reputation_index.member_received as member, SUM(rep_rating) as rep', 'core_reputation_index', $where, 'rep DESC', $limit, 'member' )->setKeyField('member')->setValueField('rep') );
}
else
{
$topContributors = iterator_to_array( \IPS\Db::i()->select( 'member_id as member, pp_reputation_points as rep', 'core_members', array( 'pp_reputation_points > 0' ), 'rep DESC', $limit )->setKeyField('member')->setValueField('rep') );
}
/* Load their data */
foreach ( \IPS\Db::i()->select( '*', 'core_members', \IPS\Db::i()->in( 'member_id', array_keys( $topContributors ) ) ) as $member )
{
\IPS\Member::constructFromData( $member );
}
/* Render */
$output = \IPS\Theme::i()->getTemplate( 'widgets' )->topContributorRows( $topContributors, $timeframe, \IPS\Request::i()->orientation );
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->sendOutput( $output );
}
else
{
\IPS\Output::i()->output = $output;
}
}
}
@@ -0,0 +1,56 @@
<?php
/**
* @brief Announcement
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 09 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Announcement
*/
class _announcement extends \IPS\Content\Controller
{
/**
* [Content\Controller] Class
*/
protected static $contentModel = 'IPS\core\Announcements\Announcement';
/**
* View Announcement
*
* @return void
*/
protected function manage()
{
parent::manage();
/* Load announcement */
try
{
$announcement = \IPS\core\Announcements\Announcement::load( \IPS\Request::i()->id );
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'announcement_missing', '2C199/1', 404, '' );
}
/* Set Session Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=announcement&id=' . $announcement->id, NULL, 'announcement', $announcement->seo_title ), array(), 'loc_viewing_announcement', array( $announcement->title => FALSE ) );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( $announcement->title );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->announcement( $announcement );
}
}
@@ -0,0 +1,157 @@
<?php
/**
* @brief My Attachments Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 22 Jul 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* My Attachments Controller
*/
class _attachments extends \IPS\Dispatcher\Controller
{
/**
* Manage
*
* @return void
*/
public function manage()
{
/* Logged in and can upload only */
if ( !\IPS\Member::loggedIn()->member_id or \IPS\Member::loggedIn()->group['g_attach_max'] == 0 )
{
\IPS\Output::i()->error( 'no_module_permission', '2C229/1', 403, '' );
}
/* Build Table */
$table = new \IPS\Helpers\Table\Db( 'core_attachments', \IPS\Http\Url::internal( 'app=core&module=system&controller=attachments', 'front', 'attachments' ), array( array( 'attach_member_id=?', \IPS\Member::loggedIn()->member_id ) ) );
$table->include = array( 'attach_id', 'attach_location', 'attach_date', 'attach_file', 'attach_filesize', 'attach_is_image', 'attach_content', 'attach_hits' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate('myAttachments'), 'rows' );
$table->joins = array();
/* Sort */
$table->sortOptions = array( 'attach_date' => 'attach_date', 'attach_file' => 'attach_file', 'attach_filesize' => 'attach_filesize' );
$table->sortBy = $table->sortBy ?: 'attach_date';
if ( $table->sortBy === 'attach_file' )
{
$table->sortDirection = 'asc';
}
$table->filters = array( 'images' => array( 'attach_is_image=1' ), 'files' => array( 'attach_is_image=0' ) );
/* Get the associated content */
$self = $this;
$table->parsers = array( 'attach_content' => function( $val, $row ) use ( $self )
{
return \IPS\core\extensions\core\EditorMedia\Attachment::getLocations( $row['attach_id'] );
} );
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('my_attachments');
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('my_attachments') );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('myAttachments')->template( (string) $table, \IPS\Db::i()->select( 'SUM(attach_filesize)', 'core_attachments', array( 'attach_member_id=?', \IPS\Member::loggedIn()->member_id ) )->first(), \IPS\Db::i()->select( 'COUNT(*)', 'core_attachments', array( 'attach_member_id=?', \IPS\Member::loggedIn()->member_id ) )->first() );
}
/**
* Lookup
*
* @return void
*/
public function lookup()
{
/* Load and check permission */
try
{
$attachment = \IPS\Db::i()->select( '*', 'core_attachments', array( 'attach_id=?', \IPS\Request::i()->id ) )->first();
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->error( 'node_error', '2C229/6', 404, '' );
}
/* Check it belongs to us */
if ( $attachment['attach_member_id'] !== \IPS\Member::loggedIn()->member_id or !\IPS\Member::loggedIn()->group['gbw_delete_attachments'] )
{
\IPS\Output::i()->error( 'no_module_permission', '2C229/7', 403, '' );
}
/* Display */
\IPS\Output::i()->title = $attachment['attach_file'];
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=core&module=system&controller=attachments', 'front', 'attachments' ), \IPS\Member::loggedIn()->language()->addToStack('my_attachments') );
\IPS\Output::i()->breadcrumb[] = array( NULL, $attachment['attach_file'] );
\IPS\Output::i()->output = $this->_getLocations( $attachment['attach_id'] );
}
/**
* Delete
*
* @return void
*/
public function delete()
{
/* Security check */
\IPS\Session::i()->csrfCheck();
/* Load and check permission */
try
{
$attachment = \IPS\Db::i()->select( '*', 'core_attachments', array( 'attach_id=?', \IPS\Request::i()->id ) )->first();
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->error( 'node_error', '2C229/4', 404, '' );
}
/* Check it belongs to us */
if ( $attachment['attach_member_id'] !== \IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'no_module_permission', '2C229/5', 403, '' );
}
/* And we can delete it */
if ( !\IPS\Member::loggedIn()->group['gbw_delete_attachments'] )
{
\IPS\core\extensions\core\EditorMedia\Attachment::getLocations( $attachment['attach_id'] );
if ( count( \IPS\core\extensions\core\EditorMedia\Attachment::$locations[ $attachment['attach_id'] ] ) )
{
\IPS\Output::i()->error( 'no_module_permission', '2C229/8', 403, '' );
}
}
/* Delete */
try
{
\IPS\File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
if ( $attachment['attach_thumb_location'] )
{
\IPS\File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
}
}
catch ( \Exception $e ) { }
\IPS\Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
\IPS\Db::i()->delete( 'core_attachments_map', array( 'attachment_id=?', $attachment['attach_id'] ) );
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( 'OK' );
}
else
{
/* Redirect */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=attachments', 'front', 'attachments' ) );
}
}
}
@@ -0,0 +1,68 @@
<?php
/**
* @brief "Content" functions Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 29 Apr 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* "Content" functions Controller
*/
class _content extends \IPS\Dispatcher\Controller
{
/**
* Find content
*
* @return void
*/
protected function find()
{
if ( ! \IPS\Request::i()->content_class AND ! \IPS\Request::i()->content_id AND ! \IPS\Request::i()->content_commentid )
{
\IPS\Output::i()->error( 'node_error', '2S226/1', 404, '' );
}
$class = 'IPS\\' . implode( '\\', explode( '_', \IPS\Request::i()->content_class ) );
if ( ! class_exists( $class ) or ! in_array( 'IPS\Content', class_parents( $class ) ) )
{
\IPS\Output::i()->error( 'node_error', '2S226/2', 404, '' );
}
try
{
$item = $class::load( \IPS\Request::i()->content_id );
$commentClass = $class::$commentClass;
$comment = $commentClass::load( \IPS\Request::i()->content_commentid );
}
catch( \OutOfRangeException $ex )
{
\IPS\Output::i()->error( 'node_error', '2S226/3', 404, '' );
}
/* Make sure we have permission to see this */
if ( ( $comment->item()->tid == $item->tid ) AND $item->canView() AND $comment->canView() )
{
\IPS\Output::i()->redirect( $comment->url() );
}
else
{
\IPS\Output::i()->error( 'node_error', '2S226/4', 404, '' );
}
}
}
@@ -0,0 +1,35 @@
<?php
/**
* @brief Designer mode controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 07 Aug 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Redirect
*/
class _designermode extends \IPS\Dispatcher\Controller
{
/**
* Something is wrong
*
* @return void
*/
protected function missing()
{
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'theme_designers_mode_error_missing', FALSE, array( 'sprintf' => array( \IPS\Request::i()->id ) ) ), "DESMODE", 500 );
}
}
@@ -0,0 +1,265 @@
<?php
/**
* @brief Editor AJAX functions Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 29 Apr 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor AJAX functions Controller
*/
class _editor extends \IPS\Dispatcher\Controller
{
/**
* Link Dialog
*
* @return void
*/
protected function link()
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->link( \IPS\Request::i()->current, \IPS\Request::i()->editorId );
}
/**
* Image Dialog
*
* @return void
*/
protected function image()
{
$maxImageDims = \IPS\Settings::i()->attachment_image_size ? explode( 'x', \IPS\Settings::i()->attachment_image_size ) : array( 1000, 750 );
$maxWidth = ( \IPS\Request::i()->actualWidth < $maxImageDims[0] ) ? \IPS\Request::i()->actualWidth : $maxImageDims[0];
$maxHeight = ( \IPS\Request::i()->actualHeight < $maxImageDims[1] ) ? \IPS\Request::i()->actualHeight : $maxImageDims[1];
if ( \IPS\Request::i()->width > $maxWidth )
{
$ratio = \IPS\Request::i()->height / \IPS\Request::i()->width;
\IPS\Request::i()->width = $maxWidth;
\IPS\Request::i()->height = floor( \IPS\Request::i()->width * $ratio );
}
if ( \IPS\Request::i()->height > $maxHeight )
{
$ratio = \IPS\Request::i()->height / \IPS\Request::i()->width;
\IPS\Request::i()->height = $maxHeight;
\IPS\Request::i()->width = floor( \IPS\Request::i()->height * $ratio );
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->image( \IPS\Request::i()->editorId, \IPS\Request::i()->width, \IPS\Request::i()->height, $maxWidth, $maxHeight, \IPS\Request::i()->border, \IPS\Request::i()->margin, \IPS\Request::i()->float, \IPS\Request::i()->link );
}
/**
* AJAX validate link
*
* @return void
*/
protected function validateLink()
{
try
{
$title = NULL;
$isEmbed = FALSE;
$url = \IPS\Request::i()->url;
if ( !\IPS\Request::i()->noEmbed and !\IPS\Request::i()->image and $embed = \IPS\Text\Parser::embeddableMedia( $url ) )
{
$insert = $embed;
$isEmbed = TRUE;
}
else
{
$response = \IPS\Http\Url::external( $url )->request()->get();
if ( \IPS\Request::i()->image and isset( $response->httpHeaders['Content-Type'] ) and mb_substr( $response->httpHeaders['Content-Type'], 0, 6 ) === 'image/' )
{
$insert = "<img src='{$url}' class='ipsImage'>";
}
else
{
if ( \IPS\Request::i()->image )
{
throw new \DomainException;
}
if ( \IPS\Request::i()->title )
{
$title = \IPS\Request::i()->title;
}
elseif ( isset( $response->httpHeaders['Content-Type'] ) and mb_substr( $response->httpHeaders['Content-Type'], 0, 9 ) === 'text/html' and preg_match( '/<title>(.+)<\/title>/', $response, $matches ) and isset( $matches[1] ) )
{
$title = $matches[1];
}
else
{
$title = $url;
}
$insert = "<a href='{$url}' ipsNoEmbed='true'>{$title}</a>";
}
}
\IPS\Output::i()->json( array( 'preview' => trim( $insert ), 'title' => $title, 'embed' => $isEmbed ) );
}
catch ( \Exception $e )
{
\IPS\Output::i()->json( $e->getMessage(), 500 );
}
}
/**
* Get Emoticons Configuration
*
* @return void
*/
protected function emoticons()
{
$emoticons = array();
foreach ( \IPS\Db::i()->select( '*', 'core_emoticons', NULL, 'emo_set_position,emo_position' ) as $row )
{
if ( !isset( $emoticons[ $row['emo_set'] ] ) )
{
$setLang = 'core_emoticon_group_' . $row['emo_set'];
$emoticons[ $row['emo_set'] ] = array(
'title' => \IPS\Member::loggedIn()->language()->addToStack( $setLang ),
'total' => 0,
'emoticons' => array(),
);
}
$emoticons[ $row['emo_set'] ]['emoticons'][] = array(
'src' => \IPS\File::get( 'core_Emoticons', $row['image'] )->url,
'text' => $row['typed']
);
}
foreach ( $emoticons as $set => $data )
{
$emoticons[ $set ]['total'] = count( $data['emoticons'] );
}
\IPS\Output::i()->json( $emoticons );
}
/**
* My Media
*
* @return void
*/
protected function myMedia()
{
/* Init */
$perPage = 7;
$search = isset( \IPS\Request::i()->search ) ? \IPS\Request::i()->search : null;
/* Get all our available sources */
$mediaSources = array();
foreach ( \IPS\Application::allExtensions( 'core', 'EditorMedia' ) as $k => $class )
{
if ( $class->count( \IPS\Member::loggedIn(), isset( \IPS\Request::i()->postKey ) ? \IPS\Request::i()->postKey : '' ) )
{
$mediaSources[] = $k;
}
}
/* Work out what tab we're on */
if ( !\IPS\Request::i()->tab )
{
if( !count( $mediaSources ) )
{
\IPS\Output::i()->error( 'no_module_permission', '2C270/1', 403, '' );
}
$sources = $mediaSources;
\IPS\Request::i()->tab = array_shift( $sources );
}
$exploded = explode( '_', \IPS\Request::i()->tab );
$classname = "IPS\\{$exploded[0]}\\extensions\\core\\EditorMedia\\{$exploded[1]}";
$extension = new $classname;
$url = \IPS\Http\Url::internal( "app=core&module=system&controller=editor&do=myMedia&tab=" . \IPS\Request::i()->tab . "&key=" . \IPS\Request::i()->key . "&postKey=" . \IPS\Request::i()->postKey . "&existing=1" );
/* Count how many we have */
$count = $extension->count( \IPS\Member::loggedIn(), isset( \IPS\Request::i()->postKey ) ? \IPS\Request::i()->postKey : '', $search );
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
/* Display */
if ( isset( \IPS\Request::i()->existing ) )
{
if ( isset( \IPS\Request::i()->search ) || ( isset( \IPS\Request::i()->page ) && \IPS\Request::i()->page !== 1 ) )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->myMediaResults(
$extension->get( \IPS\Member::loggedIn(), $search, isset( \IPS\Request::i()->postKey ) ? \IPS\Request::i()->postKey : '', $page, $perPage ),
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
$url,
ceil( $count / $perPage ),
$page,
$perPage
),
$url,
\IPS\Request::i()->tab
);
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->myMediaContent(
$extension->get( \IPS\Member::loggedIn(), $search, isset( \IPS\Request::i()->postKey ) ? \IPS\Request::i()->postKey : '', $page, $perPage ),
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
$url,
ceil( $count / $perPage ),
$page,
$perPage
),
$url,
\IPS\Request::i()->tab
);
}
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->myMedia( \IPS\Request::i()->editorId, $mediaSources, \IPS\Request::i()->tab, $url, \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->myMediaContent(
$extension->get( \IPS\Member::loggedIn(), $search, isset( \IPS\Request::i()->postKey ) ? \IPS\Request::i()->postKey : '', $page, $perPage ),
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
$url,
ceil( $count / $perPage ),
$page,
$perPage
),
$url,
\IPS\Request::i()->tab
) );
}
}
/**
* Mentions
*
* @return void
*/
protected function mention()
{
$results = '';
foreach ( \IPS\Db::i()->select( '*', 'core_members', array( "name LIKE CONCAT( ?, '%' )", mb_strtolower( \IPS\Request::i()->input ) ), 'name', 10 ) as $row )
{
$results .= \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->mentionRow( \IPS\Member::constructFromData( $row ) );
}
\IPS\Output::i()->sendOutput( $results );
}
}
@@ -0,0 +1,35 @@
<?php
/**
* @brief Embed iframe display
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 15 Sep 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Embed iframe display
*/
class _embed extends \IPS\Content\Controller
{
/**
* Embed iframe display
*
* @return void
*/
protected function manage()
{
\IPS\Output::i()->sendOutput( \IPS\Text\Parser::embeddableMedia( \IPS\Request::i()->url, TRUE ), 200 );
}
}
@@ -0,0 +1,118 @@
<?php
/**
* @brief My followed content
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 16 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* My followed content
*/
class _followed extends \IPS\Dispatcher\Controller
{
/**
* My followed content
*
* @return void
*/
protected function manage()
{
/* Guests can't follow things */
if( !\IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'no_module_permission_guest', '2C266/1', 403, '' );
}
/* Get the different types */
$types = array();
/* Don't forget Members */
$types['core'] = array( 'core_member' => "\IPS\Member" );
foreach ( \IPS\Content::routedClasses( TRUE, FALSE, TRUE ) as $class )
{
if( is_subclass_of( $class, 'IPS\Content\Followable' ) )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) ) ] = $class;
if ( isset( $class::$containerNodeClass ) )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$containerNodeClass, 4 ) ) ) ] = $class::$containerNodeClass;
}
if ( isset( $class::$containerFollowClasses ) )
{
foreach( $class::$containerFollowClasses as $followClass )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $followClass, 4 ) ) ) ] = $followClass;
}
}
}
}
/* What type are we looking at? */
$currentAppModule = NULL;
$currentType = NULL;
if ( isset( \IPS\Request::i()->type ) )
{
foreach ( $types as $appModule => $_types )
{
if ( array_key_exists( \IPS\Request::i()->type, $_types ) )
{
$currentAppModule = $appModule;
$currentType = \IPS\Request::i()->type;
break;
}
}
}
if ( $currentType === NULL )
{
foreach ( $types as $appModule => $_types )
{
foreach ( $_types as $key => $class )
{
if ( $key == 'core_member' )
{
continue;
}
$currentAppModule = $appModule;
$currentType = $key;
break 2;
}
}
}
$currentClass = $types[ $currentAppModule ][ $currentType ];
$output = new \IPS\core\Followed\Table( $currentClass, explode( '_', $currentType ) );
/* If we've clicked from the tab section */
if ( \IPS\Request::i()->isAjax() && \IPS\Request::i()->change_section )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->followedContentSection( $types, $currentAppModule, $currentType, $output );
}
else
{
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('my_followed_content');
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('my_followed_content') );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->followedContent( $types, $currentAppModule, $currentType, $output );
}
}
}
@@ -0,0 +1,45 @@
<?php
/**
* @brief Guidelines
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 02 Sept 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Guidelines
*/
class _guidelines extends \IPS\Dispatcher\Controller
{
/**
* Guidelines
*
* @return void
*/
protected function manage()
{
if ( \IPS\Settings::i()->gl_type == "none" )
{
\IPS\Output::i()->error( 'node_error', '', 404 ); /* @todo Error code */
}
/* Set Session Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=guidelines', NULL, 'guidelines' ), array(), 'loc_viewing_guidelines' );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('guidelines') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('guidelines');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->guidelines( \IPS\Settings::i()->gl_guidelines );
}
}
@@ -0,0 +1,360 @@
<?php
/**
* @brief Ignore Preferences
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 20 Aug 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Ignore Preferences
*/
class _ignore extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
if ( !\IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'no_module_permission_guest', '2C146/1', 403, '' );
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_ignore.js', 'core' ) );
parent::execute();
}
/**
* Manage
*
* @return void
*/
protected function manage()
{
$url = \IPS\Http\Url::internal( "app=core&module=system&controller=ignore", 'front', 'ignore' );
/* Build form */
$form = \IPS\core\Ignore::form();
if ( $values = $form->values() )
{
\IPS\Session::i()->csrfCheck();
try
{
\IPS\core\Ignore::createFromForm( $values );
}
catch( \InvalidArgumentException $e )
{
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'error' => \IPS\Member::loggedIn()->language()->addToStack( 'cannot_ignore_self' ) ), 403 );
}
else
{
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( $e->getMessage() ), '1C146/2', 403, '' );
}
}
if ( \IPS\Request::i()->isAjax() )
{
$data = array();
foreach( \IPS\core\Ignore::types() AS $type )
{
if ( $values["ignore_{$type}"] )
{
$data["ignore_{$type}"] = 1;
}
}
\IPS\Output::i()->json( array( 'name' => $values['member']->name, 'member_id' => $values['member']->member_id, 'data' => $data ) );
}
else
{
\IPS\Output::i()->redirect( $url );
}
}
/* Build table */
$table = new \IPS\Helpers\Table\Db( 'core_ignored_users', $url, array( array( 'ignore_owner_id=?', \IPS\Member::loggedIn()->member_id ) ) );
$table->title = 'ignored_users_current';
$table->langPrefix = 'ignore_';
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' ), 'ignoreTable' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'system' ), 'ignoreTableRows' );
$filters = array();
foreach ( \IPS\core\Ignore::types() as $type )
{
$filters[ $type ] = "ignore_{$type}=1";
}
$table->filters = $filters;
/* Display */
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('ignored_users') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('ignored_users');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->ignore( $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'system' ), 'ignoreForm' ) ), (string) $table );
}
/**
* Add new ignored user
*
* @return void
*/
protected function add()
{
\IPS\Session::i()->csrfCheck();
try
{
$member = \IPS\Member::load( \IPS\Request::i()->name, 'name' );
/* If \IPS\Member::load() cannot find a member, it just creates a new guest object, never throwing the exception */
if ( !$member->member_id )
{
throw new \OutOfRangeException( 'user_does_not_exist' );
}
if ( $member->member_id == \IPS\Member::loggedIn()->member_id )
{
throw new \InvalidArgumentException( 'cannot_ignore_self' );
}
if ( $member->group['gbw_cannot_be_ignored'] )
{
throw new \InvalidArgumentException( 'cannot_ignore_that_member' );
}
$ignore = NULL;
try
{
$ignore = \IPS\core\Ignore::load( $member->member_id, 'ignore_ignore_id', array( 'ignore_owner_id=?', \IPS\Member::loggedIn()->member_id ) );
}
catch ( \OutOfRangeException $e ) {}
$data = array();
foreach ( \IPS\core\Ignore::types() as $t )
{
$data[ $t ] = $ignore ? $ignore->$t : FALSE;
}
\IPS\Output::i()->json( $data );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->json( $e->getMessage(), 404 );
}
catch( \InvalidArgumentException $e )
{
\IPS\Output::i()->json( array( 'error' => \IPS\Member::loggedIn()->language()->addToStack( $e->getMessage() ) ), 403 );
}
}
/**
* Edit
*
* @return void
*/
protected function edit()
{
try
{
$member = \IPS\Member::load( \IPS\Request::i()->id );
/* If \IPS\Member::load() cannot find a member, it just creates a new guest object, never throwing the exception */
if ( !$member->member_id )
{
throw new \OutOfRangeException( 'user_does_not_exist' );
}
if ( $member->member_id == \IPS\Member::loggedIn()->member_id )
{
throw new \InvalidArgumentException( 'cannot_ignore_self' );
}
if ( $member->group['gbw_cannot_be_ignored'] )
{
throw new \InvalidArgumentException( 'cannot_ignore_that_member' );
}
$ignore = NULL;
try
{
$ignore = \IPS\core\Ignore::load( $member->member_id, 'ignore_ignore_id', array( 'ignore_owner_id=?', \IPS\Member::loggedIn()->member_id ) );
}
catch ( \OutOfRangeException $e ) {}
$form = new \IPS\Helpers\Form( NULL, 'ignore_edit' );
$form->class = 'ipsForm_vertical';
foreach ( \IPS\core\Ignore::types() as $type )
{
$form->add( new \IPS\Helpers\Form\Checkbox( "ignore_{$type}", $ignore ? $ignore->$type : FALSE ) );
}
/* Save values */
if( $values = $form->values() )
{
foreach ( \IPS\core\Ignore::types() as $type )
{
$ignore->$type = $values["ignore_{$type}"];
}
$ignore->save();
if( !\IPS\Request::i()->isAjax() )
{
$this->manage();
}
else
{
\IPS\Output::i()->json( 'OK' );
}
}
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('ignored_users') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('add_ignored_user');
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'system' ), 'ignoreEditForm' ) );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->json( $e->getMessage(), 404 );
}
catch( \InvalidArgumentException $e )
{
\IPS\Output::i()->json( \IPS\Member::loggedIn()->language()->addToStack( $e->getMessage() ), 403 );
}
}
/**
* Remove (AJAX)
*
* @return void
*/
protected function remove()
{
\IPS\Session::i()->csrfCheck();
try
{
$member = \IPS\Member::load( \IPS\Request::i()->id );
/* If \IPS\Member::load() cannot find a member, it just creates a new guest object, never throwing the exception */
if ( !$member->member_id )
{
throw new \OutOfRangeException;
}
$ignore = \IPS\core\Ignore::load( $member->member_id, 'ignore_ignore_id', array( 'ignore_owner_id=?', \IPS\Member::loggedIn()->member_id ) );
$ignore->delete();
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'results' => 'ok', 'name' => $member->name ) );
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=ignore", 'front', 'ignore' ), \IPS\Member::loggedIn()->language()->addToStack( 'ignore_removed', FALSE, array( 'sprintf' => array( $member->name ) ) ) );
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C146/5', 404, '' );
}
}
/**
* Ignore Specific Content Type (AJAX)
*
* @return void
*/
protected function ignoreType()
{
try
{
if ( !in_array( \IPS\Request::i()->type, \IPS\core\Ignore::types() ) )
{
throw new \OutOfRangeException( 'invalid_type' );
}
$member = \IPS\Member::load( \IPS\Request::i()->member_id );
if ( !$member->member_id )
{
throw new \OutOfRangeException( 'user_does_not_exist' );
}
if ( $member->member_id == \IPS\Member::loggedIn()->member_id )
{
throw new \InvalidArgumentException( 'cannot_ignore_self' );
}
if ( $member->group['gbw_cannot_be_ignored'] )
{
throw new \InvalidArgumentException( 'cannot_ignore_that_member' );
}
$type = \IPS\Request::i()->type;
$value = isset( \IPS\Request::i()->off ) ? FALSE : TRUE;
try
{
$ignore = \IPS\core\Ignore::load( $member->member_id, 'ignore_ignore_id', array( 'ignore_owner_id=?', \IPS\Member::loggedIn()->member_id ) );
$ignore->$type = $value;
$ignore->save();
}
catch( \OutOfRangeException $e )
{
$ignore = new \IPS\core\Ignore;
$ignore->$type = $value;
$ignore->owner_id = \IPS\Member::loggedIn()->member_id;
$ignore->ignore_id = $member->member_id;
$ignore->save();
}
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'result' => 'ok' ) );
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=ignore", 'front', 'ignore' ), 'ignore_adjusted' );
}
}
catch( \OutOfRangeException $e )
{
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'error' => 'user_does_not_exist' ), 404 );
}
else
{
\IPS\Output::i()->error( 'user_does_not_exist', '2C146/3', 404, '' );
}
}
catch( \InvalidArgumentException $e )
{
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'error' => $e->getMessage() ), 403 );
}
else
{
\IPS\Output::i()->error( $e->getMessage(), '1C146/4', 403, '' );
}
}
}
}
Whitespace-only changes.
@@ -0,0 +1,57 @@
<?php
/**
* @brief Language Changer
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 17 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Language Changer
*/
class _language extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
parent::execute();
}
/**
* Manage
*
* @return void
*/
protected function manage()
{
\IPS\Session::i()->csrfCheck();
if( \IPS\Member::loggedIn()->member_id )
{
\IPS\Member::loggedIn()->language = (int) \IPS\Request::i()->id;
\IPS\Member::loggedIn()->save();
}
else
{
\IPS\Request::i()->setCookie( 'language', (int) \IPS\Request::i()->id );
}
\IPS\Output::i()->redirect( ( !empty( $_SERVER['HTTP_REFERER'] ) ) ? \IPS\Http\Url::external( $_SERVER['HTTP_REFERER'] ) : \IPS\Http\Url::internal( '' ) );
}
}
@@ -0,0 +1,271 @@
<?php
/**
* @brief Login
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 7 Jun 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Login
*/
class _login extends \IPS\Dispatcher\Controller
{
/**
* Log In
*
* @return void
*/
protected function manage()
{
/* Did we just log in? */
if ( \IPS\Member::loggedIn()->member_id and isset( \IPS\Request::i()->_fromLogin ) )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('') );
}
/* Force HTTPs? */
if ( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' and \IPS\Settings::i()->logins_over_https and \IPS\Request::i()->url()->data['scheme'] !== 'https' )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) );
}
/* Init login class */
$login = new \IPS\Login( \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) );
/* Process */
$error = isset( \IPS\Request::i()->_err ) ? \IPS\Request::i()->_err : NULL;
try
{
$member = $login->authenticate();
if ( $member !== NULL )
{
$this->_doLogin( $member, $login->flags['signin_anonymous'], $login->flags['remember_me'] );
if ( \IPS\Request::i()->isAjax() )
{
$response = array( 'status' => 'success' );
if( !empty( \IPS\Request::i()->ref ) )
{
$response['redirect'] = \IPS\Request::i()->ref;
}
\IPS\Output::i()->json( $response );
}
else
{
\IPS\Output::i()->redirect( \IPS\Login::getDestination()->setQueryString( '_fromLogin', 1 ) );
}
}
}
catch ( \IPS\Login\Exception $e )
{
if ( $e->getCode() === \IPS\Login\Exception::MERGE_SOCIAL_ACCOUNT )
{
$e->member = $e->member->member_id;
$_SESSION['linkAccounts'] = json_encode( $e );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login&do=link', 'front', 'login' ) );
}
$error = $e->getMessage();
}
if ( \IPS\Request::i()->isAjax() && $error )
{
\IPS\Output::i()->json( array( 'status' => 'error', 'error' => $error ), 401 );
}
else
{
/* Display Login Form */
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('login');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->login( $login->forms(), $error );
}
/* Set Session Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', NULL, 'login' ), array(), 'loc_logging_in' );
}
/**
* Process the login
*
* @param \IPS\Member $member The member
* @param bool $anonymous If the login is anonymous
* @param bool $rememberMe If the "remember me" checkbox was checked
* @return void
*/
protected function _doLogin( $member, $anonymous=FALSE, $rememberMe=TRUE )
{
if ( $anonymous and !\IPS\Settings::i()->disable_anonymous )
{
\IPS\Session::i()->setAnon();
\IPS\Request::i()->setCookie( 'anon_login', 1 );
}
$member->checkLoginKey();
if ( $rememberMe )
{
$expire = new \IPS\DateTime;
$expire->add( new \DateInterval( 'P7D' ) );
\IPS\Request::i()->setCookie( 'member_id', $member->member_id, $expire );
\IPS\Request::i()->setCookie( 'pass_hash', $member->member_login_key, $expire );
if ( $anonymous and !\IPS\Settings::i()->disable_anonymous )
{
\IPS\Request::i()->setCookie( 'anon_login', 1, $expire );
}
}
$member->memberSync( 'onLogin', array( \IPS\Login::getDestination() ) );
}
/**
* Link Accounts
*
* @return void
*/
protected function link()
{
if ( !isset( $_SESSION['linkAccounts'] ) )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) );
}
$details = json_decode( $_SESSION['linkAccounts'], TRUE );
$member = \IPS\Member::load( $details['member'] );
if ( !$member->member_id )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) );
}
$form = new \IPS\Helpers\Form( 'link_accounts', 'login' );
$form->addDummy( 'email_address', isset( $details['email'] ) ? $details['email'] : $member->email );
$form->add( new \IPS\Helpers\Form\Password( 'password', NULL, TRUE, array( 'validateFor' => $member ) ) );
if ( $values = $form->values() )
{
try
{
$class = 'IPS\Login\\' . ucfirst( $details['handler'] );
$class::link( $member, $details['details'] );
unset( $_SESSION['linkAccounts'] );
$this->_doLogin( $member );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
catch ( \IPS\Login\Exception $e )
{
$form->error = $e->getMessage();
}
}
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('login');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->mergeSocialAccount( $details['handler'], $member, $form );
}
/**
* Log Out
*
* @return void
*/
protected function logout()
{
\IPS\Session::i()->csrfCheck();
\IPS\Request::i()->setCookie( 'member_id', NULL );
\IPS\Request::i()->setCookie( 'pass_hash', NULL );
\IPS\Request::i()->setCookie( 'anon_login', NULL );
foreach( \IPS\Request::i()->cookie as $name => $value )
{
if( mb_strpos( $name, "ipbforumpass_" ) !== FALSE )
{
\IPS\Request::i()->setCookie( $name, NULL );
}
}
$redirectUrl = ( !empty( $_SERVER['HTTP_REFERER'] ) ) ? \IPS\Http\Url::external( $_SERVER['HTTP_REFERER'] ) : \IPS\Http\Url::internal( '' );
$member = \IPS\Member::loggedIn();
/* Are we logging out back to an admin user? */
if( isset( $_SESSION['logged_in_as_key'] ) )
{
$key = $_SESSION['logged_in_as_key'];
unset( \IPS\Data\Store::i()->$key );
unset( $_SESSION['logged_in_as_key'] );
unset( $_SESSION['logged_in_from'] );
\IPS\Output::i()->redirect( $redirectUrl );
}
session_destroy();
/* Login handler callback */
foreach ( \IPS\Login::handlers( TRUE ) as $k => $handler )
{
try
{
$handler->logoutAccount( $member, $redirectUrl );
}
catch( \BadMethodCallException $e ) {}
}
/* Member sync callback */
$member->memberSync( 'onLogout', array( $redirectUrl ) );
\IPS\Output::i()->redirect( $redirectUrl->setQueryString( '_fromLogout', 1 ) );
}
/**
* Log in as user
*
* @return void
*/
protected function loginas()
{
if ( !\IPS\Request::i()->key or \IPS\Data\Store::i()->admin_login_as_user != \IPS\Request::i()->key )
{
\IPS\Output::i()->error( 'invalid_login_as_user_key', '3S167/1', 403, '' );
}
/* Load member and admin user */
$member = \IPS\Member::load( \IPS\Request::i()->id );
$admin = \IPS\Member::load( \IPS\Request::i()->admin );
/* Not logged in as admin? */
if ( $admin->member_id != \IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https )->setQueryString( array( 'ref' => base64_encode( \IPS\Request::i()->url() ), '_err' => 'login_as_user_login' ) ) );
}
/* Do it */
$_SESSION['logged_in_from'] = array( 'id' => $admin->member_id, 'name' => $admin->name );
$unique_id = md5( uniqid() );
$_SESSION['logged_in_as_key'] = $unique_id;
\IPS\Data\Store::i()->$unique_id = $member->member_id;
/* Ditch the key */
unset( \IPS\Data\Store::i()->admin_login_as_user );
/* Redirect */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
}
@@ -0,0 +1,140 @@
<?php
/**
* @brief Lost Password
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 26 Aug 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Lost Password
*/
class _lostpass extends \IPS\Dispatcher\Controller
{
/**
* Manage
*
* @return void
*/
protected function manage()
{
/* Build the form */
$form = new \IPS\Helpers\Form( "lostpass", 'request_password' );
$form->add( new \IPS\Helpers\Form\Email( 'email_address', NULL, TRUE, array(), function( $val ){
/* Check email exists */
$member = \IPS\Member::load( $val, 'email' );
if( !$member->member_id )
{
throw new \LogicException( 'lost_pass_no_email' );
}
}) );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('lost_password');
/* Handle the reset */
if ( $values = $form->values() )
{
/* Load the member */
$member = \IPS\Member::load( $values['email_address'], 'email' );
/* Make a validation key */
$vid = md5( $member->members_pass_hash . uniqid( mt_rand(), TRUE ) );
/* Get rid of old entries for this member */
\IPS\DB::i()->delete( 'core_validating', array( 'member_id=? AND lost_pass=1', $member->member_id ) );
/* Update the DB for this member. */
$validating = array(
'vid' => $vid,
'member_id' => $member->member_id,
'entry_date' => time(),
'lost_pass' => 1,
'ip_address' => $member->ip_address,
);
\IPS\Db::i()->insert( 'core_validating', $validating );
/* Send email */
\IPS\Email::buildFromTemplate( 'core', 'lost_password_init', array( $member, $vid ) )->send( $member );
/* Show confirmation page with further instructions */
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->lostPassConfirm();
}
else
{
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->lostPass( $form );
}
}
/**
* Validate
*
* @return void
*/
protected function validate()
{
try
{
$record = \IPS\Db::i()->select( '*', 'core_validating', array( 'vid=? AND member_id=? AND lost_pass=1', \IPS\Request::i()->vid, \IPS\Request::i()->mid ) )->first();
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->error( 'no_validation_key', '2S151/1', 410, '' );
}
/* Show form for new password */
$form = new \IPS\Helpers\Form( "resetpass", 'save' );
$form->add( new \IPS\Helpers\Form\Password( 'password', NULL, TRUE, array() ) );
$form->add( new \IPS\Helpers\Form\Password( 'password_confirm', NULL, TRUE, array( 'confirm' => 'password' ) ) );
/* Set new password */
if ( $values = $form->values() )
{
$member = \IPS\Member::load( $record['member_id'] );
$member->members_pass_salt = $member->generateSalt();
$member->members_pass_hash = $member->encryptedPassword( $values['password'] );
$member->failed_logins = array();
$member->save();
/* Delete validating record and log in */
\IPS\Db::i()->delete( 'core_validating', array( 'member_id=? AND lost_pass=1', $member->member_id ) );
/* If the member doesn't have any other validating rows validate them */
try
{
$record = \IPS\Db::i()->select( '*', 'core_validating', array( 'member_id=?', $member->member_id ) )->first();
}
catch ( \UnderflowException $e )
{
$member->validate();
}
\IPS\Session::i()->setMember( $member );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->resetPass( $form );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'lost_password' );
}
}
@@ -0,0 +1,43 @@
<?php
/**
* @brief Mark site as read
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 19 May 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Mark site as read
*/
class _markread extends \IPS\Dispatcher\Controller
{
/**
* Mark site as read
*
* @return void
*/
protected function manage()
{
\IPS\Session::i()->csrfCheck();
if ( \IPS\Member::loggedIn()->member_id )
{
\IPS\Member::loggedIn()->markAllAsRead();
}
/* Don't redirect to an external domain unless explicitly requested, and don't redirect back to ACP */
\IPS\Output::i()->redirect( ( !empty( $_SERVER['HTTP_REFERER'] ) ) ? \IPS\Http\Url::external( $_SERVER['HTTP_REFERER'] ) : \IPS\Http\Url::internal( '' ), 'core_site_marked_as_read' );
}
}
@@ -0,0 +1,119 @@
<?php
/**
* @brief Live meta tag editor
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 4 Sept 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Live meta tag editor
*/
class _metatags extends \IPS\Dispatcher\Controller
{
/**
* Redirect the request appropriately
*
* @return void
*/
protected function manage()
{
$this->_checkPermissions();
$_SESSION['live_meta_tags'] = TRUE;
\IPS\Output::i()->redirect( \IPS\Http\Url::external( \IPS\Settings::i()->base_url ) );
}
/**
* Save a meta tag
*
* @return void
*/
protected function save()
{
/* Check permissions and CSRF */
$this->_checkPermissions();
\IPS\Session::i()->csrfCheck();
/* Delete any existing database entries, as we are about to re-insert */
\IPS\DB::i()->delete( 'core_seo_meta', array( 'meta_url=?', \IPS\Request::i()->meta_url ) );
\IPS\DB::i()->delete( 'core_seo_meta', array( 'meta_url=?', trim( \IPS\Request::i()->meta_url, '/' ) ) );
/* Start save array */
$save = array(
'meta_url' => \IPS\Request::i()->meta_url,
'meta_title' => \IPS\Request::i()->meta_tag_title,
);
$_tags = array();
/* Store the new meta tags */
if( isset( \IPS\Request::i()->meta_tag_name ) AND is_array( \IPS\Request::i()->meta_tag_name ) )
{
foreach( \IPS\Request::i()->meta_tag_name as $k => $v )
{
if( $v AND ( $v != 'other' OR !empty( \IPS\Request::i()->meta_tag_name_other[ $k ] ) ) AND !isset( $_tags[ $v != 'other' ? $v : \IPS\Request::i()->meta_tag_name_other[ $k ] ] ) )
{
$_tags[ ( $v != 'other' ) ? $v : \IPS\Request::i()->meta_tag_name_other[ $k ] ] = \IPS\Request::i()->meta_tag_content[ $k ];
}
}
}
$save['meta_tags'] = json_encode( $_tags );
\IPS\DB::i()->insert( 'core_seo_meta', $save );
unset( \IPS\Data\Store::i()->metaTags );
/* Send back to the page */
if( \IPS\Request::i()->isAjax() )
{
return;
}
\IPS\Output::i()->redirect( \IPS\Http\Url::external( \IPS\Settings::i()->base_url . \IPS\Request::i()->url ) );
}
/**
* Stop editing meta tags
*
* @return void
*/
protected function end()
{
$_SESSION['live_meta_tags'] = FALSE;
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( \IPS\Request::i()->url ) );
}
/**
* Check permissions to use the tool
*
* @return void
*/
protected function _checkPermissions()
{
if( !\IPS\Member::loggedIn()->member_id OR !\IPS\Member::loggedIn()->isAdmin() )
{
\IPS\Output::i()->error( 'meta_editor_no_admin', '2C155/1', 403, '' );
}
if( !\IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'seo_manage' ) )
{
\IPS\Output::i()->error( 'meta_editor_no_acpperm', '3C155/2', 403, '' );
}
}
}
@@ -0,0 +1,52 @@
<?php
/**
* @brief Moderation
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 23 Jul 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Moderation
*/
class _moderation extends \IPS\Dispatcher\Controller
{
/**
* Flag Member As Spammer
*
* @return void
*/
protected function flagAsSpammer()
{
\IPS\Session::i()->csrfCheck();
$member = \IPS\Member::load( \IPS\Request::i()->id );
if ( $member->member_id and $member->member_id != \IPS\Member::loggedIn()->member_id and \IPS\Member::loggedIn()->modPermission('can_flag_as_spammer') and !$member->modPermission() and !$member->isAdmin() )
{
if ( \IPS\Request::i()->s )
{
$member->flagAsSpammer();
\IPS\Session::i()->modLog( 'modlog__spammer_flagged', array( $member->name => FALSE ) );
}
else
{
$member->unflagAsSpammer();
\IPS\Session::i()->modLog( 'modlog__spammer_unflagged', array( $member->name => FALSE ) );
}
}
\IPS\Output::i()->redirect( ( \IPS\Request::i()->referrer ) ? new \IPS\Http\Url( urldecode( \IPS\Request::i()->referrer ), TRUE ) : $member->url(), ( \IPS\Request::i()->s ) ? 'account_flagged' : 'account_unflagged');
}
}
@@ -0,0 +1,646 @@
<?php
/**
* @brief Notification Settings Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 27 Aug 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Notification Settings Controller
*/
class _notifications extends \IPS\Dispatcher\Controller
{
/**
* Execute
*/
protected function _checkLoggedIn()
{
if ( !\IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'no_module_permission_guest', '2C154/2', 403, '' );
}
}
/**
* View Notifications
*
* @return void
*/
protected function manage()
{
$this->_checkLoggedIn();
/* Init table */
$urlObject = \IPS\Http\Url::internal( 'app=core&module=system&controller=notifications', 'front', 'notifications' );
$table = new \IPS\Notification\Table( $urlObject );
$table->setMember( \IPS\Member::loggedIn() );
$notifications = $table->getRows();
\IPS\Db::i()->update( 'core_notifications', array( 'read_time' => time() ), array( 'member=?', \IPS\Member::loggedIn()->member_id ) );
\IPS\Member::loggedIn()->recountNotifications();
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'data' => \IPS\Theme::i()->getTemplate( 'system' )->notificationsAjax( $notifications ) ) );
}
elseif ( isset( \IPS\Request::i()->format ) and \IPS\Request::i()->format === 'rss' )
{
$document = \IPS\Xml\Rss::newDocument( $urlObject, \IPS\Member::loggedIn()->language()->get('notifications'), sprintf( \IPS\Member::loggedIn()->language()->get( 'notifications_rss_desc' ), \IPS\Member::loggedIn()->name, \IPS\Settings::i()->board_name ) );
if ( count( $table->getRows() ) )
{
foreach ( $table->getRows() as $notification )
{
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $notification['data']['title'] );
if( isset( $notification['data']['content'] ) )
{
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $notification['data']['content'] );
}
$document->addItem( $notification['data']['title'], $notification['data']['url'], isset( $notification['data']['content'] ) ? $notification['data']['content'] : NULL, $notification['notification']->updated_time, $notification['notification']->id );
}
}
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
}
else
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('notifications');
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Output::i()->title );
\IPS\Output::i()->output = (string) $table;
}
}
/**
* Options
*
* @return void
*/
protected function options()
{
$this->_checkLoggedIn();
/* Build form */
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\Checkbox( 'allow_admin_mails', \IPS\Member::loggedIn()->allow_admin_mails ) );
$_autoTrack = array();
if( \IPS\Member::loggedIn()->auto_follow['content'] )
{
$_autoTrack[] = 'content';
}
if( \IPS\Member::loggedIn()->auto_follow['comments'] )
{
$_autoTrack[] = 'comments';
}
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'auto_track', $_autoTrack, FALSE, array( 'options' => array( 'content' => 'auto_track_content', 'comments' => 'auto_track_comments' ), 'multiple' => TRUE ) ) );
$form->add( new \IPS\Helpers\Form\Radio( 'auto_track_type', \IPS\Member::loggedIn()->auto_follow['method'] ?: 'immediate', FALSE, array( 'options' => array(
'immediate' => \IPS\Member::loggedIn()->language()->addToStack('follow_type_immediate'),
'daily' => \IPS\Member::loggedIn()->language()->addToStack('follow_type_daily'),
'weekly' => \IPS\Member::loggedIn()->language()->addToStack('follow_type_weekly')
) ), NULL, NULL, NULL, 'auto_track_type' ) );
$form->add( new \IPS\Helpers\Form\Checkbox( 'show_pm_popup', \IPS\Member::loggedIn()->members_bitoptions['show_pm_popup'] ) );
$form->addMatrix( 'notifications', \IPS\Notification::buildMatrix( \IPS\Member::loggedIn() ) );
/* Handle submissions */
if ( $values = $form->values() )
{
\IPS\Member::loggedIn()->allow_admin_mails = $values['allow_admin_mails'];
\IPS\Member::loggedIn()->auto_track = json_encode( array(
'content' => ( is_array( $values['auto_track'] ) AND in_array( 'content', $values['auto_track'] ) ) ? 1 : 0,
'comments' => ( is_array( $values['auto_track'] ) AND in_array( 'comments', $values['auto_track'] ) ) ? 1 : 0,
'method' => $values['auto_track_type']
) );
\IPS\Member::loggedIn()->members_bitoptions['show_pm_popup'] = $values['show_pm_popup'];
if ( isset( $values['notifications']['report_center'] ) and !$values['notifications']['report_center']['member_notifications_inline'] )
{
\IPS\Member::loggedIn()->members_bitoptions['no_report_count'] = TRUE;
}
else
{
\IPS\Member::loggedIn()->members_bitoptions['no_report_count'] = FALSE;
}
\IPS\Notification::saveMatrix( \IPS\Member::loggedIn(), $values );
\IPS\Member::loggedIn()->save();
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
}
/* Display */
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'system' ), 'notificationsSettings' ) );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('notification_options');
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=core&module=system&controller=notifications', 'front', 'notifications' ), \IPS\Member::loggedIn()->language()->addToStack('notifications') );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('options') );
}
/**
* Follow Something
*
* @return void
*/
protected function follow()
{
$this->_checkLoggedIn();
/* Get class */
$class = NULL;
foreach ( \IPS\Application::load( \IPS\Request::i()->follow_app )->extensions( 'core', 'ContentRouter' ) as $ext )
{
foreach ( $ext->classes as $classname )
{
if ( $classname == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $classname;
break;
}
if ( isset( $classname::$containerNodeClass ) and $classname::$containerNodeClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $classname::$containerNodeClass;
break;
}
if( isset( $classname::$containerFollowClasses ) )
{
foreach( $classname::$containerFollowClasses as $followClass )
{
if( $followClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $followClass;
break;
}
}
}
}
}
if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'member' )
{
/* You can't follow yourself */
if( \IPS\Request::i()->follow_id == \IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'cant_follow_self', '3C154/7', 403, '' );
}
/* Following disabled */
$member = \IPS\Member::load( \IPS\Request::i()->follow_id );
if( !$member->member_id )
{
\IPS\Output::i()->error( 'cant_follow_member', '3C154/9', 403, '' );
}
if( $member->members_bitoptions['pp_setting_moderate_followers'] and !\IPS\Member::loggedIn()->following( 'core', 'member', $member->member_id ) )
{
\IPS\Output::i()->error( 'cant_follow_member', '3C154/8', 403, '' );
}
$class = 'IPS\\Member';
}
if ( !$class )
{
\IPS\Output::i()->error( 'node_error', '2C154/3', 404, '' );
}
/* Get thing */
$thing = NULL;
try
{
if ( in_array( 'IPS\Node\Model', class_parents( $class ) ) )
{
$thing = $class::loadAndCheckPerms( \IPS\Request::i()->follow_id );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'follow_thing', FALSE, array( 'sprintf' => array( $thing->_title ) ) );
/* Set navigation */
try
{
foreach ( $thing->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( NULL, $thing->_title );
}
catch ( \Exception $e ) { }
}
else if ( $class != "IPS\Member" )
{
$thing = $class::loadAndCheckPerms( \IPS\Request::i()->follow_id );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'follow_thing', FALSE, array( 'sprintf' => array( $thing->mapped('title') ) ) );
/* Set navigation */
$container = NULL;
try
{
$container = $thing->container();
foreach ( $container->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( $container->url(), $container->_title );
}
catch ( \Exception $e ) { }
/* Set meta tags */
\IPS\Output::i()->breadcrumb[] = array( NULL, $thing->mapped('title') );
}
else
{
$thing = $class::load( \IPS\Request::i()->follow_id );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('follow_thing', FALSE, array( 'sprintf' => array( $thing->name ) ) );
/* Set navigation */
\IPS\Output::i()->breadcrumb[] = array( NULL, $thing->name );
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C154/4', 404, '' );
}
/* Do we follow it? */
try
{
$current = \IPS\Db::i()->select( '*', 'core_follow', array( 'follow_app=? AND follow_area=? AND follow_rel_id=? AND follow_member_id=?', \IPS\Request::i()->follow_app, \IPS\Request::i()->follow_area, \IPS\Request::i()->follow_id, \IPS\Member::loggedIn()->member_id ) )->first();
}
catch ( \UnderflowException $e )
{
$current = FALSE;
}
/* How do we receive notifications? */
if ( $class == 'IPS\Member' )
{
$type = 'follower_content';
}
elseif ( in_array( 'IPS\Content\Item', class_parents( $class ) ) )
{
$type = 'new_comment';
}
else
{
$type = 'new_content';
}
$notificationConfiguration = \IPS\Member::loggedIn()->notificationsConfiguration();
$notificationConfiguration = isset( $notificationConfiguration[ $type ] ) ? $notificationConfiguration[ $type ] : array();
$lang = 'follow_type_immediate';
if ( in_array( 'email', $notificationConfiguration ) and in_array( 'inline', $notificationConfiguration ) )
{
$lang = 'follow_type_immediate_inline_email';
}
elseif ( in_array( 'email', $notificationConfiguration ) )
{
$lang = 'follow_type_immediate_email';
}
if ( $class == "IPS\Member" )
{
\IPS\Member::loggedIn()->language()->words[ $lang ] = \IPS\Member::loggedIn()->language()->addToStack( $lang . '_member', FALSE, array( 'sprintf' => array( $thing->name ) ) );
}
if ( empty( $notificationConfiguration ) )
{
\IPS\Member::loggedIn()->language()->words[ $lang . '_desc' ] = \IPS\Member::loggedIn()->language()->addToStack( 'follow_type_immediate_none', FALSE ) . ' <a href="' . \IPS\Http\Url::internal( 'app=core&module=system&controller=notifications&do=options&type=' . $type, 'front', 'notifications_options' ) . '">' . \IPS\Member::loggedIn()->language()->addToStack( 'notification_options', FALSE ) . '</a>';
}
else
{
\IPS\Member::loggedIn()->language()->words[ $lang . '_desc' ] = '<a href="' . \IPS\Http\Url::internal( 'app=core&module=system&controller=notifications&do=options&type=' . $type, 'front', 'notifications_options' ) . '">' . \IPS\Member::loggedIn()->language()->addToStack( 'follow_type_immediate_change', FALSE ) . '</a>';
}
/* Build form */
$form = new \IPS\Helpers\Form( 'follow', ( $current ) ? 'update_follow' : 'follow', NULL, array(
'data-followApp' => \IPS\Request::i()->follow_app,
'data-followArea' => \IPS\Request::i()->follow_area,
'data-followID' => \IPS\Request::i()->follow_id
) );
$form->class = 'ipsForm_vertical';
$options = array();
$options['immediate'] = $lang;
if ( $class != "IPS\Member" )
{
$options['daily'] = \IPS\Member::loggedIn()->language()->addToStack('follow_type_daily');
$options['weekly'] = \IPS\Member::loggedIn()->language()->addToStack('follow_type_weekly');
$options['none'] = \IPS\Member::loggedIn()->language()->addToStack('follow_type_no_notification');
}
if ( count( $options ) > 1 )
{
$form->add( new \IPS\Helpers\Form\Radio( 'follow_type', $current ? $current['follow_notify_freq'] : NULL, TRUE, array(
'options' => $options,
'disabled' => empty( $notificationConfiguration ) ? array( 'immediate' ) : array()
) ) );
}
else
{
foreach ( $options as $k => $v )
{
$form->hiddenValues[ $k ] = $v;
if ( empty( $notificationConfiguration ) )
{
$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack( 'follow_type_no_config' ) . ' <a href="' . \IPS\Http\Url::internal( 'app=core&module=system&controller=notifications&do=options&type=' . $type, 'front', 'notifications_options' ) . '">' . \IPS\Member::loggedIn()->language()->addToStack( 'notification_options', FALSE ) . '</a>', '', FALSE );
}
else
{
$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack( $v ) . '<br>' . \IPS\Member::loggedIn()->language()->addToStack( $lang . '_desc' ), '', FALSE );
}
}
}
$form->add( new \IPS\Helpers\Form\Checkbox( 'follow_public', $current ? !$current['follow_is_anon'] : TRUE, FALSE, array(
'label' => ( $class != "IPS\Member" ) ? \IPS\Member::loggedIn()->language()->addToStack( 'follow_public' ) : \IPS\Member::loggedIn()->language()->addToStack('follow_public_member', FALSE, array( 'sprintf' => array( $thing->name ) ) )
) ) );
if ( $current )
{
$form->addButton( 'unfollow', 'link', \IPS\Http\Url::internal( "app=core&module=system&section=notifications&do=unfollow&id={$current['follow_id']}&follow_app={$current['follow_app']}&follow_area={$current['follow_area']}" )->csrf(), 'ipsButton ipsButton_negative ipsPos_right', array('data-action' => 'unfollow') );
}
/* Handle submissions */
if ( $values = $form->values() )
{
/* Insert */
$save = array(
'follow_id' => md5( \IPS\Request::i()->follow_app . ';' . \IPS\Request::i()->follow_area . ';' . \IPS\Request::i()->follow_id . ';' . \IPS\Member::loggedIn()->member_id ),
'follow_app' => \IPS\Request::i()->follow_app,
'follow_area' => \IPS\Request::i()->follow_area,
'follow_rel_id' => \IPS\Request::i()->follow_id,
'follow_member_id' => \IPS\Member::loggedIn()->member_id,
'follow_is_anon' => !$values['follow_public'],
'follow_added' => time(),
'follow_notify_do' => ( isset( $values['follow_type'] ) AND $values['follow_type'] == 'none' ) ? 0 : 1,
'follow_notify_meta' => '',
'follow_notify_freq' => ( $class == "IPS\Member" ) ? 'immediate' : $values['follow_type'],
'follow_notify_sent' => 0,
'follow_visible' => 1
);
if ( $current )
{
\IPS\Db::i()->update( 'core_follow', $save, array( 'follow_id=?', $current['follow_id'] ) );
}
else
{
\IPS\Db::i()->insert( 'core_follow', $save );
}
/* Send notification if following member */
if( $class == "IPS\Member" )
{
$notification = new \IPS\Notification( \IPS\Application::load( 'core' ), 'member_follow', \IPS\Member::loggedIn(), array( \IPS\Member::loggedIn() ) );
$notification->recipients->attach( $thing );
$notification->send();
}
/* Boink */
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( 'ok' );
}
else
{
\IPS\Output::i()->redirect( $thing->url() );
}
}
/* Display */
$output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'system', 'core' ) ), 'followForm' ) );
/* @see http://community.invisionpower.com/4bugtrack/follow-button-adds-meta-title-and-link-tags-r3209/ */
if( \IPS\Request::i()->isAjax() ){
\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
} else {
\IPS\Output::i()->output = $output;
}
}
/**
* Unfollow
*
* @return void
*/
protected function unfollow()
{
$this->_checkLoggedIn();
\IPS\Session::i()->csrfCheck();
try
{
$follow = \IPS\Db::i()->select( '*', 'core_follow', array( 'follow_id=? AND follow_member_id=?', \IPS\Request::i()->id, \IPS\Member::loggedIn()->member_id ) )->first();
}
catch ( \OutOfRangeException $e ) {}
\IPS\Db::i()->delete( 'core_follow', array( 'follow_id=? AND follow_member_id=?', \IPS\Request::i()->id, \IPS\Member::loggedIn()->member_id ) );
/* Get class */
$class = NULL;
foreach ( \IPS\Application::load( \IPS\Request::i()->follow_app )->extensions( 'core', 'ContentRouter' ) as $ext )
{
foreach ( $ext->classes as $classname )
{
if ( $classname == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $classname;
break;
}
if ( isset( $classname::$containerNodeClass ) and $classname::$containerNodeClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $classname::$containerNodeClass;
break;
}
if( isset( $classname::$containerFollowClasses ) )
{
foreach( $classname::$containerFollowClasses as $followClass )
{
if( $followClass == 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area ) )
{
$class = $followClass;
break;
}
}
}
}
}
if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'member' )
{
$class = 'IPS\\Member';
}
/* Get thing */
$thing = NULL;
try
{
if ( $class != "IPS\Member" )
{
$thing = $class::loadAndCheckPerms( $follow['follow_rel_id'] );
}
else if( !in_array( 'IPS\Node\Model', class_parents( $class ) ) )
{
$thing = $class::load( $follow['follow_rel_id'] );
}
}
catch ( \OutOfRangeException $e )
{
}
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( 'ok' );
}
else
{
\IPS\Output::i()->redirect( ( !empty( $_SERVER['HTTP_REFERER'] ) ) ? \IPS\Http\Url::external( $_SERVER['HTTP_REFERER'] ) : \IPS\Http\Url::internal( '' ) );
}
}
/**
* Show Followers
*
* @return void
*/
protected function followers()
{
$perPage = 50;
$thisPage = isset( \IPS\Request::i()->followerPage ) ? \IPS\Request::i()->followerPage : 1;
$thisPage = ( $thisPage > 0 ) ? $thisPage : 1;
/* Get class */
if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'member' )
{
$class = 'IPS\\Member';
}
else
{
$class = 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area );
}
if ( !class_exists( $class ) )
{
\IPS\Output::i()->error( 'node_error', '2C154/5', 404, '' );
}
/* Get thing */
$thing = NULL;
$anonymous = 0;
try
{
if ( in_array( 'IPS\Node\Model', class_parents( $class ) ) )
{
$classname = $class::$contentItemClass;
$containerClass = $class;
$thing = $containerClass::loadAndCheckPerms( \IPS\Request::i()->follow_id );
$followers = $classname::containerFollowers( $thing, $classname::FOLLOW_PUBLIC, array( 'none', 'immediate', 'daily', 'weekly' ), NULL, array( ( $thisPage - 1 ) * $perPage, $perPage ), 'name' );
$anonymous = $classname::containerFollowers( $thing, $classname::FOLLOW_ANONYMOUS )->count( TRUE );
$title = $thing->_title;
}
else if ( $class != "IPS\Member" )
{
$thing = $class::loadAndCheckPerms( \IPS\Request::i()->follow_id );
$followers = $thing->followers( $class::FOLLOW_PUBLIC, array( 'none', 'immediate', 'daily', 'weekly' ), NULL, array( ( $thisPage - 1 ) * $perPage, $perPage ), 'name' );
$anonymous = $thing->followers( $class::FOLLOW_ANONYMOUS )->count( TRUE );
$title = $thing->name;
}
else
{
$thing = $class::load( \IPS\Request::i()->follow_id );
$followers = $thing->followers( $class::FOLLOW_PUBLIC, array( 'none', 'immediate', 'daily', 'weekly' ), NULL, array( ( $thisPage - 1 ) * $perPage, $perPage ), 'name' );
$anonymous = $thing->followers( $class::FOLLOW_ANONYMOUS )->count( TRUE );
$title = $thing->mapped('title');
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C154/6', 404, '' );
}
/* Display */
if ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->_infScroll ) )
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'system' )->followersRows( $followers ) );
}
else
{
$url = \IPS\Http\Url::internal( "app=core&module=system&section=notifications&do=followers&follow_app=". \IPS\Request::i()->follow_app ."&follow_area=". \IPS\Request::i()->follow_area ."&follow_id=" . \IPS\Request::i()->follow_id . "&_infScroll=1" );
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $url, ceil( $followers->count( TRUE ) / $perPage ), $thisPage, $perPage, FALSE, 'followerPage' );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('item_followers', FALSE, array( 'sprintf' => array( $title ) ) );
\IPS\Output::i()->breadcrumb[] = array( $thing->url(), $title );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('who_follows_this') );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->followers( $url, $pagination, $followers, $anonymous );
}
}
/**
* Follow button
*
* @return void
*/
protected function button()
{
/* Get class */
if( \IPS\Request::i()->follow_app == 'core' and \IPS\Request::i()->follow_area == 'member' )
{
$class = 'IPS\\Member';
}
else
{
$class = 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . ucfirst( \IPS\Request::i()->follow_area );
}
if ( !class_exists( $class ) )
{
\IPS\Output::i()->error( 'node_error', '2C154/5', 404, '' );
}
/* Get thing */
$thing = NULL;
try
{
if ( in_array( 'IPS\Node\Model', class_parents( $class ) ) )
{
$classname = $class::$contentItemClass;
$containerClass = $class;
$thing = $containerClass::loadAndCheckPerms( \IPS\Request::i()->follow_id );
$count = $classname::containerFollowerCount( $thing );
}
else if ( $class != "IPS\Member" )
{
$thing = $class::loadAndCheckPerms( \IPS\Request::i()->follow_id );
$count = $thing->followers()->count( TRUE );
}
else
{
$thing = $class::load( \IPS\Request::i()->follow_id );
$count = $thing->followers()->count( TRUE );
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C154/6', 404, '' );
}
if ( \IPS\Request::i()->follow_area == 'member' )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile' )->memberFollowButton( \IPS\Request::i()->follow_app, \IPS\Request::i()->follow_area, \IPS\Request::i()->follow_id, $count );
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->followButton( \IPS\Request::i()->follow_app, \IPS\Request::i()->follow_area, \IPS\Request::i()->follow_id, $count );
}
}
}
@@ -0,0 +1,34 @@
<?php
/**
* @brief A deliberately empty controller intended for use by plugins which need to add small actions
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 09 Aug 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* A deliberately empty controller intended for use by plugins which need to add small actions
*/
class _plugins extends \IPS\Dispatcher\Controller
{
/**
* This is only here to prevent a fatal error calling to manage from the dispatcher
*
* @return void
*/
protected function manage()
{
}
}
@@ -0,0 +1,48 @@
<?php
/**
* @brief Poll View Voters Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 13 Jan 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Poll View Voters Controller
*/
class _poll extends \IPS\Dispatcher\Controller
{
/**
* View log
*
* @return void
*/
protected function voters()
{
try
{
$poll = \IPS\Poll::load( \IPS\Request::i()->id );
if ( !$poll->canSeeVoters() )
{
\IPS\Output::i()->error( 'node_error', '2C174/2', 403, '' );
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pollVoters( $poll->getVotes( \IPS\Request::i()->question, \IPS\Request::i()->option ) );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C174/1', 404, '' );
}
}
}
@@ -0,0 +1,47 @@
<?php
/**
* @brief Privacy Policy
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 28 Jun 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Privacy Policy
*/
class _privacy extends \IPS\Dispatcher\Controller
{
/**
* Privacy Policy
*
* @return void
*/
protected function manage()
{
if ( \IPS\Settings::i()->privacy_type == "none" )
{
\IPS\Output::i()->error( 'node_error', '', 404 ); /* @todo Error code */
}
/* Set Session Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=privacy', NULL, 'privacy' ), array(), 'loc_viewing_privacy_policy' );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('privacy') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('privacy');
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->privacy();
}
}
@@ -0,0 +1,121 @@
<?php
/**
* @brief External redirector with key checks
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 12 Jun 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Redirect
*/
class _redirect extends \IPS\Dispatcher\Controller
{
/**
* Redirect the request appropriately
*
* @return void
*/
protected function manage()
{
/* First check the key to make sure this actually came from HTMLPurifier */
if ( \IPS\Request::i()->key == hash_hmac( "sha256", \IPS\Request::i()->url, md5( \IPS\Settings::i()->sql_pass . \IPS\Settings::i()->board_url . \IPS\Settings::i()->sql_database ) ) )
{
/* Is it a resource? (image, etc.) */
if ( \IPS\Request::i()->resource )
{
/* If it's a resource, redirect without a message. Browsers should follow a location header for resources such as image fine. */
/* Note that this scenario is hit if we have <img src='munged url' /> */
\IPS\Output::i()->redirect( \IPS\Http\Url::external( \IPS\Request::i()->url ) );
}
else
{
/* Regular URL? Show a redirect page. */
\IPS\Output::i()->redirect( \IPS\Http\Url::external( \IPS\Request::i()->url ), \IPS\Member::loggedIn()->language()->addToStack('external_redirect'), 303, TRUE );
}
}
else
{
/* Key did not validate, send the user to the index page */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('') );
}
}
/**
* Redirect an ACP click
*
* @note The purpose of this method is to avoid exposing \IPS\CP_DIRECTORY to non-admins
* @return void
*/
protected function admin()
{
if( \IPS\Member::loggedIn()->isAdmin() )
{
$queryString = base64_decode( \IPS\Request::i()->_data );
\IPS\Output::i()->redirect( new \IPS\Http\Url( \IPS\Http\Url::baseUrl() . \IPS\CP_DIRECTORY . '/?' . $queryString, TRUE ) );
}
\IPS\Output::i()->error( 'no_access_cp', '2C159/3', 403 );
}
/**
* Redirect an advertisement click
*
* @return void
*/
protected function advertisement()
{
/* CSRF check */
\IPS\Session::i()->csrfCheck();
/* Get the advertisement */
$advertisement = array();
if( isset( \IPS\Request::i()->ad ) )
{
try
{
$advertisement = \IPS\core\Advertisement::load( \IPS\Request::i()->ad );
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'ad_not_found', '2C159/2', 404, 'ad_not_found_admin' );
}
}
if( !$advertisement->id OR !$advertisement->link )
{
\IPS\Output::i()->error( 'ad_not_found', '2C159/1', 404, 'ad_not_found_admin' );
}
/* We need to update click count for this advertisement. Does it need to be shut off too due to hitting click maximum?
Note that this needs to be done as a string to do "col=col+1", which is why we're not using the ActiveRecord save() method.
Updating by doing col=col+1 is more reliable when there are several clicks at nearly the same time. */
$update = "ad_clicks=ad_clicks+1";
if( $advertisement->maximum_unit == 'c' AND $advertisement->maximum_value > -1 AND $advertisement->clicks + 1 >= $advertisement->maximum_value )
{
$update .= ", ad_active=0";
unset( \IPS\Data\Cache::i()->advertisements );
}
/* Update the database */
\IPS\Db::i()->update( 'core_advertisements', $update, array( 'ad_id=?', $advertisement->id ) );
/* And do the redirect */
\IPS\Output::i()->redirect( \IPS\Http\Url::external( $advertisement->link ) );
}
}
@@ -0,0 +1,573 @@
<?php
/**
* @brief Register
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 3 July 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Register
*/
class _register extends \IPS\Dispatcher\Controller
{
/**
* Constructor
*
* @return void
*/
public function __construct()
{
if ( \IPS\Member::loggedIn()->member_id and isset( \IPS\Request::i()->_fromLogin ) )
{
\IPS\Output::i()->redirect( \IPS\Settings::i()->base_url );
}
if( !\IPS\Settings::i()->allow_reg and \IPS\Request::i()->do !== 'complete'
and \IPS\Request::i()->do !== 'changeEmail' and \IPS\Request::i()->do !== 'validate' and \IPS\Request::i()->do !== 'validating' )
{
\IPS\Output::i()->error( 'reg_disabled', '2S129/5', 403, '' );
}
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
}
/**
* Register
*
* @return void
*/
protected function manage()
{
if( !\IPS\Settings::i()->site_online )
{
\IPS\Output::i()->showOffline();
}
if( isset( $_SESSION['coppa_user'] ) )
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('reg_awaiting_validation');
return \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->notCoppaValidated();
}
/* Set up the step array */
$steps = array();
/* If coppa is enabled we need to add a birthday verification */
if ( \IPS\Settings::i()->use_coppa )
{
$steps['coppa'] = function( $data )
{
/* Build the form */
$form = new \IPS\Helpers\Form( 'coppa', 'register_button' );
$form->add( new \IPS\Helpers\Form\Date( 'bday', NULL, TRUE, array( 'max' => \IPS\DateTime::create() ) ) );
if( $values = $form->values() )
{
if( ( $values['bday']->diff( \IPS\DateTime::create() )->y < 13 ) )
{
$_SESSION['coppa_user'] = TRUE;
return \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->notCoppaValidated();
}
return $values;
}
return \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->coppa( $form );
};
}
$self = $this;
$steps['basic_info'] = function ( $data ) use ( $self )
{
$form = \IPS\core\modules\front\system\register::buildRegistrationForm();
/* Handle submissions */
if ( $values = $form->values() )
{
/* Create Member */
$member = \IPS\core\modules\front\system\register::_createMember( $values );
/* Custom Fields */
$profileFields = array();
foreach ( \IPS\core\ProfileFields\Field::fields( array(), \IPS\core\ProfileFields\REG ) as $group => $fields )
{
foreach ( $fields as $id => $field )
{
$profileFields[ "field_{$id}" ] = $field::stringValue( $values[ $field->name ] );
if ( $fields instanceof \IPS\Helpers\Form\Editor )
{
$field->claimAttachments( $self->id );
}
}
}
\IPS\Db::i()->replace( 'core_pfields_content', array_merge( array( 'member_id' => $member->member_id ), $profileFields ) );
/* Email - We don't want to send if the new member is banned or we're not using email validation */
if( \IPS\Settings::i()->reg_auth_type != 'none' AND \IPS\Settings::i()->reg_auth_type != 'admin' AND !$member->members_bitoptions['bw_is_spammer'] )
{
\IPS\Email::buildFromTemplate( 'core', 'registration_validate', array( $member, \IPS\Db::i()->select( 'vid', 'core_validating', array( 'member_id=?', $member->member_id ) )->first() ) )->send( $member );
}
/* Notify the incoming mail address except if they're a spammer */
if( \IPS\Settings::i()->new_reg_notify && !$member->members_bitoptions['bw_is_spammer'] )
{
\IPS\Email::buildFromTemplate( 'core', 'registration_notify', array( $member, $profileFields ) )->send( \IPS\Settings::i()->email_in );
}
/* Log them in */
\IPS\Session::i()->setMember( $member );
$redirectUrl = \IPS\Login::getRegistrationDestination( $member );
/* Redirect */
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'redirect' => (string) $redirectUrl ) );
}
else
{
\IPS\Output::i()->redirect( $redirectUrl );
}
}
return \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->register( $form, new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login', NULL, \IPS\Settings::i()->logins_over_https ) ) );
};
/* Set Session Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=register', NULL, 'register' ), array(), 'loc_registering' );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('registration');
\IPS\Output::i()->output = (string) new \IPS\Helpers\Wizard( $steps, \IPS\Http\Url::internal( 'app=core&module=system&controller=register' ), FALSE );
}
/**
* Build Registration Form
*
* @return \IPS\Helpers\Form
*/
public static function buildRegistrationForm()
{
/* Build the form */
$form = new \IPS\Helpers\Form( 'form', 'register_button', NULL, array( 'data-controller' => 'core.front.system.register') );
$form->add( new \IPS\Helpers\Form\Text( 'username', NULL, TRUE, array( 'accountUsername' => TRUE ) ) );
$form->add( new \IPS\Helpers\Form\Email( 'email_address', NULL, TRUE, array( 'accountEmail' => TRUE, 'maxLength' => 150 ) ) );
$form->add( new \IPS\Helpers\Form\Password( 'password', NULL, TRUE, array() ) );
$form->add( new \IPS\Helpers\Form\Password( 'password_confirm', NULL, TRUE, array( 'confirm' => 'password' ) ) );
/* Profile fields */
foreach ( \IPS\core\ProfileFields\Field::fields( array(), \IPS\core\ProfileFields\REG ) as $group => $fields )
{
foreach ( $fields as $field )
{
$form->add( $field );
}
}
$form->addSeparator();
$question = FALSE;
try
{
$question = \IPS\Db::i()->select( '*', 'core_question_and_answer', NULL, "RAND()" )->first();
}
catch ( \UnderflowException $e ) {}
/* Random Q&A */
if( $question )
{
$form->hiddenValues['q_and_a_id'] = $question['qa_id'];
$form->add( new \IPS\Helpers\Form\Text( 'q_and_a', NULL, TRUE, array(), function( $val )
{
$qanda = intval( \IPS\Request::i()->q_and_a_id );
$pass = true;
if( $qanda )
{
$question = \IPS\Db::i()->select( '*', 'core_question_and_answer', array( 'qa_id=?', $qanda ) )->first();
$answers = json_decode( $question['qa_answers'] );
if( $answers )
{
$answers = is_array( $answers ) ? $answers : array( $answers );
$pass = FALSE;
foreach( $answers as $answer )
{
$answer = trim( $answer );
if( mb_strlen( $answer ) AND mb_strtolower( $answer ) == mb_strtolower( $val ) )
{
$pass = TRUE;
}
}
}
}
else
{
$questions = \IPS\Db::i()->select( 'count(*)', 'core_question_and_answer', 'qa_id > 0' )->first();
if( $questions )
{
$pass = FALSE;
}
}
if( !$pass )
{
throw new \DomainException( 'q_and_a_incorrect' );
}
} ) );
/* Set the form label */
\IPS\Member::loggedIn()->language()->words['q_and_a'] = \IPS\Member::loggedIn()->language()->addToStack( 'core_question_and_answer_' . $question['qa_id'], FALSE );
}
$captcha = new \IPS\Helpers\Form\Captcha;
if ( (string) $captcha !== '' )
{
$form->add( $captcha );
}
if ( $question OR (string) $captcha !== '' )
{
$form->addSeparator();
}
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_admin_mails', TRUE, FALSE ) );
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] = sprintf( \IPS\Member::loggedIn()->language()->get("reg_agreed_terms"), \IPS\Http\Url::internal( 'app=core&module=system&controller=terms', 'front', 'terms' ) );
/* Build the appropriate links for registration terms & privacy policy */
if ( \IPS\Settings::i()->privacy_type == "internal" )
{
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= sprintf( \IPS\Member::loggedIn()->language()->get("reg_privacy_link"), \IPS\Http\Url::internal( 'app=core&module=system&controller=privacy', 'front', 'privacy' ), 'data-ipsDialog data-ipsDialog-size="wide" data-ipsDialog-title="' . \IPS\Member::loggedIn()->language()->get("privacy") . '"' );
}
else if ( \IPS\Settings::i()->privacy_type == "external" )
{
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= sprintf( \IPS\Member::loggedIn()->language()->get("reg_privacy_link"), \IPS\Http\Url::external( \IPS\Settings::i()->privacy_link ), 'target="_blank"' );
}
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_agreed_terms', NULL, TRUE, array(), function( $val )
{
if ( !$val )
{
throw new \InvalidArgumentException('reg_not_agreed_terms');
}
} ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_system.js', 'core', 'front' ), \IPS\Output::i()->js( 'front_templates.js', 'core', 'front' ) );
return $form;
}
/**
* Create Member
*
* @param array $values Values from form
* @return \IPS\Member
*/
public static function _createMember( $values )
{
/* Create */
$member = new \IPS\Member;
$member->name = $values['username'];
$member->email = $values['email_address'];
$member->members_pass_salt = $member->generateSalt();
$member->members_pass_hash = $member->encryptedPassword( $values['password'] );
$member->allow_admin_mails = $values['reg_admin_mails'];
$member->member_group_id = \IPS\Settings::i()->member_group;
$member->members_bitoptions['view_sigs'] = TRUE;
/* Query spam service */
if( \IPS\Settings::i()->spam_service_enabled )
{
if( $member->spamService() == 4 )
{
\IPS\Output::i()->error( 'spam_denied_account', '2S129/1', 403, '' );
}
}
/* Will we be validating? */
if ( \IPS\Settings::i()->reg_auth_type != 'none' )
{
$member->members_bitoptions['validating'] = TRUE;
}
/* Save and return */
$member->save();
return $member;
}
/**
* A printable coppa form
*
* @return void
*/
protected function coppaForm()
{
$output = \IPS\Theme::i()->getTemplate( 'system' )->coppaConsent();
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $output );
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $output ) );
}
/**
* Awaiting Validation
*
* @return void
*/
protected function validating()
{
if( !\IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
/* Fetch the validating record to see what we're dealing with */
try
{
$validating = \IPS\Db::i()->select( '*', 'core_validating', array( 'member_id=? AND ( new_reg=? OR email_chg=? )', \IPS\Member::loggedIn()->member_id, 1, 1 ) )->first();
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->error( 'validate_no_record', '2S129/4', 404, '' );
}
/* They're not validated but in what way? */
if( $validating['user_verified'] )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->notAdminValidated();
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->notValidated( $validating );
}
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('reg_awaiting_validation');
}
/**
* Resend validation email
*
* @return void
*/
protected function resend()
{
$validating = \IPS\Db::i()->select( '*', 'core_validating', array( 'member_id=?', \IPS\Member::loggedIn()->member_id ) );
if ( !count( $validating ) )
{
\IPS\Output::i()->error( 'validate_no_record', '2S129/3', 404, '' );
}
foreach( $validating as $reg )
{
\IPS\Email::buildFromTemplate( 'core', 'registration_validate', array( \IPS\Member::loggedIn(), $reg['vid'] ) )->send( \IPS\Member::loggedIn() );
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=validating', 'front', 'register' ), 'reg_email_resent' );
}
/**
* Validate
*
* @return void
*/
protected function validate()
{
if( \IPS\Request::i()->vid AND \IPS\Request::i()->mid )
{
try
{
$record = \IPS\Db::i()->select( '*', 'core_validating', array( 'vid=? AND member_id=? AND ( new_reg=? or email_chg=? )', \IPS\Request::i()->vid, \IPS\Request::i()->mid, 1, 1 ) )->first();
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->error( 'validate_no_record', '2S129/2', 404, '' );
}
/* If we're using user validation, or this was anything other than a new registration (like an email change) we can go ahead and validate */
if( \IPS\Settings::i()->reg_auth_type == 'user' or $record['email_chg'] )
{
\IPS\Member::load( \IPS\Request::i()->mid )->validate();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ), 'validate_confirmation' );
}
/* Otherwise admin still needs to validate so we flag user validated */
else
{
\IPS\Db::i()->update( 'core_validating', array( 'user_verified' => TRUE ), array( 'member_id=?', \IPS\Request::i()->mid ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ), 'validate_email_confirmation' );
}
}
}
/**
* Complete Profile
*
* @return void
*/
protected function complete()
{
/* Build the form */
$form = new \IPS\Helpers\Form( 'form', 'register_button' );
if( !\IPS\Member::loggedIn()->real_name OR \IPS\Member::loggedIn()->name === \IPS\Member::loggedIn()->language()->get('guest') )
{
$form->add( new \IPS\Helpers\Form\Text( 'username', NULL, TRUE, array( 'accountUsername' => \IPS\Member::loggedIn() ) ) );
}
if( !\IPS\Member::loggedIn()->email )
{
$form->add( new \IPS\Helpers\Form\Email( 'email_address', NULL, TRUE, array( 'accountEmail' => TRUE ) ) );
}
$form->addButton( 'cancel', 'link', \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=cancel', 'front', 'register' )->csrf() );
/* Handle the submission */
if ( $values = $form->values() )
{
if( isset( $values['username'] ) )
{
\IPS\Member::loggedIn()->name = $values['username'];
}
if( isset( $values['email_address'] ) )
{
\IPS\Member::loggedIn()->email = $values['email_address'];
if( \IPS\Member::loggedIn()->spamService() == 4 )
{
\IPS\Member::loggedIn()->delete();
\IPS\Output::i()->error( 'spam_denied_account', '2S272/1', 403, '' );
}
/* If email validation is enabled add a validating record */
if( in_array( \IPS\Settings::i()->reg_auth_type, array( 'user', 'admin_user' ) ) )
{
$vid = md5( uniqid() );
\IPS\Db::i()->insert( 'core_validating', array(
'vid' => $vid,
'member_id' => \IPS\Member::loggedIn()->member_id,
'entry_date' => time(),
'new_reg' => 1,
'email_chg' => 0,
'user_verified' => FALSE,
'ip_address' => \IPS\Request::i()->ipAddress()
) );
\IPS\Member::loggedIn()->members_bitoptions['validating'] = TRUE;
}
}
/* Save */
\IPS\Member::loggedIn()->save();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('reg_complete_details');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->completeProfile( $form );
}
/**
* Change Email
*
* @return void
*/
protected function changeEmail()
{
/* Are we logged in and pending validation? */
if( !\IPS\Member::loggedIn()->member_id OR !\IPS\Member::loggedIn()->members_bitoptions['validating'] )
{
\IPS\Output::i()->error( 'no_module_permission', '2C223/2', 403, '' );
}
/* Do we have any pending validation emails? */
try
{
$pending = \IPS\Db::i()->select( '*', 'core_validating', array( 'member_id=? AND ( new_reg=1 or email_chg=1 )', \IPS\Member::loggedIn()->member_id ), 'entry_date DESC' )->first();
}
catch( \UnderflowException $e )
{
$pending = null;
}
/* Build the form */
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\Email( 'new_email', '', TRUE, array( 'accountEmail' => TRUE ) ) );
/* Handle submissions */
if ( $values = $form->values() )
{
/* Change the email */
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
{
try
{
$handler->changeEmail( \IPS\Member::loggedIn(), \IPS\Member::loggedIn()->email, $values['new_email'] );
}
catch( \BadMethodCallException $e ) {}
}
/* Delete any pending validation emails */
if ( $pending['vid'] )
{
\IPS\Db::i()->delete( 'core_validating', array( 'member_id=? AND ( new_reg=1 or email_chg=1 )', \IPS\Member::loggedIn()->member_id ) );
}
$vid = md5( uniqid() );
\IPS\Db::i()->insert( 'core_validating', array(
'vid' => $vid,
'member_id' => \IPS\Member::loggedIn()->member_id,
'entry_date' => time(),
'new_reg' => !$pending or $pending['new_reg'],
'email_chg' => $pending and $pending['email_chg'],
'user_verified' => ( \IPS\Settings::i()->reg_auth_type == 'admin' ) ?: FALSE,
'ip_address' => \IPS\Request::i()->ipAddress()
) );
\IPS\Member::loggedIn()->save();
\IPS\Email::buildFromTemplate( 'core', 'registration_validate', array( \IPS\Member::loggedIn(), $vid ) )->send( \IPS\Member::loggedIn() );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
}
/**
* Cancel Registration
*
* @return void
*/
protected function cancel()
{
/* This bit is kind of important */
\IPS\Session::i()->csrfCheck();
if ( \IPS\Member::loggedIn()->name and \IPS\Member::loggedIn()->email and !\IPS\Db::i()->select( 'COUNT(*)', 'core_validating', array( 'member_id=? AND new_reg=1', \IPS\Member::loggedIn()->member_id ) )->first() )
{
\IPS\Output::i()->error( 'no_module_permission', '2C223/1', 403, '' );
}
/* Delete Member */
\IPS\Member::loggedIn()->delete();
/* Redirect */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ), 'reg_canceled' );
}
}
@@ -0,0 +1,579 @@
<?php
/**
* @brief User CP Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 10 Jun 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* User CP Controller
*/
class _settings extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Output::i()->sidebar['enabled'] = FALSE;
parent::execute();
}
/**
* Settings
*
* @return void
*/
protected function manage()
{
/* Only logged in members */
if ( !\IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'no_module_permission_guest', '2C122/1', 403, '' );
}
/* Work out output */
$area = \IPS\Request::i()->area ?: 'overview';
if ( method_exists( $this, "_{$area}" ) )
{
$output = call_user_func( array( $this, "_{$area}" ) );
}
/* What can we do? */
$canChangeEmail = FALSE;
$canChangePassword = FALSE;
$canChangeUsername = FALSE;
foreach ( \IPS\Login::handlers( TRUE ) as $k => $handler )
{
if ( \IPS\Member::loggedIn()->group['g_dname_changes'] and $handler->canChange( 'username', \IPS\Member::loggedIn() ) )
{
$canChangeUsername = TRUE;
}
if ( $handler->canChange( 'email', \IPS\Member::loggedIn() ) )
{
$canChangeEmail = TRUE;
}
if ( $handler->canChange( 'password', \IPS\Member::loggedIn() ) )
{
$canChangePassword = TRUE;
}
}
$sigLimits = explode( ":", \IPS\Member::loggedIn()->group['g_signature_limits'] );
$canChangeSignature = (bool) ( \IPS\Settings::i()->signatures_enabled && !$sigLimits[0] );
/* Add sync services */
$services = \IPS\core\ProfileSync\ProfileSyncAbstract::services();
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('settings');
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('settings') );
if ( !\IPS\Request::i()->isAjax() )
{
if ( \IPS\Request::i()->service )
{
$area = "{$area}_" . \IPS\Request::i()->service;
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->settings( $area, $output, $canChangeEmail, $canChangePassword, $canChangeUsername, $canChangeSignature, $services );
}
else
{
\IPS\Output::i()->output = $output;
}
}
/**
* Overview
*
* @return string
*/
protected function _overview()
{
$services = array();
foreach ( \IPS\core\ProfileSync\ProfileSyncAbstract::services() as $key => $class )
{
$services[$key] = new $class( \IPS\Member::loggedIn() );
}
return \IPS\Theme::i()->getTemplate( 'system' )->settingsOverview( $services );
}
/**
* Email
*
* @return string
*/
protected function _email()
{
if( \IPS\Member::loggedIn()->isAdmin() )
{
return \IPS\Theme::i()->getTemplate( 'system' )->settingsEmail();
}
/* Do we have any pending validation emails? */
try
{
$pending = \IPS\Db::i()->select( '*', 'core_validating', array( 'member_id=? AND email_chg=1', \IPS\Member::loggedIn()->member_id ), 'entry_date DESC' )->first();
}
catch( \UnderflowException $e )
{
$pending = null;
}
/* Build the form */
$form = new \IPS\Helpers\Form;
$form->addDummy( 'current_email', \IPS\Member::loggedIn()->email );
$form->add( new \IPS\Helpers\Form\Email( 'new_email', '', TRUE, array( 'accountEmail' => TRUE ) ) );
$form->add( new \IPS\Helpers\Form\Password( 'current_password', '', TRUE, array( 'validateFor' => \IPS\Member::loggedIn() ) ) );
/* Handle submissions */
if ( $values = $form->values() )
{
/* Change the email */
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
{
/* We cannot update our email address in some login handlers, that's ok */
try
{
$handler->changeEmail( \IPS\Member::loggedIn(), \IPS\Member::loggedIn()->email, $values['new_email'] );
}
catch( \BadMethodCallException $e ){}
}
/* Delete any pending validation emails */
if ( $pending['vid'] )
{
\IPS\Db::i()->delete( 'core_validating', array( 'member_id=? AND email_chg=1', \IPS\Member::loggedIn()->member_id ) );
}
/* Send a validation email if we need to */
if ( \IPS\Settings::i()->reg_auth_type == 'user' or \IPS\Settings::i()->reg_auth_type == 'admin_user' )
{
$vid = md5( uniqid() );
\IPS\Db::i()->insert( 'core_validating', array(
'vid' => $vid,
'member_id' => \IPS\Member::loggedIn()->member_id,
'entry_date' => time(),
'email_chg' => TRUE,
'ip_address' => \IPS\Request::i()->ipAddress(),
'prev_email' => \IPS\Member::loggedIn()->email
) );
\IPS\Member::loggedIn()->members_bitoptions['validating'] = TRUE;
\IPS\Member::loggedIn()->save();
\IPS\Email::buildFromTemplate( 'core', 'email_change', array( \IPS\Member::loggedIn(), $vid ) )->send( \IPS\Member::loggedIn() );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
/* Or just redirect */
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=email', 'front', 'settings' ), 'email_changed' );
}
}
return \IPS\Theme::i()->getTemplate( 'system' )->settingsEmail( $form );
}
/**
* Password
*
* @return string
*/
protected function _password()
{
if( \IPS\Member::loggedIn()->isAdmin() )
{
return \IPS\Theme::i()->getTemplate( 'system' )->settingsPassword();
}
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\Password( 'current_password', '', TRUE, array( 'validateFor' => \IPS\Member::loggedIn() ) ) );
$form->add( new \IPS\Helpers\Form\Password( 'new_password', '', TRUE ) );
$form->add( new \IPS\Helpers\Form\Password( 'confirm_new_password', '', TRUE, array( 'confirm' => 'new_password' ) ) );
if ( $values = $form->values() )
{
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
{
/* We cannot update our password in some login handlers, that's ok */
try
{
$handler->changePassword( \IPS\Member::loggedIn(), $values['new_password'] );
}
catch( \BadMethodCallException $e ){}
}
\IPS\Member::loggedIn()->members_pass_salt = \IPS\Member::loggedIn()->generateSalt();
\IPS\Member::loggedIn()->members_pass_hash = \IPS\Member::loggedIn()->encryptedPassword( $values['new_password'] );
\IPS\Member::loggedIn()->save();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=password', 'front', 'settings' ), 'password_changed' );
}
return \IPS\Theme::i()->getTemplate( 'system' )->settingsPassword( $form );
}
/**
* Username
*
* @return string
*/
protected function _username()
{
/* Check they have permission to change their username */
if( !\IPS\Member::loggedIn()->group['g_dname_changes'] )
{
\IPS\Output::i()->error( 'username_err_nochange', '1C122/4', 403, '' );
}
if ( \IPS\Member::loggedIn()->group['g_displayname_unit'] )
{
if ( \IPS\Member::loggedIn()->group['gbw_displayname_unit_type'] )
{
if ( \IPS\Member::loggedIn()->joined->diff( \IPS\DateTime::create() )->days < \IPS\Member::loggedIn()->group['g_displayname_unit'] )
{
\IPS\Output::i()->error(
\IPS\Member::loggedIn()->language()->addToStack( 'username_err_days', FALSE, array( 'sprintf' => array(
\IPS\Member::loggedIn()->joined->add(
new \DateInterval( 'P' . \IPS\Member::loggedIn()->group['g_displayname_unit'] . 'D' )
)->localeDate()
), 'pluralize' => array( \IPS\Member::loggedIn()->group['g_displayname_unit'] ) ) ),
'1C122/5', 403, '' );
}
}
else
{
if ( \IPS\Member::loggedIn()->member_posts < \IPS\Member::loggedIn()->group['g_displayname_unit'] )
{
\IPS\Output::i()->error(
\IPS\Member::loggedIn()->language()->addToStack( 'username_err_posts' , FALSE, array( 'sprintf' => array(
( \IPS\Member::loggedIn()->group['g_displayname_unit'] - \IPS\Member::loggedIn()->member_posts )
), 'pluralize' => array( \IPS\Member::loggedIn()->group['g_displayname_unit'] ) ) ),
'1C122/6', 403, '' );
}
}
}
/* How many changes */
$nameCount = \IPS\Db::i()->select( 'COUNT(*) as count, MIN(dname_date) as min_date', 'core_dnames_change', array(
'dname_member_id=? AND dname_date>?',
\IPS\Member::loggedIn()->member_id,
\IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Member::loggedIn()->group['g_dname_date'] . 'D' ) )->getTimestamp()
) )->first();
if ( \IPS\Member::loggedIn()->group['g_dname_changes'] != -1 and $nameCount['count'] >= \IPS\Member::loggedIn()->group['g_dname_changes'] )
{
return \IPS\Theme::i()->getTemplate( 'system' )->settingsUsernameLimitReached( \IPS\Member::loggedIn()->language()->addToStack('username_err_limit', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->group['g_dname_date'] ), 'pluralize' => array( \IPS\Member::loggedIn()->group['g_dname_changes'] ) ) ) );
}
else
{
/* Build form */
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\Text( 'new_username', '', TRUE, array( 'accountUsername' => TRUE ) ) );
/* Handle submissions */
if ( $values = $form->values() )
{
$oldName = \IPS\Member::loggedIn()->name;
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
{
/* We cannot update our username in some login handlers, that's ok */
try
{
$handler->changeUsername( \IPS\Member::loggedIn(), $oldName, $values['new_username'] );
}
catch( \BadMethodCallException $e ){}
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=username', 'front', 'settings' ), 'username_changed' );
}
}
return \IPS\Theme::i()->getTemplate( 'system' )->settingsUsername( $form, $nameCount['count'], \IPS\Member::loggedIn()->group['g_dname_changes'], $nameCount['min_date'] ? \IPS\DateTime::ts( $nameCount['min_date'] ) : \IPS\Member::loggedIn()->joined, \IPS\Member::loggedIn()->group['g_dname_date'] );
}
/**
* Signature
*
* @return string
*/
protected function _signature()
{
/* Check they have permission to change their signature */
$sigLimits = explode( ":", \IPS\Member::loggedIn()->group['g_signature_limits']);
if( !\IPS\Settings::i()->signatures_enabled && !$sigLimits[0] )
{
\IPS\Output::i()->error( 'signatures_disabled', '2C122/C', 403, '' );
}
/* Check limits */
if ( \IPS\Member::loggedIn()->group['g_sig_unit'] )
{
/* Days */
if ( \IPS\Member::loggedIn()->group['gbw_sig_unit_type'] )
{
if ( \IPS\Member::loggedIn()->joined->diff( \IPS\DateTime::create() )->days < \IPS\Member::loggedIn()->group['g_sig_unit'] )
{
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->pluralize(
sprintf(
\IPS\Member::loggedIn()->language()->get('sig_err_days'),
\IPS\Member::loggedIn()->joined->add(
new \DateInterval( 'P' . \IPS\Member::loggedIn()->group['g_sig_unit'] . 'D' )
)->localeDate()
), array( \IPS\Member::loggedIn()->group['g_sig_unit'] ) ),
'1C122/D', 403, '' );
}
}
/* Posts */
else
{
if ( \IPS\Member::loggedIn()->member_posts < \IPS\Member::loggedIn()->group['g_sig_unit'] )
{
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->pluralize(
sprintf(
\IPS\Member::loggedIn()->language()->get('sig_err_posts'),
( \IPS\Member::loggedIn()->group['g_sig_unit'] - \IPS\Member::loggedIn()->member_posts )
), array( \IPS\Member::loggedIn()->group['g_sig_unit'] ) ),
'1C122/E', 403, '' );
}
}
}
/* Build form */
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\YesNo( 'view_sigs', \IPS\Member::loggedIn()->members_bitoptions['view_sigs'], FALSE ) );
$form->add( new \IPS\Helpers\Form\Editor( 'signature', \IPS\Member::loggedIn()->signature, FALSE, array( 'app' => 'core', 'key' => 'Signatures', 'autoSaveKey' => "frontsig-" .\IPS\Member::loggedIn()->member_id, 'attachIds' => array( \IPS\Member::loggedIn()->member_id ) ) ) );
/* Handle submissions */
if ( $values = $form->values() )
{
if( $values['signature'] )
{
/* Check Limits */
$signature = new \DOMDocument;
$signature->loadHTML( $values['signature'] );
$errors = array();
/* Links */
if ( is_numeric( $sigLimits[4] ) and $signature->getElementsByTagName('a')->length > $sigLimits[4] )
{
$errors[] = \IPS\Member::loggedIn()->language()->addToStack('sig_num_links_exceeded');
}
/* Number of Images */
if ( is_numeric( $sigLimits[1] ) and $signature->getElementsByTagName('img')->length > $sigLimits[1] )
{
$errors[] = \IPS\Member::loggedIn()->language()->addToStack('sig_num_images_exceeded');
}
/* Size of images */
if ( ( is_numeric( $sigLimits[2] ) and $sigLimits[2] ) or ( is_numeric( $sigLimits[3] ) and $sigLimits[3] ) )
{
foreach ( $signature->getElementsByTagName('img') as $image )
{
$src = $image->getAttribute('src');
\IPS\Output::i()->parseFileObjectUrls( $src );
$imageProperties = @getimagesize( $src );
if( is_array( $imageProperties ) AND count( $imageProperties ) )
{
if( $imageProperties[0] > $sigLimits[2] OR $imageProperties[1] > $sigLimits[3] )
{
$errors[] = \IPS\Member::loggedIn()->language()->addToStack( 'sig_imagetoobig', FALSE, array( 'sprintf' => array( $src, $sigLimits[2], $sigLimits[3] ) ) );
}
}
else
{
$errors[] = \IPS\Member::loggedIn()->language()->addToStack( 'sig_imagenotretrievable' );
}
}
}
/* Lines */
if ( is_numeric( $sigLimits[5] ) and ( $signature->getElementsByTagName('p')->length + $signature->getElementsByTagName('br')->length ) > $sigLimits[5] )
{
$errors[] = \IPS\Member::loggedIn()->language()->addToStack('sig_num_lines_exceeded');
}
}
if( !empty( $errors ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('sig_restrictions_exceeded');
$form->elements['']['signature']->error = \IPS\Member::loggedIn()->language()->formatList( $errors );
return \IPS\Theme::i()->getTemplate( 'system' )->settingsSignature( $form, $sigLimits );
}
\IPS\Member::loggedIn()->signature = $values['signature'];
\IPS\Member::loggedIn()->members_bitoptions['view_sigs'] = $values['view_sigs'];
\IPS\Member::loggedIn()->save();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=signature', 'front', 'settings' ), 'signature_changed' );
}
return \IPS\Theme::i()->getTemplate( 'system' )->settingsSignature( $form, $sigLimits );
}
/**
* Profile Sync
*
* @return string
*/
protected function _profilesync()
{
$service = \IPS\Request::i()->service;
$class = 'IPS\core\ProfileSync\\' . $service;
if ( !class_exists( $class ) or !isset( $class::$loginKey ) )
{
\IPS\Output::i()->error( 'page_doesnt_exist', '2C122/B', 404, '' );
}
$obj = new $class( \IPS\Member::loggedIn() );
if ( $obj->connected() )
{
if ( isset( \IPS\Request::i()->sync ) )
{
$obj->sync();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=settings&area=profilesync&service={$service}", 'front', "settings_{$service}" ), 'profilesync_synced' );
}
elseif ( isset( \IPS\Request::i()->disassociate ) )
{
/* Check they have another way of signing in */
$isOkay = FALSE;
foreach ( \IPS\Login::handlers() as $handler )
{
if ( $handler->key != $obj::$loginKey and $handler->canProcess( \IPS\Member::loggedIn() ) )
{
$isOkay = TRUE;
break;
}
}
if ( !$isOkay )
{
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'profilesync_cannot_disassociate', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack("profilesync__{$service}") ) ) ), '1C122/I', 403, '' );
}
/* Do it */
$obj->disassociate();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=system&controller=settings&area=profilesync&service={$service}", 'front', "settings_{$service}" ), 'profile_disassociated' );
}
$serviceName = 'profilesync__' . $service;
$headline = ( $obj->name() ) ? \IPS\Member::loggedIn()->language()->addToStack( 'profilesync_headline', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $serviceName ), $obj->name() ) ) ) : \IPS\Member::loggedIn()->language()->addToStack( 'profilesync_headline_no_name', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $serviceName ) ) ) );
$settings = $obj->settings();
$form = new \IPS\Helpers\Form;
$form->class = 'ipsForm_vertical';
$form->add( new \IPS\Helpers\Form\Checkbox( 'profilesync_photo', $settings['photo'], FALSE, array( 'labelSprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $serviceName ) ) ) ) );
if ( method_exists( $obj, 'cover' ) )
{
$form->add( new \IPS\Helpers\Form\Checkbox( 'profilesync_cover', $settings['cover'], FALSE, array( 'labelSprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $serviceName ) ) ) ) );
}
if ( method_exists( $obj, 'status' ) and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members' ) ) and !\IPS\Member::loggedIn()->members_bitoptions['bw_no_status_update'] )
{
$options = array();
if ( !\IPS\Member::loggedIn()->group['gbw_no_status_import'] )
{
$options['import'] = \IPS\Member::loggedIn()->language()->addToStack('profilesync_import_status', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $serviceName ) ) ) );
}
if ( method_exists( $obj, 'exportStatus' ) )
{
$options['export'] = \IPS\Member::loggedIn()->language()->addToStack('profilesync_export_status', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $serviceName ) ) ) );
}
$options[''] = \IPS\Member::loggedIn()->language()->addToStack('profilesync_status_none');
$form->add( new \IPS\Helpers\Form\Radio( 'profilesync_status', $settings['status'], FALSE, array(
'labelSprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $serviceName ) ),
'options' => $options,
'parse' => FALSE
) ) );
}
if ( $values = $form->values() )
{
$obj->save( $values );
}
$photo = $obj->photo();
return \IPS\Theme::i()->getTemplate( 'system' )->settingsProfileSync( $photo instanceof \IPS\File ? $photo->url : $photo, $headline, method_exists( $obj, 'status' ) ? $obj->status() : NULL, $form, $service, "profilesync__{$service}", ( $settings['photo'] or $settings['cover'] or $settings['status'] ) );
}
else
{
$login = \IPS\Login\LoginAbstract::load( $class::$loginKey );
$url = \IPS\Http\Url::internal( "app=core&module=system&controller=settings&area=profilesync&service={$service}", 'front', "settings_{$service}" );
if ( \IPS\Request::i()->loginProcess )
{
try
{
$login->authenticate( $url, \IPS\Member::loggedIn() );
\IPS\Output::i()->redirect( $url );
}
catch ( \IPS\Login\Exception $e ) { }
}
return \IPS\Theme::i()->getTemplate( 'system' )->settingsProfileSyncLogin( $login->loginForm( $url, TRUE ), "profilesync__{$service}" );
}
}
/**
* Disable All Signatures
*
* @return void
*/
protected function toggleSigs()
{
if ( !\IPS\Settings::i()->signatures_enabled )
{
\IPS\Output::i()->error( 'signatures_disabled', '2C122/F', 403, '' );
}
\IPS\Session::i()->csrfCheck();
if ( \IPS\Member::loggedIn()->members_bitoptions['view_sigs'] )
{
\IPS\Member::loggedIn()->members_bitoptions['view_sigs'] = 0;
}
else
{
\IPS\Member::loggedIn()->members_bitoptions['view_sigs'] = 1;
}
\IPS\Member::loggedIn()->save();
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( 'OK' );
}
$redirectUrl = ( !empty( $_SERVER['HTTP_REFERER'] ) ) ? \IPS\Http\Url::external( $_SERVER['HTTP_REFERER'] ) : \IPS\Http\Url::internal( "app=core&module=system&controller=settings", 'front', 'settings' );
\IPS\Output::i()->redirect( $redirectUrl, 'signature_pref_toggled' );
}
}
@@ -0,0 +1,49 @@
<?php
/**
* @brief Splash Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 21 Jun 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Splash Controller
*/
class _splash extends \IPS\Dispatcher\Controller
{
/**
* Splash
*
* @return void
*/
protected function manage()
{
if ( \IPS\Member::loggedIn()->member_id )
{
if ( \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members', 'front' ) ) )
{
\IPS\Output::i()->redirect( \IPS\Member::loggedIn()->url() );
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings', 'front', 'settings' ) );
}
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) );
}
}
}
@@ -0,0 +1,40 @@
<?php
/**
* @brief Terms of Use
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 25 Sept 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Terms of Use
*/
class _terms extends \IPS\Dispatcher\Controller
{
/**
* Terms of Use
*
* @return void
*/
protected function manage()
{
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=core&module=system&controller=terms', NULL, 'terms' ), array(), 'loc_viewing_reg_terms' );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('reg_terms');
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->terms();
}
}
@@ -0,0 +1,63 @@
<?php
/**
* @brief Theme Changer
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 17 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Theme Changer
*/
class _theme extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
parent::execute();
}
/**
* Manage
*
* @return void
*/
protected function manage()
{
\IPS\Session::i()->csrfCheck();
if( \IPS\Member::loggedIn()->member_id )
{
\IPS\Member::loggedIn()->skin = (int) \IPS\Request::i()->id;
\IPS\Member::loggedIn()->save();
}
else
{
\IPS\Request::i()->setCookie( 'theme', (int) \IPS\Request::i()->id );
}
/* Make sure VSE cookie is killed */
if ( isset( \IPS\Request::i()->cookie['vseThemeId'] ) )
{
\IPS\Request::i()->setCookie( 'vseThemeId', 0 );
}
\IPS\Output::i()->redirect( ( !empty( $_SERVER['HTTP_REFERER'] ) ) ? \IPS\Http\Url::external( $_SERVER['HTTP_REFERER'] ) : \IPS\Http\Url::internal( '' ) );
}
}
@@ -0,0 +1,63 @@
<?php
/**
* @brief Allow users to unsubscribe from site updates
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 12 Jun 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Unsubscribe
*/
class _unsubscribe extends \IPS\Dispatcher\Controller
{
/**
* Unsubscribe the user
*
* @return void
*/
protected function manage()
{
/* Get the member being requested */
if( empty( \IPS\Request::i()->email ) )
{
\IPS\Output::i()->error( 'no_user_to_unsubscribe', '2S127/3', 404, '' );
}
$member = \IPS\Member::load( \IPS\Request::i()->email, 'email' );
if( !$member->member_id )
{
\IPS\Output::i()->error( 'no_user_to_unsubscribe', '2S127/2', 404, '' );
}
/* Verify the key is correct */
if ( \IPS\Request::i()->key == md5( $member->email . ':' . $member->members_pass_hash ) )
{
/* Set the member not to receive future emails */
$member->allow_admin_mails = 0;
$member->save();
/* And then show them a confirmation screen */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('unsubscribed');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->unsubscribed();
}
else
{
/* Key did not match */
\IPS\Output::i()->error( 'no_user_to_unsubscribe', '3S127/4', 403, '' );
}
}
}
@@ -0,0 +1,111 @@
<?php
/**
* @brief Visual Language Editor
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 27 Jun 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Visual Language Editor
*/
class _vle extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
if ( !\IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'languages', 'lang_words' ) )
{
\IPS\Output::i()->json( 'NO_PERMISSION', 403 );
}
return parent::execute();
}
/**
* Get
*
* @return void
*/
public function get()
{
try
{
$word = \IPS\Member::loggedIn()->language()->get( \IPS\Request::i()->key );
}
catch ( \UnderflowException $e )
{
$word = NULL;
}
\IPS\Output::i()->json( $word );
}
/**
* Set
*
* @return void
*/
public function set()
{
try
{
$word = \IPS\Db::i()->select( '*', 'core_sys_lang_words', array( 'lang_id=? AND word_key=?', \IPS\Member::loggedIn()->language()->id, \IPS\Request::i()->key ) )->first();
}
catch( \UnderflowException $e )
{
$word = NULL;
}
if ( $word !== NULL )
{
if ( $word['word_export'] )
{
\IPS\Db::i()->update( 'core_sys_lang_words', array( 'word_custom' => \IPS\Request::i()->value, 'word_custom_version' => \IPS\Application::load( $word['word_app'] )->long_version ), array( 'word_id=?', $word['word_id'] ) );
}
else
{
\IPS\Lang::saveCustom( $word['word_app'], $word['word_key'], array( \IPS\Member::loggedIn()->language()->id => \IPS\Request::i()->value ) );
}
$string = \IPS\Request::i()->value ?: $word['word_default'];
}
else
{
\IPS\Lang::saveCustom( 'core', \IPS\Request::i()->key, array( \IPS\Member::loggedIn()->language()->id => \IPS\Request::i()->value ) );
$string = \IPS\Request::i()->value;
}
\IPS\Db::i()->insert( 'core_admin_logs', array(
'member_id' => \IPS\Member::loggedIn()->member_id,
'ctime' => time(),
'note' => json_encode( array( $word['word_key'] => FALSE, \IPS\Member::loggedIn()->language()->title => FALSE ) ),
'ip_address' => \IPS\Request::i()->ipAddress(),
'appcomponent' => 'core',
'module' => 'system',
'controller' => 'vle',
'do' => 'set',
'lang_key' => 'acplogs__lang_translate'
) );
\IPS\Widget::deleteCaches();
\IPS\Output::i()->sendOutput( $string, 200, 'text/text' );
}
}
@@ -0,0 +1,694 @@
<?php
/**
* @brief New Content
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 18 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* New Content
*/
class _vnc extends \IPS\Dispatcher\Controller
{
/**
* New Content
*
* @return void
*/
public function manage()
{
/* Flood control */
\IPS\Request::floodCheck();
if( isset( \IPS\Request::i()->nodes ) )
{
\IPS\Request::i()->nodes = urldecode( \IPS\Request::i()->nodes );
}
/* Logged in only */
if ( !\IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'no_module_permission_guest', '2C232/1', 403, '' );
}
elseif( !\IPS\Request::i()->updateFilters )
{
$preferences = json_decode( \IPS\Member::loggedIn()->vnc_preferences, TRUE );
if( isset( $preferences['onlyFollowed'] ) AND !isset( \IPS\Request::i()->onlyFollowed ) )
{
\IPS\Request::i()->onlyFollowed = $preferences['onlyFollowed'];
}
if( isset( $preferences['onlyParticipated'] ) AND !isset( \IPS\Request::i()->onlyParticipated ) )
{
\IPS\Request::i()->onlyParticipated = $preferences['onlyParticipated'];
}
if( isset( $preferences['onlyStarted'] ) AND !isset( \IPS\Request::i()->onlyStarted ) )
{
\IPS\Request::i()->onlyStarted = $preferences['onlyStarted'];
}
if( isset( $preferences['onlyUnread'] ) AND !isset( \IPS\Request::i()->onlyUnread ) )
{
\IPS\Request::i()->onlyUnread = $preferences['onlyUnread'];
}
if( isset( $preferences['searchType'] ) AND !isset( \IPS\Request::i()->type ) )
{
\IPS\Request::i()->type = $preferences['searchType'];
}
if( isset( $preferences['vncTimePeriod'] ) AND !isset( \IPS\Request::i()->vncTimePeriod ) )
{
\IPS\Request::i()->vncTimePeriod = $preferences['vncTimePeriod'];
}
if( isset( $preferences['container'] ) AND !isset( \IPS\Request::i()->nodes ) )
{
\IPS\Request::i()->nodes = $preferences['container'];
}
}
/* Though this isn't part of search, disabling the search module will disable it */
if ( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'search' ) ) )
{
\IPS\Output::i()->error( 'no_module_permission', '2C232/2', 403, '' );
}
/* Init */
$baseUrl = \IPS\Http\Url::internal( 'app=core&module=system&controller=vnc&updateFilters=1', 'front', 'vnc' );
$nodeSelect = NULL;
$nodeTitle = NULL;
/* Get types */
$types = array();
foreach ( \IPS\Content::routedClasses( TRUE, FALSE, TRUE ) as $class )
{
if( is_subclass_of( $class, 'IPS\Content\ReadMarkers' ) )
{
$key = mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) );
$types[ $key ] = $class;
}
}
/* If a user last filtered by "downloads_file" and then the download manager app was disabled we need to clear this otherwise you get a fatal error */
if ( \IPS\Request::i()->type AND \IPS\Request::i()->type !== 'all' AND !isset( $types[ \IPS\Request::i()->type ] ) )
{
\IPS\Request::i()->type = '';
}
/* Force a type if only one available */
if( count( $types ) == 1 )
{
$keys = array_keys( $types );
\IPS\Request::i()->type = array_shift( $keys );
}
/* Set filters */
$where = array();
$start = NULL;
$end = NULL;
$onlyUnread = FALSE;
if ( isset( \IPS\Request::i()->onlyUnread ) and \IPS\Request::i()->onlyUnread )
{
$baseUrl = $baseUrl->setQueryString( 'onlyUnread', 1 );
$onlyUnread = TRUE;
}
$onlyFollowed = FALSE;
if ( isset( \IPS\Request::i()->onlyFollowed ) and \IPS\Request::i()->onlyFollowed )
{
$baseUrl = $baseUrl->setQueryString( 'onlyFollowed', 1 );
$onlyFollowed = TRUE;
$where[] = array( 'follow_id IS NOT NULL AND follow_member_id =?', \IPS\Member::loggedIn()->member_id );
}
$onlyParticipated = FALSE;
if ( isset( \IPS\Request::i()->onlyParticipated ) and \IPS\Request::i()->onlyParticipated )
{
$baseUrl = $baseUrl->setQueryString( 'onlyParticipated', 1 );
$onlyParticipated = TRUE;
}
$onlyStarted = FALSE;
if ( isset( \IPS\Request::i()->onlyStarted ) and \IPS\Request::i()->onlyStarted )
{
$baseUrl = $baseUrl->setQueryString( 'onlyStarted', 1 );
$onlyStarted = TRUE;
}
/* Get cutoff */
$interval = NULL;
$vncTimePeriod = NULL;
if ( isset( \IPS\Request::i()->vncTimePeriod ) )
{
$vncTimePeriod = \IPS\Request::i()->vncTimePeriod;
$baseUrl = $baseUrl->setQueryString( 'vncTimePeriod', $vncTimePeriod );
if ( isset( \IPS\Request::i()->vncTime ) )
{
$start = \IPS\DateTime::ts( \IPS\Request::i()->vncTime, TRUE );
}
switch ( $vncTimePeriod )
{
case 'all':
$cutoff = NULL;
break;
case 'day':
$interval = new \DateInterval( 'P1D' );
if ( !$start )
{
$start = \IPS\DateTime::ts( \IPS\DateTime::create()->getTimestamp(), TRUE )->sub( $interval );
}
else
{
$end = \IPS\DateTime::ts( $start->getTimestamp(), TRUE )->add( $interval );
}
break;
case 'week':
$interval = new \DateInterval( 'P1W' );
if ( !$start )
{
$start = \IPS\DateTime::ts( \IPS\DateTime::create()->getTimestamp(), TRUE )->sub( $interval );
}
else
{
$end = \IPS\DateTime::ts( $start->getTimestamp(), TRUE )->add( $interval );
}
break;
case 'month':
$interval = new \DateInterval( 'P1M' );
if ( !$start )
{
$start = \IPS\DateTime::create()->sub( $interval );
}
else
{
$end = \IPS\DateTime::ts( $start->getTimestamp(), TRUE )->add( $interval );
}
break;
default:
$start = \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit, TRUE );
break;
}
}
else
{
$start = \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit, TRUE );
}
if( \IPS\Member::loggedIn()->member_id and isset( \IPS\Request::i()->updateFilters ) )
{
$vncPreferences = json_encode( array(
'onlyFollowed' => $onlyFollowed,
'onlyParticipated' => $onlyParticipated,
'onlyStarted' => $onlyStarted,
'onlyUnread' => $onlyUnread,
'searchType' => \IPS\Request::i()->type ?: NULL,
'vncTimePeriod' => $vncTimePeriod,
'container' => \IPS\Request::i()->nodes ?: NULL,
) );
if ( $vncPreferences != \IPS\Member::loggedIn()->vnc_preferences )
{
\IPS\Member::loggedIn()->vnc_preferences = $vncPreferences;
\IPS\Member::loggedIn()->save();
}
}
/* Get results - if we're just searching one type, it's a bit simpler */
if ( \IPS\Request::i()->type AND \IPS\Request::i()->type !== 'all' )
{
/* Init */
$baseUrl = $baseUrl->setQueryString( 'type', \IPS\Request::i()->type );
$class = $types[ \IPS\Request::i()->type ];
if ( $onlyUnread )
{
$unreadWhere = $this->_getUnreadWhere( $class );
if ( count( $unreadWhere ) )
{
foreach( $unreadWhere as $id => $item )
{
$where[] = $item;
}
}
}
/* Where */
if ( $onlyParticipated or $onlyStarted )
{
if( isset( $class::$databaseColumnMap['author'] ) )
{
$participatedWhere[] = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['author'] . '=' . \IPS\Member::loggedIn()->member_id;
}
if ( !$onlyStarted )
{
if( isset( $class::$commentClass ) )
{
$commentClass = $class::$commentClass;
$participatedWhere[] = '(' . str_replace( "`", '', (string) \IPS\Db::i()->select( 'COUNT(*)', $commentClass::$databaseTable, $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['author'] . '=' . \IPS\Member::loggedIn()->member_id . ' AND ' .
$commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'] . '=' . $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnId ) ) . ') > 0';
}
if( isset( $class::$reviewClass ) )
{
$reviewClass = $class::$reviewClass;
$participatedWhere[] = '(' . str_replace( "`", '', (string) \IPS\Db::i()->select( 'COUNT(*)', $reviewClass::$databaseTable, $reviewClass::$databaseTable . '.' . $reviewClass::$databasePrefix . $reviewClass::$databaseColumnMap['author'] . '=' . \IPS\Member::loggedIn()->member_id . ' AND ' .
$reviewClass::$databaseTable . '.' . $reviewClass::$databasePrefix . $reviewClass::$databaseColumnMap['item'] . '=' . $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnId ) ) . ') > 0';
}
}
$where[] = array( '( ' . implode( ' OR ', $participatedWhere ) . ' )' );
}
/* Node Filter */
if ( $class::$containerNodeClass )
{
$node = NULL;
$nodeClass = $class::$containerNodeClass;
$nodeTitle = \IPS\Member::loggedIn()->language()->addToStack( $nodeClass::$nodeTitle );
if ( isset( \IPS\Request::i()->nodes ) and \IPS\Request::i()->nodes )
{
try
{
$baseUrl = $baseUrl->setQueryString( 'nodes', \IPS\Request::i()->nodes );
$where[] = array( \IPS\Db::i()->in( $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['container'], is_array( \IPS\Request::i()->nodes ) ? \IPS\Request::i()->nodes : explode( ',', \IPS\Request::i()->nodes ) ) );
}
catch ( \OutOfRangeException $e ) { }
}
$nodeSelect = new \IPS\Helpers\Form\Node( 'nodes', ( is_array( \IPS\Request::i()->nodes ) ) ? \IPS\Request::i()->nodes : explode( ',', \IPS\Request::i()->nodes ), FALSE, array( 'class' => $class::$containerNodeClass, 'permissionCheck' => 'view', 'url' => $baseUrl, 'multiple' => TRUE ) );
}
/* Cutoff */
$dateColumnExpression = $this->_getDateExpression( $class );
if ( $start )
{
$where[] = array( $dateColumnExpression . '>?', $start->getTimestamp() );
}
if ( $end )
{
$where[] = array( $dateColumnExpression . '<?', $end->getTimestamp() );
}
if ( isset( $class::$databaseColumnMap['state'] ) )
{
$where[] = array( $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['state'] . "!=?", 'link' );
}
/* Create table */
$table = new \IPS\Helpers\Table\Content( $class, $baseUrl, $where, NULL, NULL, 'read', FALSE );
$table->classes[] = 'ipsDataList_zebra';
$table->sortOptions = array();
$table->noModerate = TRUE;
/* Joins */
if ( $onlyFollowed )
{
$followArea = mb_strtolower( mb_substr( $class, mb_strrpos( $class, '\\' ) + 1 ) );
$table->joins[] = array( 'from' => 'core_follow', 'where' => array( "follow_app=? AND follow_area=? AND follow_member_id=? AND follow_rel_id={$class::$databasePrefix}{$class::$databaseColumnId}", $class::$application, $followArea, \IPS\Member::loggedIn()->member_id ) );
}
}
/* If we're searching them all, we need to go all union */
else
{
/* Build the selects */
$selects = array();
foreach ( $types as $key => $class )
{
$dateColumnExpression = $this->_getDateExpression( $class );
/* Normalize the columns */
$contentWhere = array();
$columns = array(
$class::$databaseTable . "." . $class::$databasePrefix.$class::$databaseColumnId => 'id',
$dateColumnExpression => 'date',
$class::$databaseTable . "." . $class::$databasePrefix.$class::$databaseColumnMap['author'] => 'author'
);
if ( in_array( 'IPS\Content\Hideable', class_implements( $class ) ) and !\IPS\Member::loggedIn()->modPermission( "can_view_hidden_content" ) )
{
if ( $class::$databaseColumnMap['approved'] )
{
$columns[ $class::$databaseTable . "." . $class::$databasePrefix.$class::$databaseColumnMap['approved'] . '-1' ] = 'hidden';
$contentWhere[] = array( $class::$databaseTable . "." . $class::$databasePrefix.$class::$databaseColumnMap['approved'] . '-1=0' );
}
else
{
$columns[ $class::$databaseTable . "." . $class::$databasePrefix.$class::$databaseColumnMap['hidden'] ] = 'hidden';
$contentWhere[] = array( $class::$databaseTable . "." . $class::$databasePrefix.$class::$databaseColumnMap['hidden'] . '=0' );
}
}
$select = array( "'".str_replace( '\\', '\\\\' , $class ) ."' AS class" );
foreach ( $columns as $local => $normalized )
{
$select[] = "{$local} AS {$normalized}";
}
if ( $onlyFollowed )
{
$select[] = "'".$class::$application."' AS _app";
$followArea = mb_strtolower( mb_substr( $class, mb_strrpos( $class, '\\' ) + 1 ) );
$select[] = "'{$followArea}' AS _follow_area";
}
$select = implode( ', ', $select );
/* Permissions */
if ( in_array( 'IPS\Content\Permissions', class_implements( $class ) ) )
{
$containerClass = $class::$containerNodeClass;
$categories = array();
foreach( \IPS\Db::i()->select( 'perm_type_id', 'core_permission_index', array( "core_permission_index.app='" . $containerClass::$permApp . "' AND core_permission_index.perm_type='" . $containerClass::$permType . "' AND (" . \IPS\Db::i()->findInSet( 'perm_' . $containerClass::$permissionMap['read'], \IPS\Member::loggedIn()->groups ) . ' OR ' . 'perm_' . $containerClass::$permissionMap['read'] . "='*' )" ) ) as $result )
{
$categories[] = $result;
}
if( count( $categories ) )
{
$contentWhere[] = array( $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['container'] . ' IN(' . implode( ',', $categories ) . ')' );
}
else
{
$contentWhere[] = array( $class::$databaseTable . "." . $class::$databasePrefix . $class::$databaseColumnMap['container'] . '=0' );
}
}
/* Future */
if ( in_array( 'IPS\Content\FuturePublishing', class_implements( $class ) ) and !$class::canViewFutureItems() )
{
$authorCol = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['author'];
$col = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['is_future_entry'];
$contentWhere[] = array( "( {$col}=0 OR ( {$col}=1 AND {$authorCol}=" . \IPS\Member::loggedIn()->member_id . " ) )" );
}
/* Add app-sepcific wheres */
$joinContainer = FALSE;
$joins = array();
$vncWhere = $class::vncWhere( $joinContainer, $joins );
if ( is_array( $vncWhere ) )
{
foreach( $vncWhere as $key => $value )
{
if ( $key ==='item' )
{
$contentWhere = array_merge( $contentWhere, $value );
}
else if ( $key === 'container' )
{
$contentWhere = array_merge( $contentWhere, $value );
}
else
{
$contentWhere[] = $value;
}
}
}
/* Only unread */
if ( $onlyUnread )
{
$unreadWhere = $this->_getUnreadWhere( $class );
if ( count( $unreadWhere ) )
{
foreach( $unreadWhere as $id => $item )
{
$contentWhere[] = $item;
}
}
}
/* Participated Only */
if ( $onlyParticipated or $onlyStarted )
{
$participatedWhere = array();
if( isset( $class::$databaseColumnMap['author'] ) )
{
$participatedWhere[] = $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['author'] . '=' . \IPS\Member::loggedIn()->member_id;
}
if ( !$onlyStarted )
{
if( isset( $class::$commentClass ) )
{
$commentClass = $class::$commentClass;
$participatedWhere[] = '(' . str_replace( "`", '', (string) \IPS\Db::i()->select( 'COUNT(*)', $commentClass::$databaseTable, $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['author'] . '=' . \IPS\Member::loggedIn()->member_id . ' AND ' .
$commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'] . '=' . $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnId ) ) . ') > 0';
}
if( isset( $class::$reviewClass ) )
{
$reviewClass = $class::$reviewClass;
$participatedWhere[] = '(' . str_replace( "`", '', (string) \IPS\Db::i()->select( 'COUNT(*)', $reviewClass::$databaseTable, $reviewClass::$databaseTable . '.' . $reviewClass::$databasePrefix . $reviewClass::$databaseColumnMap['author'] . '=' . \IPS\Member::loggedIn()->member_id . ' AND ' .
$reviewClass::$databaseTable . '.' . $reviewClass::$databasePrefix . $reviewClass::$databaseColumnMap['item'] . '=' . $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnId ) ) . ') > 0';
}
}
$contentWhere[] = '( ' . implode( ' OR ', $participatedWhere ) . ' )';
}
if ( isset( $class::$databaseColumnMap['state'] ) )
{
$contentWhere[] = array( $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['state'] . "!='link'" );
}
/* Add to the list */
$select = \IPS\Db::i()->select( $select, $class::$databaseTable, $contentWhere );
if ( $joinContainer )
{
$containerClass = $class::$containerNodeClass;
$select->join( $containerClass::$databaseTable, $class::$databaseTable . "." . $class::$databasePrefix . $class::$databaseColumnMap['container'] . '=' . $containerClass::$databaseTable . "." . $containerClass::$databasePrefix . $containerClass::$databaseColumnId );
}
if ( count( $joins ) )
{
foreach ( $joins as $join )
{
$select->join( $join['from'], $join['where'] );
}
}
$selects[] = $select;
}
/* Cutoff */
if ( $start )
{
$where[] = array( 'date>?', $start->getTimestamp() );
}
if ( $end )
{
$where[] = array( 'date<?', $end->getTimestamp() );
}
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
/* Run */
$results = \IPS\Db::i()->union( $selects, 'date DESC', array( ( ( $page - 1 ) * 25 ), 25 ), ( $onlyFollowed ) ? '_app, _follow_area, id' : NULL, FALSE, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS, $where );
/* Joins */
if ( $onlyFollowed )
{
$results->join( 'core_follow', "follow_app=_app AND follow_area=_follow_area AND follow_rel_id=id" );
}
$resultPages = ceil( $results->count( TRUE ) / 25 );
/* Build a table */
$table = new \IPS\Helpers\Table\Custom( iterator_to_array( $results ), $baseUrl );
$table->classes[] = 'ipsDataList_zebra';
$table->pages = $resultPages;
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'vnc' ), 'genericRows' );
}
/* Display */
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array(
'sidebar' => \IPS\Theme::i()->getTemplate('vnc')->filters( $baseUrl, $types, $nodeSelect, $nodeTitle ),
'content' => \IPS\Theme::i()->getTemplate('vnc')->results( $baseUrl, (string) $table, \IPS\Request::i()->vncTimePeriod, $interval, $start, $end ?: \IPS\DateTime::create() ),
) );
}
else
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_vnc.js', 'core' ) );
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('search_vnc_title') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('search_vnc_title');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('vnc')->template( $baseUrl, $types, (string) $table, \IPS\Request::i()->vncTimePeriod, $interval, $start, $end ?: \IPS\DateTime::create(), $nodeSelect, $nodeTitle );
}
}
/**
* Get the 'unread' where SQL
*
* @param string $class Content class (\IPS\forums\Forum)
* @return array
*/
protected function _getUnreadWhere( $class )
{
$classBits = explode( "\\", $class );
$application = $classBits[1];
$resetTimes = \IPS\Member::loggedIn()->markersResetTimes( $application );
$oldestTime = time();
$markers = array();
$excludeIds = array();
$where = array();
$unreadWheres = array();
$containerIds = array();
$containerClass = ( $class::$containerNodeClass ) ? $class::$containerNodeClass : NULL;
/* What is the best date column? */
$dateColumns = array();
foreach ( array( 'updated', 'last_comment', 'last_review' ) as $k )
{
if ( isset( $class::$databaseColumnMap[ $k ] ) )
{
if ( is_array( $class::$databaseColumnMap[ $k ] ) )
{
foreach ( $class::$databaseColumnMap[ $k ] as $v )
{
$dateColumns[] = " IFNULL( " . $class::$databaseTable . '.'. $class::$databasePrefix . $v . ", 0 )";
}
}
else
{
$dateColumns[] = " IFNULL( " . $class::$databaseTable . '.'. $class::$databasePrefix . $class::$databaseColumnMap[ $k ] . ", 0 )";
}
}
}
$dateColumnExpression = count( $dateColumns ) > 1 ? ( 'GREATEST(' . implode( ',', $dateColumns ) . ')' ) : array_pop( $dateColumns );
foreach( $resetTimes as $containerId => $timestamp )
{
$container = NULL;
if( $containerId AND $containerClass )
{
try
{
$container = $containerClass::load( $containerId );
}
catch ( \OutOfRangeException $e)
{
continue;
}
}
$timestamp = $timestamp ?: \IPS\Member::loggedIn()->marked_site_read;
$containerIds[] = $containerId;
$unreadWheres[] = '( ' . $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['container'] . '=' . $containerId . ' AND ' . $dateColumnExpression . ' > ' . (int) $timestamp . ')';
$items = \IPS\Member::loggedIn()->markersItems( $application, \IPS\Content\Item::makeMarkerKey( $container ) );
if ( count( $items ) )
{
foreach( $items as $mid => $mtime )
{
if ( $mtime > $timestamp )
{
$markers[ $mtime . '.' . $mid ] = $mid;
}
}
}
}
if( count( $containerIds ) )
{
$unreadWheres[] = "( " . $dateColumnExpression . " > " . \IPS\Member::loggedIn()->marked_site_read . " AND ( " . $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnMap['container'] . " NOT IN(" . implode( ',', $containerIds ) . ") ) )";
}
else
{
$unreadWheres[] = "( " . $dateColumnExpression . " > " . \IPS\Member::loggedIn()->marked_site_read . ")";
}
if( count( $unreadWheres ) )
{
$where[] = array( "(" . implode( " OR ", $unreadWheres ) . ")" );
}
if ( count( $markers ) )
{
/* Avoid packet issues */
krsort( $markers );
$useIds = array_flip( array_slice( $markers, 0, 500, TRUE ) );
$select = '';
$from = '';
$notIn = array();
foreach( \IPS\Db::i()->select( $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnId. ' as _id, ' . $dateColumnExpression . ' as _date', $class::$databaseTable, \IPS\Db::i()->in( $class::$databasePrefix . $class::$databaseColumnId, array_keys( $useIds ) ) ) as $row )
{
if ( isset( $useIds[ $row['_id'] ] ) )
{
if ( $useIds[ $row['_id'] ] >= $row['_date'] )
{
/* Still read */
$notIn[] = intval( $row['_id'] );
}
}
}
if ( count( $notIn ) )
{
$where[] = array( "( " . $class::$databaseTable . '.' . $class::$databasePrefix . $class::$databaseColumnId . " NOT IN (" . implode( ',', $notIn ) . ") )" );
}
}
return $where;
}
/**
* Get the date Column expression
*
* @param string $class Content class (\IPS\forums\Forum)
* @return string
*/
protected function _getDateExpression( $class )
{
/* What is the best date column? */
$dateColumns = array();
foreach ( array( 'updated', 'last_comment', 'last_review' ) as $k )
{
if ( isset( $class::$databaseColumnMap[ $k ] ) )
{
if ( is_array( $class::$databaseColumnMap[ $k ] ) )
{
foreach ( $class::$databaseColumnMap[ $k ] as $v )
{
$dateColumns[] = " IFNULL( " . $class::$databaseTable . '.'. $class::$databasePrefix . $v . ", 0 )";
}
}
else
{
$dateColumns[] = " IFNULL( " . $class::$databaseTable . '.'. $class::$databasePrefix . $class::$databaseColumnMap[ $k ] . ", 0 )";
}
}
}
return count( $dateColumns ) > 1 ? ( 'GREATEST(' . implode( ',', $dateColumns ) . ')' ) : array_pop( $dateColumns );
}
}
@@ -0,0 +1,214 @@
<?php
/**
* @brief Visual Theme Editor
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 7 Nov 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Visual Language Editor
*/
class _vse extends \IPS\Dispatcher\Controller
{
/**
* Shows the VSE
*
* @return void
*/
public function show()
{
if ( ! \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'customization', 'theme_easy_editor' ) OR ! \IPS\Member::loggedIn()->isAdmin() OR ! \IPS\Member::loggedIn()->members_bitoptions['bw_using_skin_gen'] )
{
\IPS\Output::i()->error( 'core_theme_cant_easy_mode', '2S164/1', 403, '' );
}
$theme = null;
if ( isset( \IPS\Request::i()->cookie['vseThemeId'] ) and \IPS\Request::i()->cookie['vseThemeId'] )
{
try
{
$theme = \IPS\Theme::load( intval( \IPS\Request::i()->cookie['vseThemeId'] ) );
if ( ! $theme->by_skin_gen )
{
$theme = null;
}
}
catch( \OutOfRangeException $ex )
{
$theme = null;
}
}
if ( $theme === null )
{
\IPS\Output::i()->error( 'core_theme_cant_easy_mode', '2S164/2', 403, '' );
}
/* CSS */
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'framework.css', 'core', 'front' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/vse.css', 'core', 'front' ) );
/* JS */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'library.js' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'js/jslang.php?langId=' . \IPS\Member::loggedIn()->language()->id, 'core', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jscolor/jscolor.js', 'core', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'framework.js' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'app.js' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'vse/vsedata.js', 'core', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_vse.js', 'core', 'front' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/diff_match_patch.js', 'core', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/codemirror.js', 'core', 'interface' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'codemirror/codemirror.css', 'core', 'interface' ) );
$css = $theme->getRawCss( 'core', 'front', 'custom', \IPS\Theme::RETURN_ALL, true );
$vseCss = null;
$customCss = null;
/* VSE CSS */
if ( isset( $css['core']['front']['custom']['vse.css'] ) )
{
$functionName = "css_" . uniqid();
\IPS\Theme::makeProcessFunction( \IPS\Theme::fixResourceTags( $css['core']['front']['custom']['vse.css']['css_content'], 'front' ), $functionName, '', FALSE, TRUE );
$vseCss = call_user_func( 'IPS\\Theme\\'. $functionName );
}
if ( isset( $css['core']['front']['custom']['custom.css'] ) )
{
/* Custom CSS */
$functionName = "css_" . uniqid();
\IPS\Theme::makeProcessFunction( \IPS\Theme::fixResourceTags( $css['core']['front']['custom']['custom.css']['css_content'], 'front' ), $functionName, '', FALSE, TRUE );
$customCss = call_user_func( 'IPS\\Theme\\'. $functionName );
}
$form = new \IPS\Helpers\Form( 'form', NULL );
$settings = $theme->getThemeSettings();
$settingKeyValues = array();
foreach( $settings as $key => $data )
{
$settingKeyValues[ $key ] = $data['_value'];
if ( $data['sc_show_in_vse'] )
{
$value = ( isset( $data['sv_value'] ) ) ? $data['sv_value'] : $data['sc_default'];
$data['sc_type'] = ( empty( $data['sc_type'] ) ) ? 'Text' : $data['sc_type'];
$class = '\IPS\Helpers\Form\\' . $data['sc_type'];
$options = array();
switch ( $data['sc_type'] )
{
case 'Text':
case 'TextArea':
case 'Select':
$options['sc_multiple'] = $data['sc_multiple'];
// No break
case 'Radio':
$content = json_decode( $data['sc_content'], TRUE );
$options['options'] = ( is_array( $content ) ) ? $content : array();
break;
}
$field = new $class( "core_theme_setting_title_{$data['sc_id']}", $value, false, $options );
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $data['sc_title'] );
$form->add( $field );
}
}
/* Template */
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'vse', 'core', 'front' )->globalTemplate( $vseCss, $customCss, $settingKeyValues, (string) $form, $theme->skin_gen_data );
\IPS\Output::i()->sendOutput( \IPS\Output::i()->output, 200, 'text/html' );
}
/**
* Close the VSE
*
* @return void
*/
public function close()
{
/* Update the current member */
\IPS\Member::loggedIn()->members_bitoptions['bw_using_skin_gen'] = 0;
\IPS\Member::loggedIn()->save();
\IPS\Request::i()->setCookie( 'vseThemeId', 0 );
\IPS\Output::i()->json( 'ok' );
}
/**
* Home
*
* @return void
*/
protected function home()
{
\IPS\Session::i()->csrfCheck();
\IPS\Member::loggedIn()->skin = (int) \IPS\Request::i()->id;
\IPS\Member::loggedIn()->save();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ) );
}
/**
* Execute
*
* @return void
*/
public function build()
{
if ( ! \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'customization', 'theme_easy_editor' ) OR ! \IPS\Member::loggedIn()->isAdmin() OR ! \IPS\Member::loggedIn()->members_bitoptions['bw_using_skin_gen'] )
{
\IPS\Output::i()->json( 'NO_PERMISSION', 403 );
}
$theme = null;
if ( isset( \IPS\Request::i()->cookie['vseThemeId'] ) )
{
$theme = \IPS\Theme::load( intval( \IPS\Request::i()->cookie['vseThemeId'] ) );
if ( ! $theme->by_skin_gen )
{
$theme = null;
}
}
if ( $theme === null )
{
\IPS\Output::i()->json( 'NO_PERMISSION', 403 );
}
$theme->vseSave( \IPS\Request::i()->css, \IPS\Request::i()->customcss, \IPS\Request::i()->settings, \IPS\Request::i()->values );
\IPS\File::getClass('core_Theme')->deleteContainer( 'css_built_' . $this->id );
$theme->css_map = array();
$theme->save();
foreach( $theme->children() as $child )
{
\IPS\File::getClass('core_Theme')->deleteContainer( 'css_built_' . $child->id );
$child->css_map = array();
$child->save();
}
\IPS\Output::i()->json( array( 'status' => 'ok', 'theme_set_id' => $theme->id ) );
}
}
@@ -0,0 +1,375 @@
<?php
/**
* @brief Member Warnings
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 18 Jul 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Warnings
*/
class _warnings extends \IPS\Content\Controller
{
/**
* [Content\Controller] Class
*/
protected static $contentModel = 'IPS\core\Warnings\Warning';
/**
* Rebuilt FURL
*/
protected $rebuiltUrl = NULL;
/**
* Execute
*
* @return void
*/
public function execute()
{
parent::execute();
if ( !\IPS\Settings::i()->warn_on )
{
\IPS\Output::i()->error( 'warning_system_disabled', '2C184/7', 403, '' );
}
}
/**
* View List
*
* @return void
*/
protected function manage()
{
/* Load the member */
$member = \IPS\Member::load( \IPS\Request::i()->id );
if ( !$member->member_id )
{
\IPS\Output::i()->error( 'node_error', '2C135/A', 403, '' );
}
/* Check permission */
if ( !( \IPS\Settings::i()->warn_on AND ( \IPS\Member::loggedIn()->modPermission('mod_see_warn') or ( \IPS\Settings::i()->warn_show_own and \IPS\Member::loggedIn()->member_id == $member->member_id ) ) ) )
{
\IPS\Output::i()->error( 'no_module_permission', '2C135/9', 403, '' );
}
$table = new \IPS\Helpers\Table\Content( 'IPS\core\Warnings\Warning', \IPS\Http\Url::internal( "app=core&module=system&controller=warnings&id={$member->member_id}", 'front', 'warn_list', $member->members_seo_name ), array( array( 'wl_member=?', $member->member_id ) ) );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' ), 'warningRow' );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('members_warnings', FALSE, array( 'sprintf' => array( $member->name ) ) );
\IPS\Output::i()->breadcrumb[] = array( $member->url(), $member->name );
if( !\IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'tables', 'core' )->container( (string) $table );
}
else
{
\IPS\Output::i()->output = (string) $table;
}
}
/**
* View Warning
*
* @return void
*/
protected function view()
{
/* Load the member */
$member = \IPS\Member::load( \IPS\Request::i()->id );
if ( !$member->member_id )
{
\IPS\Output::i()->error( 'node_error', '2C135/4', 403, '' );
}
/* Load it */
try
{
$warning = \IPS\core\Warnings\Warning::loadAndCheckPerms( \IPS\Request::i()->w );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C184/3', 404, '' );
}
/* Show it */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'view_warning_details' );
\IPS\Output::i()->breadcrumb[] = array( $member->url(), $member->name );
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=core&module=system&controller=warnings&id={$member->member_id}", NULL, 'warn_list', $member->members_seo_name ), \IPS\Member::loggedIn()->language()->addToStack('members_warnings', FALSE, array( 'sprintf' => array( $member->name ) ) ) );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'view_warning_details' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('modcp')->warnHovercard( $warning );
}
/**
* Warn
*
* @return void
*/
protected function warn()
{
/* Load the member */
$member = \IPS\Member::load( \IPS\Request::i()->id );
if ( !$member->member_id )
{
\IPS\Output::i()->error( 'node_error', '2C135/2', 403, '' );
}
/* Permission Check */
if ( !\IPS\Member::loggedIn()->canWarn( $member ) )
{
\IPS\Output::i()->error( 'no_module_permission', '2C184/6', 403, '' );
}
/* Build the form */
$form = \IPS\core\Warnings\Warning::create();
$form->class = 'ipsForm_vertical';
$form->attributes = array( 'data-controller' => 'core.front.modcp.warnForm', 'data-member' => $member->member_id );
$form->hiddenValues['ref'] = \IPS\Request::i()->ref;
$form->hiddenValues['member'] = $member->member_id;
/* Display */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_modcp.js', 'core' ) );
$actions = \IPS\Db::i()->select( '*', 'core_members_warn_actions', NULL, 'wa_points ASC' );
if ( count( $actions ) )
{
$min = NULL;
foreach ( $actions as $a )
{
if ( ( $a['wa_points'] - $member->warn_level ) > 1 )
{
$min = $a['wa_points'] - $member->warn_level;
}
break;
}
$form->addSidebar( \IPS\Theme::i()->getTemplate( 'modcp' )->warnActions( $actions, $member, $min ) );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('warn_member', FALSE, array( 'sprintf' => array( $member->name ) ) );
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
}
/**
* Axknowledge Warning
*
* @return void
*/
protected function acknowledge()
{
/* Load the member */
$member = \IPS\Member::load( \IPS\Request::i()->id );
if ( !$member->member_id )
{
\IPS\Output::i()->error( 'node_error', '2C184/4', 403, '' );
}
/* Load it */
try
{
$warning = \IPS\core\Warnings\Warning::loadAndCheckPerms( \IPS\Request::i()->w );
if ( $warning->member !== $member->member_id )
{
throw new \OutOfRangeException;
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C184/5', 404, '' );
}
/* Acknowledge it */
$warning->acknowledged = TRUE;
$warning->save();
$member->members_bitoptions['unacknowledged_warnings'] = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'core_members_warn_logs', array( "wl_member=? AND wl_acknowledged=0", $member->member_id ) )->first();
$member->save();
/* Redirect */
if ( isset( $_SERVER['HTTP_REFERER'] ) )
{
$url = new \IPS\Http\Url( $_SERVER['HTTP_REFERER'] );
if ( $url->isInternal )
{
\IPS\Output::i()->redirect( $url );
return;
}
}
\IPS\Output::i()->redirect( $warning->url() );
}
/**
* Revoke Warning
*
* @return void
*/
protected function delete()
{
$class = static::$contentModel;
try
{
$item = $class::loadAndCheckPerms( \IPS\Request::i()->w );
$member = \IPS\Member::load( $item->member );
if ( $item->canDelete() )
{
if ( isset( \IPS\Request::i()->undo ) )
{
\IPS\Session::i()->csrfCheck();
if ( \IPS\Request::i()->undo )
{
$item->undo();
}
$item->delete();
\IPS\Output::i()->redirect( $member->url(), 'warn_revoked' );
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('modcp')->warningRevoke( $item );
}
}
else
{
\IPS\Output::i()->error( 'generic_error', '2C184/1', 403, '' );
}
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C184/2', 404, '' );
}
}
/**
* Add Warning Form - AJAX response to reason select
*
* @return void
*/
protected function reasonAjax()
{
$remove = array(
'date' => NULL,
'time' => NULL,
'unlimited' => TRUE,
);
if ( \IPS\Request::i()->id == 'other' )
{
\IPS\Output::i()->json( array(
'points' => 0,
'points_override' => TRUE,
'remove' => $remove,
'remove_override' => TRUE,
) );
}
try
{
$reason = \IPS\core\Warnings\Reason::load( \IPS\Request::i()->id );
/* Add in the remove properties */
if ( $reason->remove )
{
$date = \IPS\DateTime::create();
if ( $reason->remove_unit == 'h' )
{
$date->add( new \DateInterval( "PT{$reason->remove}H" ) );
}
else
{
$date->add( new \DateInterval( "P{$reason->remove}D" ) );
}
$remove = array(
'date' => $date->format( 'Y-m-d' ),
'time' => $date->format( 'H:i' ),
'unlimited' => FALSE
);
}
\IPS\Output::i()->json( array(
'points' => $reason->points,
'points_override' => $reason->points_override,
'remove' => $remove,
'remove_override' => $reason->remove_override,
) );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->json( array(
'points' => 0,
'points_override' => FALSE,
'remove' => $remove,
'remove_override' => FALSE,
) );
}
}
/**
* Add Warning Form - AJAX response to points change
*
* @return void
*/
protected function actionAjax()
{
$actions = array(
'mq' => array(
'date' => NULL,
'time' => NULL,
'unlimited' => FALSE,
),
'rpa' => array(
'date' => NULL,
'time' => NULL,
'unlimited' => FALSE,
),
'suspend' => array(
'date' => NULL,
'time' => NULL,
'unlimited' => FALSE,
),
);
$member = \IPS\Member::load( \IPS\Request::i()->member );
try
{
$action = \IPS\Db::i()->select( '*', 'core_members_warn_actions', array( 'wa_points<=?', ( $member->warn_level + \IPS\Request::i()->points ) ), 'wa_points DESC', 1 )->first();
foreach ( array( 'mq', 'rpa', 'suspend' ) as $k )
{
if ( $action[ 'wa_' . $k ] == -1 )
{
$actions[ $k ]['unlimited'] = TRUE;
}
elseif ( $action[ 'wa_' . $k ] )
{
$date = \IPS\DateTime::ts( time() )->add( new \DateInterval( $action[ 'wa_' . $k . '_unit' ] == 'h' ? "PT{$action[ 'wa_' . $k ]}H" : "P{$action[ 'wa_' . $k ]}D" ) );
$actions[ $k ]['date'] = $date->format( 'Y-m-d' );
$actions[ $k ]['time'] = $date->format( 'H:i' );
}
}
}
catch ( \UnderflowException $e ) { }
\IPS\Output::i()->json( array(
'actions' => $actions,
'override' => isset( $action ) ? $action['wa_override'] : \IPS\Member::loggedIn()->modPermission('warning_custom_noaction')
) );
}
}
@@ -0,0 +1,318 @@
<?php
/**
* @brief Sidebar Widgets
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 19 Nov 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\system;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Sidebar Widgets
*/
class _widgets extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
/* Check Permissions */
if ( ! \IPS\Member::loggedIn()->modPermission('can_manage_sidebar') )
{
\IPS\Output::i()->error( 'no_permission_manage_sidebar', '3S172/1', 403, '' );
}
parent::execute();
}
/**
* Build The Block List For Front End
*
* @return void
*/
protected function getBlockList()
{
$availableBlocks = array();
foreach ( \IPS\Db::i()->select( "*", 'core_widgets' ) as $widget )
{
try
{
$appOrPlugin = isset( $widget['plugin'] ) ? \IPS\Plugin::load( $widget['plugin'] ) : \IPS\Application::load( $widget['app'] );
if ( isset( $widget['plugin'] ) )
{
if ( !$appOrPlugin->enabled )
{
continue;
}
}
else
{
if ( !\IPS\Application::appIsEnabled( $appOrPlugin->directory ) or !\IPS\Application::load( $appOrPlugin->directory )->canAccess() )
{
continue;
}
}
$block = \IPS\Widget::load( $appOrPlugin, $widget['key'], uniqid(), array(), $widget['restrict'], null );
$block->allowReuse = (boolean) $widget['allow_reuse'];
$block->menuStyle = $widget['menu_style'];
if ( ! $block->isExecutableByApp( array( \IPS\Request::i()->pageApp, 'sidebar' ) ) )
{
throw new \OutOfRangeException;
}
}
catch( \Exception $e )
{
continue;
}
if( isset( $widget['app'] ) )
{
$availableBlocks['apps'][ $widget['app'] ][] = $block;
}
else
{
$availableBlocks['plugin'][ $widget['plugin'] ][] = $block;
}
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'widgets' )->blockList( $availableBlocks );
}
/**
* Get Output For Adding A New Block
*
* @return void
*/
protected function getBlock()
{
$key = $block = explode( "_", \IPS\Request::i()->blockID );
if ( isset( \IPS\Request::i()->pageApp ) )
{
try
{
foreach ( json_decode( \IPS\Db::i()->select( 'widgets', 'core_widget_areas', array( 'app=? AND module=? AND controller=? AND area=?', \IPS\Request::i()->pageApp, \IPS\Request::i()->pageModule, \IPS\Request::i()->pageController, \IPS\Request::i()->pageArea ) )->first(), TRUE ) as $k => $block )
{
switch( $key[0] )
{
case 'app':
if( ( isset( $block['app'] ) and $block['app'] == $key[1] ) AND $block['key'] == $key[2] AND $block['unique'] == $key[3] )
{
$widget = \IPS\Widget::load( \IPS\Application::load( $block['app'] ), $block['key'], $block['unique'], $block['configuration'], null, \IPS\Request::i()->orientation );
break 2;
}
break;
case 'plugin':
if( ( isset( $block['plugin'] ) and $block['plugin'] == $key[1] ) AND $block['key'] == $key[2] AND $block['unique'] == $key[3] )
{
$widget = \IPS\Widget::load( \IPS\Plugin::load( $block['plugin'] ), $block['key'], $block['unique'], $block['configuration'], null, \IPS\Request::i()->orientation );
break 2;
}
break;
}
}
}
catch ( \UnderflowException $e ) { }
}
if ( !isset( $widget ) )
{
$widget = \IPS\Widget::load( ( $key[0] == 'plugin' ) ? \IPS\Plugin::load( $key[1] ) : \IPS\Application::load( $key[1] ), $key[2], $key[3], array(), null, \IPS\Request::i()->orientation );
}
\IPS\Output::i()->sendOutput( (string) $widget );
}
/**
* Get Configuration
*
* @return void
*/
protected function getConfiguration()
{
$key = explode( "_", \IPS\Request::i()->block );
$blocks = array();
try
{
$blocks = \IPS\Db::i()->select( '*', 'core_widget_areas', array( 'app=? AND module=? AND controller=? AND area=?', \IPS\Request::i()->pageApp, \IPS\Request::i()->pageModule, \IPS\Request::i()->pageController, \IPS\Request::i()->pageArea ) )->first();
$blocks = json_decode( $blocks['widgets'], TRUE );
$where = ( $key[0] ) == 'app' ? '`key`=? AND `app`=?' : '`key`=? AND `plugin`=?';
$widgetMaster = \IPS\Db::i()->select( '*', 'core_widgets', array( $where, $key[2], $key[1] ) )->first();
}
catch ( \UnderflowException $e )
{
switch( $key[0] )
{
case 'app':
$blocks = array( array( 'app' => $key[1], 'key' => $key[2], 'unique' => $key[3], 'configuration' => array() ) );
break;
case 'plugin':
$blocks = array( array( 'plugin' => $key[1], 'key' => $key[2], 'unique' => $key[3], 'configuration' => array() ) );
break;
}
}
$widget = NULL;
if( !empty( $blocks ) )
{
foreach ( $blocks as $k => $block )
{
switch( $key[0] )
{
case 'app':
if( ( isset( $block['app'] ) AND $block['app'] == $key[1] ) AND $block['key'] == $key[2] AND $block['unique'] == $key[3] )
{
$widget = \IPS\Widget::load( \IPS\Application::load( $block['app'] ), $block['key'], $block['unique'], $block['configuration'] );
}
break;
case 'plugin':
if( ( isset( $block['plugin'] ) AND $block['plugin'] == $key[1] ) AND $block['key'] == $key[2] AND $block['unique'] == $key[3] )
{
$widget = \IPS\Widget::load( \IPS\Plugin::load( $block['plugin'] ), $block['key'], $block['unique'], $block['configuration'] );
}
break;
}
if( $widget !== NULL AND method_exists( $widget, 'configuration' ) )
{
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->jsFiles = array();
}
$widget->menuStyle = $widgetMaster['menu_style'];
$form = new \IPS\Helpers\Form( 'form', 'saveSettings' );
if ( $widget->configuration( $form ) !== NULL )
{
if ( $values = $form->values() )
{
if ( method_exists( $widget, 'preConfig' ) )
{
$values = $widget->preConfig( $values );
}
$blocks[ $k ]['configuration'] = $values;
\IPS\Db::i()->insert( 'core_widget_areas', array( 'app' => \IPS\Request::i()->pageApp, 'module' => \IPS\Request::i()->pageModule, 'controller' => \IPS\Request::i()->pageController, 'area' => \IPS\Request::i()->pageArea, 'widgets' => json_encode( $blocks ) ), TRUE );
\IPS\Output::i()->json( 'OK' );
}
\IPS\Output::i()->sendOutput( $widget->configuration()->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'widgets', 'core' ) ), 'formTemplate' ), $widget ) );
}
}
}
}
}
/**
* Reorder Blocks
*
* @return void
*/
protected function saveOrder()
{
if( !in_array( \IPS\Request::i()->area, array( 'sidebar', 'header', 'footer' ) ) )
{
\IPS\Output::i()->error( 'invalid_widget_area', '3S172/2', 403, '' );
}
$newOrder = array();
$seen = array();
try
{
$currentConfig = \IPS\Db::i()->select( '*', 'core_widget_areas', array( 'app=? AND module=? AND controller=? AND area=?', \IPS\Request::i()->pageApp, \IPS\Request::i()->pageModule, \IPS\Request::i()->pageController, \IPS\Request::i()->area ) )->first();
$widgets = json_decode( $currentConfig['widgets'], TRUE );
}
catch ( \UnderflowException $e )
{
$widgets = array();
}
/* Loop over the new order and merge in current blocks so we don't lose config */
if ( isset ( \IPS\Request::i()->order ) )
{
foreach ( \IPS\Request::i()->order as $block )
{
$block = explode( "_", $block );
$added = FALSE;
foreach( $widgets as $widget )
{
if ( $widget['key'] == $block[2] AND $widget['unique'] == $block[3] )
{
$seen[] = $widget['unique'];
$newOrder[] = $widget;
$added = TRUE;
break;
}
}
if( !$added )
{
$newBlock = array();
if ( $block[0] == 'app' )
{
$newBlock['app'] = $block[1];
}
else
{
$newBlock['plugin'] = $block[1];
}
$newBlock['key'] = $block[2];
$newBlock['unique'] = $block[3];
$newBlock['configuration'] = array();
/* Make sure this widget doesn't have configuration in another area */
$newBlock['configuration'] = \IPS\Widget::getConfiguration( $newBlock['unique'] );
$seen[] = $block[3];
$newOrder[] = $newBlock;
}
}
}
/* Anything to update? */
if ( count( $widgets ) > count( $newOrder ) )
{
/* No items left in area, or one has been removed */
foreach( $widgets as $widget )
{
/* If we haven't seen this widget, it's been removed, so add to trash */
if ( ! in_array( $widget['unique'], $seen ) )
{
\IPS\Widget::trash( $widget['unique'], $widget );
}
}
}
/* Expire Caches so up to date information displays */
\IPS\Widget::deleteCaches();
/* Save to database */
\IPS\Db::i()->replace( 'core_widget_areas', array( 'app' => \IPS\Request::i()->pageApp, 'module' => \IPS\Request::i()->pageModule, 'controller' => \IPS\Request::i()->pageController, 'widgets' => json_encode( $newOrder ), 'area' => \IPS\Request::i()->area ) );
}
}