Version 4.1.2

This commit is contained in:
Neo committed 2025-12-19 05:32:19 -08:00
1 parent 3ba79295ee
commit 28bd025b35
1131 files changed
+63658 -20579

No files matched your search

@@ -1,144 +0,0 @@
<?php
/**
* @brief Activity Stream
* @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 2 Sep 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\activity;
/* 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;
}
/**
* Activity Stream
*/
class _activity extends \IPS\Dispatcher\Controller
{
/**
* New Content
*
* @return void
*/
public function manage()
{
/* Flood control */
\IPS\Request::floodCheck();
/* Get the different types */
$types = array();
$hasCallback = array();
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter', TRUE, NULL, NULL, TRUE ) as $router )
{
foreach( $router->classes as $class )
{
if( !is_subclass_of( $class, 'IPS\Content\Searchable' ) )
{
continue;
}
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) ) ] = $class;
if ( isset( $class::$commentClass ) )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$commentClass, 4 ) ) ) ] = $class::$commentClass;
}
if ( isset( $class::$reviewClass ) )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$reviewClass, 4 ) ) ) ] = $class::$reviewClass;
}
if( method_exists( $class, 'customTableHelper' ) )
{
$hasCallback[ mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) ) ] = $router;
if ( isset( $class::$commentClass ) )
{
$hasCallback[ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$commentClass, 4 ) ) ) ] = $router;
}
if ( isset( $class::$reviewClass ) )
{
$hasCallback[ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$reviewClass, 4 ) ) ) ] = $router;
}
}
}
}
/* 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;
}
}
}
$url = \IPS\Http\Url::internal( "app=core&module=activity&controller=activity", 'front', 'activity' );
/* Build Output */
if ( !$currentType )
{
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
$query = \IPS\Content\Search\Query::init()->excludeFirstPostContentItems()->excludeDisabledApps()->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_CREATED )->setPage( $page );
$results = $query->search();
$pagination = trim( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $url, ceil( $results->count( TRUE ) / $query->resultsToGet ), $page, $query->resultsToGet ) );
$output = \IPS\Theme::i()->getTemplate('system')->activityStream( $results, $pagination );
}
else
{
$currentClass = $types[ $currentAppModule ][ $currentType ];
$currentAppArray = explode( '_', $currentAppModule );
$currentApp = $currentAppArray[0];
if( isset( $hasCallback[ $currentType ] ) )
{
$output = $hasCallback[ $currentType ]->customTableHelper( $currentClass, $url->setQueryString( array( 'type' => $currentType ) ) );
}
else
{
$where = array();
if ( isset( $currentClass::$databaseColumnMap['state'] ) )
{
$where[] = array( $currentClass::$databaseColumnMap['state'] . ' != ?', 'link' );
}
$output = new \IPS\Helpers\Table\Content( $currentClass, $url->setQueryString( array( 'type' => $currentType ) ), $where, NULL, NULL, 'read', FALSE );
}
$output->showFilters = FALSE;
}
/* If we've clicked from the tab section */
if ( \IPS\Request::i()->isAjax() && \IPS\Request::i()->change_section )
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'system' )->activitySection( $url, $types, $currentAppModule, $currentType, (string) $output ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
}
else
{
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->get('activity_stream');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->activity( $url, $types, $currentAppModule, $currentType, (string) $output );
}
}
}
Whitespace-only changes.
@@ -56,8 +56,9 @@ class _contact extends \IPS\Dispatcher\Controller
/* Send the message */
$fromName = ( \IPS\Member::loggedIn()->member_id ) ? \IPS\Member::loggedIn()->name : $values['contact_name'];
$mail = \IPS\Email::buildFromTemplate( 'core', 'contact_form', array( \IPS\Member::loggedIn(), $fromName, $values['contact_text'] ) );
$mail->from = ( \IPS\Member::loggedIn()->member_id ) ? \IPS\Member::loggedIn()->email : $values['email_address'];
$mail->fromName = $fromName;
/* Set contact email as Reply-To instead of From, so that it will pass Spam/SPF checks */
$mail->headers['Reply-To'] = '=?UTF-8?B?' . base64_encode( $fromName ) . "?= <" . ( \IPS\Member::loggedIn()->member_id ? \IPS\Member::loggedIn()->email : $values['email_address'] ) . '>';
$mail->send( \IPS\Settings::i()->email_in );
if( \IPS\Request::i()->isAjax() )
@@ -0,0 +1,476 @@
<?php
/**
* @brief streams
* @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 Jul 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\discover;
/* 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;
}
/**
* streams
*/
class _streams extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
/* Initiate the breadcrumb */
\IPS\Output::i()->breadcrumb = array( array( \IPS\Http\Url::internal( "app=core&module=discovery&controller=streams", 'front', 'discover_all' ), \IPS\Member::loggedIn()->language()->addToStack('activity') ) );
/* Necessary CSS/JS */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_streams.js', 'core' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/streams.css' ) );
/* Execute */
return parent::execute();
}
/**
* View Stream
*
* @return void
*/
protected function manage()
{
/* If this request is from an auto-poll, kill it and exit */
if ( !\IPS\Settings::i()->auto_polling_enabled && \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->after ) ){
\IPS\Output::i()->json( array( 'error' => 'auto_polling_disabled' ) );
return;
}
/* Viewing a particular stream? */
if ( isset( \IPS\Request::i()->id ) )
{
/* Get it */
try
{
$stream = \IPS\core\Stream::load( \IPS\Request::i()->id );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C280/1', 404, '' );
}
/* Suitable for guests? */
if ( ! \IPS\Member::loggedIn()->member_id and ! ( ( $stream->ownership == 'all' or $stream->ownership == 'custom' ) and $stream->read == 'all' and $stream->follow == 'all' and $stream->date_type != 'last_visit' ) )
{
\IPS\Output::i()->error( 'stream_no_permission', '2C280/3', 403, '' );
}
$baseUrl = $stream->url();
if ( \IPS\Member::loggedIn()->member_id and isset( \IPS\Request::i()->default ) )
{
if ( \IPS\Request::i()->default )
{
\IPS\Member::loggedIn()->defaultStream = $stream->_id;
}
else
{
\IPS\Member::loggedIn()->defaultStream = NULL;
}
if ( \IPS\Request::i()->isAjax() )
{
$defaultStream = \IPS\core\Stream::defaultStream();
if ( ! $defaultStream )
{
\IPS\Output::i()->json( array( 'title' => NULL ) );
}
else
{
\IPS\Output::i()->json( array(
'url' => $defaultStream->url(),
'title' => $defaultStream->_title,
'id' => $defaultStream->_id
) );
}
}
\IPS\Output::i()->redirect( $stream->url() );
}
if ( isset( \IPS\Request::i()->form ) )
{
if ( \IPS\Request::i()->form == 'show' )
{
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->sendOutput( $this->_buildForm( $stream ), 200, 'text/html' );
}
else
{
\IPS\Output::i()->output = $this->_buildForm( $stream );
}
return;
}
else
{
/* We want to process the form */
$this->_buildForm( $stream );
}
}
/* Set title and breadcrumb */
\IPS\Output::i()->breadcrumb[] = array( $stream->url(), $stream->_title );
\IPS\Output::i()->title = $stream->_title;
}
/* Or just everything? */
else
{
if ( \IPS\Member::loggedIn()->member_id and isset( \IPS\Request::i()->default ) )
{
if ( \IPS\Request::i()->default )
{
\IPS\Member::loggedIn()->defaultStream = 0;
}
else
{
\IPS\Member::loggedIn()->defaultStream = NULL;
}
if ( \IPS\Request::i()->isAjax() )
{
$defaultStream = \IPS\core\Stream::defaultStream();
if ( ! $defaultStream )
{
\IPS\Output::i()->json( array( 'title' => NULL ) );
}
else
{
\IPS\Output::i()->json( array(
'url' => \IPS\Http\Url::internal( "app=core&module=discovery&controller=streams", 'front', 'discover_all' ),
'title' => $defaultStream->_title,
'id' => $defaultStream->_id
) );
}
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=discovery&controller=streams", 'front', 'discover_all' ) );
}
/* Start with a blank stream */
$stream = \IPS\core\Stream::allActivityStream();
$baseUrl = \IPS\Http\Url::internal( "app=core&module=discovery&controller=streams", 'front', 'discover_all' );
/* Set the title to "All Activity" */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('all_activity');
}
/* Changes from Update Only */
foreach ( array( 'include_comments', 'classes', 'containers', 'ownership', 'read', 'follow', 'date_type', 'date_start', 'date_end', 'date_relative_days', 'sort' ) as $k )
{
if ( isset( \IPS\Request::i()->$k ) )
{
$stream->$k = \IPS\Request::i()->$k;
$baseUrl = $baseUrl->setQueryString( $k, \IPS\Request::i()->$k );
}
}
/* RSS validate? */
$member = NULL;
if ( isset( \IPS\Request::i()->rss ) )
{
$member = \IPS\Member::load( \IPS\Request::i()->member );
if ( \IPS\Request::i()->key != md5( ( $member->members_pass_hash ?: $member->email ) . $member->members_pass_salt ) )
{
$member = NULL;
}
}
/* Build the query */
$query = $stream->query( $member );
/* Set page or the before/after date */
$currentPage = 1;
if ( isset( \IPS\Request::i()->page ) )
{
$currentPage = \IPS\Request::i()->page;
$query->setPage( $currentPage );
}
if ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->before ) )
{
if ( $stream->id and !$stream->include_comments )
{
$query->filterByLastUpdatedDate( NULL, \IPS\DateTime::ts( \IPS\Request::i()->before ) );
}
else
{
$query->filterByCreateDate( NULL, \IPS\DateTime::ts( \IPS\Request::i()->before ) );
}
}
if ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->after ) )
{
if ( $stream->id and !$stream->include_comments )
{
$query->filterByLastUpdatedDate( \IPS\DateTime::ts( \IPS\Request::i()->after ) );
}
else
{
$query->filterByCreateDate( \IPS\DateTime::ts( \IPS\Request::i()->after ) );
}
}
/* Get the results */
$results = $query->search( NULL, $stream->tags ? explode( ',', $stream->tags ) : NULL );
/* Load data we need like the authors, etc */
$results->init();
/* Add in extra stuff? */
if ( !isset( \IPS\Request::i()->id ) )
{
/* Is anything turned on? */
$extra = array();
foreach ( array( 'register', 'follow_member', 'follow_content', 'photo', 'like', 'rep_neg' ) as $k )
{
$key = "all_activity_{$k}";
if ( \IPS\Settings::i()->$key )
{
$extra[] = $k;
}
}
if ( !empty( $extra ) )
{
$results = $results->addExtraItems( $extra, NULL, ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->after ) : NULL, ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->before ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->before ) : NULL );
}
}
/* Condensed or expanded? */
$view = 'expanded';
$streamID = ( \IPS\Request::i()->id ) ? \IPS\Request::i()->id : 'all';
if ( ( isset( \IPS\Request::i()->cookie['stream_view_' . $streamID] ) and \IPS\Request::i()->cookie['stream_view_' . $streamID] == 'condensed' ) or ( isset( \IPS\Request::i()->view ) and \IPS\Request::i()->view == 'condensed' ) )
{
$view = 'condensed';
}
/* If this is an AJAX request, just show the results */
if ( \IPS\Request::i()->isAjax() )
{
if( isset( \IPS\Request::i()->_changeView ) )
{
$output = \IPS\Theme::i()->getTemplate('streams')->stream( $stream, $results, !isset( \IPS\Request::i()->id ), true, $baseUrl, ( $stream->id and !$stream->include_comments ) ? 'last_comment' : 'date', $view );
}
else
{
$output = \IPS\Theme::i()->getTemplate('streams')->streamItems( $results, true, ( $stream->id and !$stream->include_comments ) ? 'last_comment' : 'date', $view );
}
$return = array(
'title' => $stream->_title,
'blurb' => $stream->blurb(),
'count' => count( $results ),
'results' => $output,
'id' => ( $stream->id ) ? $stream->id : ''
);
\IPS\Output::i()->json( $return );
return;
}
/* Display - RSS */
if ( isset( \IPS\Request::i()->rss ) )
{
$document = \IPS\Xml\Rss::newDocument( $baseUrl, $stream->_title, sprintf( \IPS\Member::loggedIn()->language()->get( 'stream_rss_title' ), \IPS\Settings::i()->board_name, $stream->_title ) );
foreach ( $results as $result )
{
$result->addToRssFeed( $document );
}
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
return;
}
/* Display - HTML */
else
{
/* What's the RSS Link? */
$rssLink = NULL;
if ( isset( \IPS\Request::i()->id ) )
{
$rssLink = \IPS\Http\Url::internal( "app=core&module=discovery&controller=streams&id={$stream->id}", 'front', 'discover_rss' );
if ( \IPS\Member::loggedIn()->member_id )
{
$rssLink = $rssLink->setQueryString( 'member', \IPS\Member::loggedIn()->member_id );
if ( !\IPS\Member::loggedIn()->members_pass_salt )
{
\IPS\Member::loggedIn()->members_pass_salt = \IPS\Member::loggedIn()->generateSalt();
\IPS\Member::loggedIn()->save();
}
$rssLink = $rssLink->setQueryString( 'key', md5( ( \IPS\Member::loggedIn()->members_pass_hash ?: \IPS\Member::loggedIn()->email ) . \IPS\Member::loggedIn()->members_pass_salt ) );
}
}
/* Display */
$output = \IPS\Theme::i()->getTemplate('streams')->stream( $stream, $results, !isset( \IPS\Request::i()->id ), true, $baseUrl, ( $stream->id and !$stream->include_comments ) ? 'last_comment' : 'date', $view );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('streams')->streamWrapper( $stream, $output, ( isset( \IPS\Request::i()->id ) and ( !$stream->member or $stream->member == \IPS\Member::loggedIn()->member_id ) ) ? TRUE : FALSE, $rssLink, isset( \IPS\Request::i()->id ) and $stream->member and $stream->member != \IPS\Member::loggedIn()->member_id );
}
}
/**
* Create a new stream
*
* @return void
*/
public function create()
{
$stream = new \IPS\core\Stream;
$stream->member = \IPS\Member::loggedIn()->member_id;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'create_new_stream' );
\IPS\Output::i()->output = $this->_buildForm( $stream );
}
/**
* Copy a stream
*
* @return void
*/
public function copy()
{
try
{
$stream = clone \IPS\core\Stream::load( \IPS\Request::i()->id );
$stream->member = \IPS\Member::loggedIn()->member_id;
$stream->save();
$this->_rebuildStreams();
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C280/3', 404, '' );
}
\IPS\Output::i()->redirect( $stream->url() );
}
/**
* Deletes a new stream
*
* @return void
*/
public function delete()
{
try
{
$stream = \IPS\core\Stream::load( \IPS\Request::i()->id );
if ( !$stream->member or $stream->member != \IPS\Member::loggedIn()->member_id )
{
throw new \OutOfRangeException;
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2C280/2', 404, '' );
}
$stream->delete();
$this->_rebuildStreams();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=discover&controller=streams", 'front', 'discover_all' ) );
}
/**
* Build form
*
* @param \IPS\core\Stream $stream The stream
* @return string
*/
protected function _buildForm( \IPS\core\Stream $stream )
{
/* Build form */
$form = new \IPS\Helpers\Form( 'select_blog', 'continue', ( $stream->id ? $stream->url() : NULL ) );
$form->class = 'ipsForm_vertical ipsForm_noLabels';
$stream->form( $form, 'Text', !$stream->id );
$redirectAfterSave = FALSE;
/* Note if it's custom */
if ( $stream->member && \IPS\Member::loggedIn()->member_id )
{
$form->hiddenValues['__custom_stream'] = TRUE;
}
/* Handle submissions */
if ( $values = $form->values() )
{
/* Update only */
if ( !$stream->member or isset( \IPS\Request::i()->updateOnly ) )
{
$url = $stream->url();
$formattedValues = $stream->formatFormValues( $values );
foreach ( array( 'include_comments', 'classes', 'containers', 'ownership', 'read', 'follow', 'date_type', 'date_start', 'date_end', 'date_relative_days' ) as $k )
{
if ( $stream->$k != $formattedValues[ $k ] )
{
$url = $url->setQueryString( $k, $formattedValues[ $k ] );
}
}
\IPS\Output::i()->redirect( $url );
}
/* Update & Save */
else
{
if ( !$stream->id )
{
$stream->position = \IPS\Db::i()->select( 'MAX(position)', 'core_streams', array( 'member=?', \IPS\Member::loggedIn()->member_id ) )->first() + 1;
$redirectAfterSave = TRUE;
}
if ( count( $values['stream_classes'] ) )
{
$values['stream_classes_type'] = 1;
}
$stream->saveForm( $stream->formatFormValues( $values ) );
$this->_rebuildStreams();
if( $redirectAfterSave )
{
\IPS\Output::i()->redirect( $stream->url() );
}
}
}
/* Display */
return $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'streams', 'core' ) ), $stream->id ? ( $stream->member ? 'filterUpdateForm' : 'filterDuplicateForm' ) : 'filterCreateForm' ) );
}
/**
* Rebuild logged in member's streams
*
* @return void
*/
protected function _rebuildStreams()
{
$default = \IPS\Member::loggedIn()->defaultStream;
\IPS\Member::loggedIn()->member_streams = json_encode( array( 'default' => $default, 'streams' => iterator_to_array( \IPS\Db::i()->select( 'id, title', 'core_streams', array( 'member=?', \IPS\Member::loggedIn()->member_id ) )->setKeyField('id')->setValueField('title') ) ) );
\IPS\Member::loggedIn()->save();
}
}
@@ -51,12 +51,12 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
if( !\IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_profile.js', 'core' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_statuses.js', 'core' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/profiles.css' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/statuses.css' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/streams.css' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/statuses_responsive.css' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/profiles_responsive.css' ) );
}
}
@@ -100,23 +100,14 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
protected function manage()
{
/* Can we access this member's statuses */
$canAccessStatuses = ( \IPS\Settings::i()->profile_comments
and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'status' ) )
and ( $this->member->pp_setting_count_comments or \IPS\Member::loggedIn()->member_id == $this->member->member_id ) );
$canAccessSingleStatuses = ( \IPS\Settings::i()->profile_comments and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'status' ) ) );
$canAccessStatuses = $canAccessSingleStatuses and ( $this->member->pp_setting_count_comments or \IPS\Member::loggedIn()->member_id == $this->member->member_id );
/* Are we loading a different page of comments? */
if ( \IPS\Request::i()->status && \IPS\Request::i()->isAjax() && !\IPS\Request::i()->submitting && !\IPS\Request::i()->getUploader && $canAccessStatuses )
{
try
{
$status = \IPS\core\Statuses\Status::loadAndCheckPerms( \IPS\Request::i()->status );
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->output = \IPS\Output::i()->error( 'node_error', '2C138/D', 404, '' );
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile' )->statusReplies( $status );
$status = \IPS\core\Statuses\Status::loadAndCheckPerms( \IPS\Request::i()->status );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'statuses' )->statusReplies( $status );
return;
}
@@ -157,24 +148,21 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
}
}
/* Work out the main content to display */
if ( $canAccessStatuses and \IPS\Request::i()->status and \IPS\Request::i()->type == 'status' )
if ( $canAccessSingleStatuses and \IPS\Request::i()->status and \IPS\Request::i()->type == 'status' )
{
$statuses = $this->_getStatuses();
$mainContent = \IPS\Theme::i()->getTemplate( 'profile' )->statusFeed( $this->member, $statuses['statuses'], $statuses['count'], $statuses['form'], TRUE );
$status = \IPS\core\Statuses\Status::loadAndCheckPerms( \IPS\Request::i()->status );
$mainContent = \IPS\Theme::i()->getTemplate( 'profile' )->singleStatus( $this->member, $status );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->get( 'viewing_single_status' );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->get( 'viewing_single_status' ) );
}
else
{
/* What tabs are available? */
$tabs = array( 'activity' => 'users_activity_feed' );
if ( $canAccessStatuses )
{
$tabs['statuses'] = 'status_feed';
}
foreach( $mainFields as $group => $fields )
{
foreach( $fields as $field => $value )
@@ -196,7 +184,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$tabs[ "node_{$matches[1]}_{$matches[2]}" ] = "profile_{$matches[1]}_{$matches[2]}";
}
}
/* What tab are we on? */
if ( !isset( \IPS\Request::i()->tab ) or !array_key_exists( \IPS\Request::i()->tab, $tabs ) )
{
@@ -206,19 +194,65 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
{
$tab = \IPS\Request::i()->tab;
}
/* Work out the content */
$tabContents = '';
if ( $tab == 'activity' )
{
$latestActivity = \IPS\Content\Search\Query::init()->filterByAuthor( $this->member )->excludeFirstPostContentItems()->excludeDisabledApps()->setLimit( 15 )->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_CREATED )->search();
$latestActivity = \IPS\Content\Search\Query::init()->filterForProfile( $this->member )->setLimit( 15 )->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_CREATED )->search();
$latestActivity->init( TRUE );
$tabContents = \IPS\Theme::i()->getTemplate( 'profile' )->profileActivity( $this->member, $latestActivity );
}
elseif ( $tab == 'statuses' )
{
$statuses = $this->_getStatuses();
$tabContents = \IPS\Theme::i()->getTemplate( 'profile' )->statusFeed( $this->member, $statuses['statuses'], $statuses['count'], $statuses['form'] );
$extra = array();
foreach ( array( 'register', 'follow_member', 'follow_content', 'photo', 'like', 'rep_neg' ) as $k )
{
$key = "all_activity_{$k}";
if ( \IPS\Settings::i()->$key )
{
$extra[] = $k;
}
}
if ( !empty( $extra ) )
{
$latestActivity = $latestActivity->addExtraItems( $extra, $this->member );
}
$statusForm = NULL;
if ( \IPS\core\Statuses\Status::canCreate( \IPS\Member::loggedIn() ) )
{
if ( isset( \IPS\Request::i()->status_content_ajax ) )
{
\IPS\Request::i()->status_content = \IPS\Request::i()->status_content_ajax;
}
$form = new \IPS\Helpers\Form( 'new_status', 'status_new' );
foreach( \IPS\core\Statuses\Status::formElements() AS $k => $element )
{
$form->add( $element );
}
if ( $values = $form->values() )
{
$status = \IPS\core\Statuses\Status::createFromForm( $values );
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'statuses', 'core', 'front' )->statusContainer( $status ) );
}
else
{
\IPS\Output::i()->redirect( $status->url() );
}
}
$statusForm = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'statusTemplate' ) );
if ( \IPS\core\Statuses\Status::moderateNewItems( \IPS\Member::loggedIn() ) )
{
$statusForm = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $statusForm;
}
}
$tabContents = \IPS\Theme::i()->getTemplate( 'profile' )->profileActivity( $this->member, $latestActivity, $statusForm );
}
elseif ( mb_substr( $tab, 0, 6 ) == 'field_' )
{
@@ -230,16 +264,16 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$type = mb_substr( $tab, 5 );
$tabContents = (string) $nodes[ $type ]->render();
}
/* If this is AJAX request to change the tab, just display that */
if ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->tab ) )
{
\IPS\Output::i()->sendOutput( $tabContents );
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $tabContents ) );
}
/* Otherwise wrap it in the tabs */
$mainContent = \IPS\Theme::i()->getTemplate( 'profile' )->profileTabs( $this->member, $tabs, $tab, $tabContents );
\IPS\Output::i()->title = $this->member->name;
}
@@ -329,22 +363,19 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
continue;
}
if ( $class == 'IPS\core\Statuses\Status' AND ( !\IPS\Settings::i()->profile_comments OR !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'status' ) ) ) )
{
continue;
}
/* Add CSS for this app */
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'profile.css', $class::$application ) );
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) ) ] = $class;
if ( isset( $class::$commentClass ) )
$supportsComments = ( in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::supportsComments( \IPS\Member::loggedIn() ) );
if ( $supportsComments )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$commentClass, 4 ) ) ) ] = $class::$commentClass;
}
if ( isset( $class::$reviewClass ) )
$supportsReviews = ( in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::supportsReviews( \IPS\Member::loggedIn() ) );
if ( $supportsReviews )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$reviewClass, 4 ) ) ) ] = $class::$reviewClass;
}
@@ -353,12 +384,12 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
{
$hasCallback[ mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) ) ] = $router;
if ( isset( $class::$commentClass ) )
if ( $supportsComments )
{
$hasCallback[ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$commentClass, 4 ) ) ) ] = $router;
}
if ( isset( $class::$reviewClass ) )
if ( $supportsReviews )
{
$hasCallback[ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$reviewClass, 4 ) ) ) ] = $router;
}
@@ -392,7 +423,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
/* Build Output */
if ( !$currentType )
{
$query = \IPS\Content\Search\Query::init()->filterByAuthor( $this->member )->excludeFirstPostContentItems()->excludeDisabledApps()->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_UPDATED )->setPage( $page );
$query = \IPS\Content\Search\Query::init()->filterByAuthor( $this->member )->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_UPDATED )->setPage( $page );
$results = $query->search();
$pagination = trim( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $this->member->url()->setQueryString( array( 'do' => 'content' ) ), ceil( $results->count( TRUE ) / $query->resultsToGet ), $page, $query->resultsToGet ) );
$output = \IPS\Theme::i()->getTemplate('profile')->userContentStream( $this->member, $results, $pagination );
@@ -423,8 +454,13 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$output = new \IPS\Helpers\Table\Content( $currentClass, $this->member->url()->setQueryString( array( 'do' => 'content', 'type' => $currentType ) ), $where, NULL, NULL, 'read', FALSE );
}
$output->showFilters = FALSE;
$output->classes[] = 'cProfileContent';
if ( $currentType == 'core_statuses_status' )
{
$output->noModerate = TRUE;
}
$output->showFilters = FALSE;
$output->classes[] = 'cProfileContent';
}
/* If we've clicked from the tab section */
@@ -673,44 +709,6 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
}
/**
* Toggle Statuses
*
* @return void
*/
protected function statuses()
{
if ( !\IPS\Member::loggedIn()->modPermission('can_modify_profiles') AND ( \IPS\Member::loggedIn()->member_id !== $this->member->member_id OR !$this->member->group['g_edit_profile'] ) )
{
\IPS\Output::i()->error( 'no_permission_edit_profile', '2C138/4', 403, '' );
}
\IPS\Session::i()->csrfCheck();
$statuses = array( 'statuses' => array(), 'form' => NULL );
if ( \IPS\Request::i()->state == 0 )
{
$this->member->pp_setting_count_comments = FALSE;
}
else
{
$this->member->pp_setting_count_comments = TRUE;
}
$this->member->save();
if ( \IPS\Request::i()->isAjax() )
{
$statuses = $this->_getStatuses();
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile', 'core' )->statuses( $statuses['statuses'], $statuses['count'], $statuses['form'], $this->member );
}
else
{
\IPS\Output::i()->redirect( $this->member->url(), 'saved' );
}
}
/**
* Edit Status
*
@@ -766,7 +764,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$form = new \IPS\Helpers\Form;
/* The basics */
$form->addtab( 'profile_edit_basic_tab', 'user');
$form->addTab( 'profile_edit_basic_tab', 'user');
$form->addHeader( 'profile_edit_basic_header' );
if( \IPS\Settings::i()->post_titlechange != -1 and ( isset( \IPS\Settings::i()->post_titlechange ) and $this->member->member_posts >= \IPS\Settings::i()->post_titlechange ) )
{
@@ -782,6 +780,10 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
'yyyy' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_year( $element->name, $element->value, $element->error ),
) );
} ) ) );
if ( \IPS\Settings::i()->profile_comments and $this->member->canAccessModule( \IPS\Application\Module::get( 'core', 'status' ) ) )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'enable_status_updates', $this->member->pp_setting_count_comments ) );
}
/* Profile fields */
try
@@ -833,6 +835,13 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$this->member->member_title = $values['member_title'];
}
if( $values['bday'] and ( ( $values['bday']['day'] and !$values['bday']['month'] ) or ( $values['bday']['month'] and !$values['bday']['day'] ) ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'bday_month_and_day_required' );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->editContentForm( \IPS\Member::loggedIn()->language()->addToStack( 'profile_edit' ), $form );
return;
}
if ( $values['bday'] and $values['bday']['day'] and $values['bday']['month'] )
{
$this->member->bday_day = $values['bday']['day'];
@@ -846,6 +855,20 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$this->member->bday_year = NULL;
}
if ( isset( $values['enable_status_updates'] ) )
{
$this->member->pp_setting_count_comments = $values['enable_status_updates'];
if ( $values['enable_status_updates'] )
{
\IPS\Content\Search\Index::i()->massUpdate( 'IPS\core\Statuses\Status', NULL, NULL, '*', NULL, NULL, $this->member->member_id );
}
else
{
\IPS\Content\Search\Index::i()->massUpdate( 'IPS\core\Statuses\Status', NULL, NULL, '', NULL, NULL, $this->member->member_id );
}
}
/* Profile Fields */
try
{
@@ -870,11 +893,13 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
{
$profileFields[ "field_{$id}" ] = $field::stringValue( $values[ $field->name ] );
if ( $fields instanceof \IPS\Helpers\Form\Editor )
if ( $field instanceof \IPS\Helpers\Form\Editor )
{
$field->claimAttachments( $this->id );
\IPS\core\ProfileFields\Field::load( $id )->claimAttachments( $this->member->member_id );
}
}
$this->member->changedCustomFields = $profileFields;
}
/* Moderator stuff */
@@ -902,8 +927,8 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
/* Save */
$this->member->save();
\IPS\Db::i()->replace( 'core_pfields_content', $profileFields );
$this->member->save();
\IPS\Output::i()->redirect( $this->member->url() );
}
@@ -911,7 +936,14 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
/* Set Session Location */
\IPS\Session::i()->setLocation( $this->member->url(), array(), 'loc_editing_profile', array( $this->member->name => FALSE ) );
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->editContentForm( \IPS\Member::loggedIn()->language()->addToStack( 'profile_edit' ), $form );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'editing_profile', FALSE, array( 'sprintf' => array( $this->member->name ) ) );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'editing_profile', FALSE, array( 'sprintf' => array( $this->member->name ) ) ) );
}
@@ -1011,6 +1043,8 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$thumbnail = $values['member_photo_upload']->thumbnail( 'core_Profile', \IPS\PHOTO_THUMBNAIL_SIZE, \IPS\PHOTO_THUMBNAIL_SIZE, TRUE );
$this->member->pp_thumb_photo = (string) $thumbnail;
$this->member->photo_last_update = time();
}
}
break;
@@ -1024,12 +1058,15 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$thumbnail = $values['member_photo_url']->thumbnail( 'core_Profile', \IPS\PHOTO_THUMBNAIL_SIZE, \IPS\PHOTO_THUMBNAIL_SIZE, TRUE );
$this->member->pp_thumb_photo = (string) $thumbnail;
$this->member->photo_last_update = time();
}
break;
case 'none':
$this->member->pp_main_photo = NULL;
$this->member->members_bitoptions['bw_disable_gravatar'] = 1;
$this->member->photo_last_update = NULL;
break;
case 'gravatar':
@@ -1174,7 +1211,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
try
{
$item = ( \IPS\Request::i()->type == 'status' ) ? \IPS\core\Statuses\Status::load( \IPS\Request::i()->status ) : \IPS\core\Statuses\Reply::load( \IPS\Request::i()->status );
$item = ( \IPS\Request::i()->type == 'status' ) ? \IPS\core\Statuses\Status::load( \IPS\Request::i()->status ) : \IPS\core\Statuses\Reply::load( \IPS\Request::i()->reply );
$item->modAction( \IPS\Request::i()->action, \IPS\Member::loggedIn() );
@@ -1186,7 +1223,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
{
if( \IPS\Request::i()->action == 'delete' )
{
\IPS\Output::i()->redirect( ( $item instanceof \IPS\core\Statuses\Status ) ? \IPS\Member::load( $item->member_id )->url() : \IPS\core\Statuses\Status::load( $item->status_id )->url());
\IPS\Output::i()->redirect( ( $item instanceof \IPS\core\Statuses\Status ) ? \IPS\Member::load( $item->member_id )->url()->setQueryString( array( 'do' => 'content', 'type' => 'core_statuses_status' ) ) : \IPS\core\Statuses\Status::load( $item->status_id )->url());
}
else
{
@@ -1218,14 +1255,14 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
try
{
$item = ( \IPS\Request::i()->type == 'status' ) ? \IPS\core\Statuses\Status::load( \IPS\Request::i()->status ) : \IPS\core\Statuses\Reply::load( \IPS\Request::i()->status );
$item = ( \IPS\Request::i()->type == 'status' ) ? \IPS\core\Statuses\Status::load( \IPS\Request::i()->status ) : \IPS\core\Statuses\Reply::load( \IPS\Request::i()->reply );
$type = intval( \IPS\Request::i()->rep ) === 1 ? 1 : -1;
$item->giveReputation( $type );
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->reputationMini( $item ) );
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->reputationMini( $item->reputation(), $item->canGiveReputation( 1 ), $item->canGiveReputation( -1 ), $item->url('showRep'), $item->url('rep') ) );
}
else
{
@@ -1275,7 +1312,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
{
$itemClass = '\IPS\core\Statuses\Status';
$commentClass = '\IPS\core\Statuses\Reply';
$item = ( \IPS\Request::i()->type == 'status' ) ? $itemClass::load( \IPS\Request::i()->status ) : $commentClass::load( \IPS\Request::i()->status );
$item = ( \IPS\Request::i()->type == 'status' ) ? $itemClass::load( \IPS\Request::i()->status ) : $commentClass::load( \IPS\Request::i()->reply );
$canReport = $item->canReport();
if ( $canReport !== TRUE )
@@ -1288,6 +1325,10 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$idColumn = ( \IPS\Request::i()->type == 'status' ) ? $itemClass::$databaseColumnId : $commentClass::$databaseColumnId;
$autoSaveKey = ( \IPS\Request::i()->type == 'status' ) ? "report-{$itemClass::$application}-{$itemClass::$module}-{$item->$idColumn}" : "report-{$itemClass::$application}-{$itemClass::$module}-{$item->status_id}-{$item->$idColumn}";
$form->add( new \IPS\Helpers\Form\Editor( 'report_message', NULL, FALSE, array( 'app' => 'core', 'key' => 'Reports', 'autoSaveKey' => $autoSaveKey, 'minimize' => 'report_message_placeholder' ) ) );
if( !\IPS\Member::loggedIn()->member_id )
{
$form->add( new \IPS\Helpers\Form\Captcha );
}
if ( $values = $form->values() )
{
$report = $item->report( $values['report_message'] );
@@ -1332,98 +1373,6 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('members_followers', FALSE, array( 'sprintf' => array( $this->member->name ) ) ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile' )->allFollowers( $this->member, $followers );
}
/**
* Returns status list and form
*
* @return array
*/
protected function _getStatuses()
{
$statuses = array();
$count = 0;
if ( !\IPS\Settings::i()->profile_comments OR !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'status' ) ) )
{
return array( 'statuses' => $statuses, 'form' => '', 'count' => $count );
}
if ( \IPS\Request::i()->status )
{
try
{
$statuses = array( \IPS\core\Statuses\Status::loadAndCheckPerms( \IPS\Request::i()->status ) );
$count = 1;
}
catch ( \OutOfRangeException $e ) { }
}
if ( !count( $statuses ) )
{
$_where = !\IPS\core\Statuses\Status::modPermission( 'unhide' ) ? "status_approved=1 AND " : '';
$count = \IPS\Db::i()->select( 'count(*)', 'core_member_status_updates', array( "{$_where} (status_member_id=? or status_author_id=?)", $this->member->member_id, $this->member->member_id ) )->first();
$start = ( intval( \IPS\Request::i()->statusPage ?: 1 ) - 1 ) * 25;
if( $start > $count )
{
$start = 0;
\IPS\Request::i()->statusPage = 1;
}
$statuses = new \IPS\Patterns\ActiveRecordIterator(
\IPS\Db::i()->select(
'*',
'core_member_status_updates',
array( "{$_where} (status_member_id=? or status_author_id=?)", $this->member->member_id, $this->member->member_id ),
'status_date DESC',
array( $start, 25 )
),
'\IPS\core\Statuses\Status'
);
}
if ( \IPS\core\Statuses\Status::canCreate( \IPS\Member::loggedIn() ) AND !isset( \IPS\Request::i()->status ) )
{
if ( isset( \IPS\Request::i()->status_content_ajax ) )
{
\IPS\Request::i()->status_content = \IPS\Request::i()->status_content_ajax;
}
$form = new \IPS\Helpers\Form( 'new_status', 'status_new' );
foreach( \IPS\core\Statuses\Status::formElements() AS $k => $element )
{
$form->add( $element );
}
if ( $values = $form->values() )
{
$status = \IPS\core\Statuses\Status::createFromForm( $values );
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'profile', 'core', 'front' )->statusContainer( $status ) );
}
else
{
\IPS\Output::i()->redirect( $status->url() );
}
}
$formTpl = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'statusTemplate' ) );
if ( \IPS\core\Statuses\Status::moderateNewItems( \IPS\Member::loggedIn() ) )
{
$formTpl = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $formTpl;
}
}
else
{
$formTpl = NULL;
}
return array( 'statuses' => $statuses, 'form' => $formTpl, 'count' => $count );
}
/**
* Get Cover Photo Storage Extension
@@ -218,6 +218,7 @@ class _messenger extends \IPS\Content\Controller
}
/* If we're searching, get the results */
$perPage = 25;
if ( \IPS\Request::i()->q )
{
$where[] = array( "( MATCH(core_message_topics.mt_title) AGAINST ('" . \IPS\Db::i()->escape_string( \IPS\Request::i()->q ) . "' IN BOOLEAN MODE) OR
@@ -248,7 +249,7 @@ class _messenger extends \IPS\Content\Controller
'core_message_posts',
$where,
( in_array( \IPS\Request::i()->sortBy, array( 'mt_last_post_time', 'mt_start_time', 'mt_replies' ) ) ? \IPS\Request::i()->sortBy : 'mt_last_post_time' ) . ' DESC',
array( ( intval( \IPS\Request::i()->listPage ?: 1 ) - 1 ) * 25, 25 ),
array( ( intval( \IPS\Request::i()->listPage ?: 1 ) - 1 ) * $perPage, $perPage ),
'msg_topic_id'
)->join(
'core_message_topics',
@@ -269,7 +270,7 @@ class _messenger extends \IPS\Content\Controller
'core_message_topic_user_map',
$where,
( in_array( \IPS\Request::i()->sortBy, array( 'mt_last_post_time', 'mt_start_time', 'mt_replies' ) ) ? \IPS\Request::i()->sortBy : 'mt_last_post_time' ) . ' DESC',
array( ( intval( \IPS\Request::i()->listPage ?: 1 ) - 1 ) * 25, 25 )
array( ( intval( \IPS\Request::i()->listPage ?: 1 ) - 1 ) * $perPage, $perPage )
)->join(
'core_message_topics',
'core_message_topic_user_map.map_topic_id=core_message_topics.mt_id'
@@ -278,18 +279,20 @@ class _messenger extends \IPS\Content\Controller
/* Build the message list */
$conversations = array();
foreach ( $iterator as $row )
{
$row['last_message'] = \IPS\core\Messenger\Conversation::load( $row['mt_id'] )->comments( 1, 0, 'date', 'desc' );
$row['participants'] = \IPS\core\Messenger\Conversation::load( $row['mt_id'] )->participantBlurb();
$conversations[ $row['mt_id'] ] = $row;
}
/* Note the last time we looked at the message list */
\IPS\Member::loggedIn()->msg_count_reset = time();
\IPS\core\Messenger\Conversation::rebuildMessageCounts( \IPS\Member::loggedIn() );
/* Display */
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $baseUrl->setQueryString('_list', 1), ceil( $count / 25 ), ( \IPS\Request::i()->listPage ?: 1 ), 25, TRUE, 'listPage' );
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $baseUrl->setQueryString('_list', 1), ceil( $count / $perPage ), ( \IPS\Request::i()->listPage ?: 1 ), $perPage, TRUE, 'listPage' );
if ( \IPS\Request::i()->isAjax() )
{
if( \IPS\Request::i()->id )
@@ -302,7 +305,7 @@ class _messenger extends \IPS\Content\Controller
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('messaging')->messageListRows( $conversations, $pagination );
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate('messaging')->messageListRows( $conversations, $pagination, TRUE ), 200, 'text/html' );
}
}
else
@@ -664,10 +667,23 @@ class _messenger extends \IPS\Content\Controller
{
try
{
$conversation = \IPS\core\Messenger\Conversation::loadAndCheckPerms( \IPS\Request::i()->id );
$conversation->deauthorize( \IPS\Member::loggedIn() );
\IPS\core\Messenger\Conversation::rebuildMessageCounts( \IPS\Member::loggedIn() );
$ids = \IPS\Request::i()->id;
if ( !is_array( \IPS\Request::i()->id ) )
{
$ids = array( $ids );
}
foreach ( $ids as $id )
{
try
{
$conversation = \IPS\core\Messenger\Conversation::loadAndCheckPerms( $id );
$conversation->deauthorize( \IPS\Member::loggedIn() );
}
catch ( \Exception $e ) {}
}
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array_merge( array( 'result' => 'success' ), $this->_getNewTotals() ) );
@@ -95,7 +95,7 @@ class _modcp extends \IPS\Dispatcher\Controller
}
}
if ( isset( $class::$commentClass ) and in_array( 'IPS\Content\Hideable', class_implements( $class::$commentClass ) ) )
if ( in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::supportsComments( \IPS\Member::loggedIn() ) and in_array( 'IPS\Content\Hideable', class_implements( $class::$commentClass ) ) )
{
$commentClass = $class::$commentClass;
if ( \IPS\Member::loggedIn()->modPermission( 'can_view_hidden_content' ) or \IPS\Member::loggedIn()->modPermission( 'can_view_hidden_' . $commentClass::$title ) )
@@ -104,7 +104,7 @@ class _modcp extends \IPS\Dispatcher\Controller
}
}
if ( isset( $class::$reviewClass ) and in_array( 'IPS\Content\Hideable', class_implements( $class::$reviewClass ) ) )
if ( in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::supportsReviews( \IPS\Member::loggedIn() ) and in_array( 'IPS\Content\Hideable', class_implements( $class::$reviewClass ) ) )
{
$reviewClass = $class::$reviewClass;
if ( \IPS\Member::loggedIn()->modPermission( 'can_view_hidden_content' ) or \IPS\Member::loggedIn()->modPermission( 'can_view_hidden_' . $reviewClass::$title ) )
+211 -150
View File
@@ -32,29 +32,28 @@ class _search extends \IPS\Dispatcher\Controller
{
/* Init stuff for the output */
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/streams.css' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/search.css' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/search_responsive.css' ) );
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_search.js', 'core' ) );
\IPS\Output::i()->metaTags['robots'] = 'noindex'; // Tell search engines not to index search pages
/* Get the form */
$baseUrl = \IPS\Http\Url::internal( 'app=core&module=search&controller=search', 'front', 'search' );
$form = $this->_form();
/* If we have the term, show the results */
if ( \IPS\Request::i()->isAjax() or isset( \IPS\Request::i()->q ) or isset( \IPS\Request::i()->tags ) or ( \IPS\Request::i()->type == 'core_members' ) )
if ( \IPS\Request::i()->isAjax() or isset( \IPS\Request::i()->q ) or isset( \IPS\Request::i()->tags ) or ( \IPS\Request::i()->type == 'core_members' and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members', 'front' ) ) ) )
{
if ( !\IPS\Request::i()->isAjax() and !\IPS\Request::i()->q and !\IPS\Request::i()->tags and \IPS\Request::i()->type !== 'core_members' )
if ( !\IPS\Request::i()->isAjax() and !\IPS\Request::i()->q and !\IPS\Request::i()->tags and \IPS\Request::i()->type !== 'core_members' and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members', 'front' ) ) )
{
if ( isset( \IPS\Request::i()->csrfKey ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('no_search_term');
$form->hiddenValues['__advanced'] = true;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'advanced_search' );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'advancedSearchForm' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'search' )->search( $this->_splitTermsForDisplay(), FALSE, FALSE, FALSE, $baseUrl, FALSE, $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ), $baseUrl, NULL ), 0, TRUE );
}
else
{
@@ -68,8 +67,10 @@ class _search extends \IPS\Dispatcher\Controller
/* Otherwise, show the advanced search form */
else
{
$form->hiddenValues['__advanced'] = true;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'advanced_search' );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'advancedSearchForm' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'search' )->search( $this->_splitTermsForDisplay(), FALSE, FALSE, FALSE, $baseUrl, FALSE, $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ), $baseUrl, NULL ), 0, TRUE );
}
}
@@ -86,6 +87,10 @@ class _search extends \IPS\Dispatcher\Controller
{
$baseUrl = $baseUrl->setQueryString( 'q', \IPS\Request::i()->q );
}
elseif ( \IPS\Request::i()->tags )
{
$baseUrl = $baseUrl->setQueryString( 'tags', \IPS\Request::i()->tags );
}
$types = $this->_contentTypes();
@@ -93,7 +98,7 @@ class _search extends \IPS\Dispatcher\Controller
\IPS\Request::floodCheck();
/* Are we searching members? */
if ( isset( \IPS\Request::i()->type ) and \IPS\Request::i()->type === 'core_members' )
if ( isset( \IPS\Request::i()->type ) and \IPS\Request::i()->type === 'core_members' and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members', 'front' ) ) )
{
$baseUrl = $baseUrl->setQueryString( 'type', \IPS\Request::i()->type );
if ( \IPS\Request::i()->q )
@@ -111,7 +116,7 @@ class _search extends \IPS\Dispatcher\Controller
{
$$l = NULL;
$key = "start_{$l}";
if ( isset( \IPS\Request::i()->$key ) )
if ( isset( \IPS\Request::i()->$key ) AND \IPS\Request::i()->$key != 'any' )
{
switch ( \IPS\Request::i()->$key )
{
@@ -252,8 +257,8 @@ class _search extends \IPS\Dispatcher\Controller
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array(
'filters' => $this->_form()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ) ),
'content' => \IPS\Theme::i()->getTemplate( 'search' )->results( \IPS\Request::i()->q, $title, $results, $pagination, $baseUrl, $count ),
'filters' => $this->_form()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ), $baseUrl, $count ),
'content' => \IPS\Theme::i()->getTemplate( 'search' )->results( $this->_splitTermsForDisplay(), $title, $results, $pagination, $baseUrl, $count ),
'title' => $title,
'css' => array()
) );
@@ -261,63 +266,16 @@ class _search extends \IPS\Dispatcher\Controller
else
{
\IPS\Output::i()->title = $title;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'search' )->search( \IPS\Request::i()->q, $title, $results, $pagination, $baseUrl, $types, $this->_form()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ) ), $count );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'search' )->search( $this->_splitTermsForDisplay(), $title, $results, $pagination, $baseUrl, $types, $this->_form()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ), $baseUrl, $count ), $count );
}
return;
}
/* Init */
$query = \IPS\Content\Search\Query::init();
/* Work out the title */
if ( \IPS\Request::i()->tags and !\IPS\Request::i()->q )
{
$baseUrl = $baseUrl->setQueryString( 'tags', \IPS\Request::i()->tags );
$tagList = array_map( function( $val )
{
return '\'' . htmlentities( $val, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . '\'';
}, explode( ',', \IPS\Request::i()->tags ) );
$term = \IPS\Member::loggedIn()->language()->formatList( $tagList, \IPS\Member::loggedIn()->language()->get('or_list_format') );
$titleKey = 'search_results_title_tag';
}
else
{
$term = urldecode( \IPS\Request::i()->q );
$titleKey = 'search_results_title_term';
}
if ( isset( \IPS\Request::i()->type ) and array_key_exists( \IPS\Request::i()->type, $types ) )
{
$title = \IPS\Member::loggedIn()->language()->addToStack( $titleKey . '_area', FALSE, array( 'sprintf' => array( $term, \IPS\Member::loggedIn()->language()->addToStack( \IPS\Request::i()->type . '_pl' ) ) ) );
if ( isset( \IPS\Request::i()->item ) )
{
$class = $types[ \IPS\Request::i()->type ];
try
{
$item = $class::loadAndCheckPerms( \IPS\Request::i()->item );
$title = \IPS\Member::loggedIn()->language()->addToStack( $titleKey . '_area', FALSE, array( 'sprintf' => array( $term, $item->mapped('title') ) ) );
}
catch ( \OutOfRangeException $e ) { }
}
if ( isset( \IPS\Request::i()->nodes ) and mb_strstr( \IPS\Request::i()->nodes, ',' ) === FALSE )
{
$class = $types[ \IPS\Request::i()->type ];
$nodeClass = $class::$containerNodeClass;
try
{
$node = $nodeClass::loadAndCheckPerms( \IPS\Request::i()->nodes );
$title = \IPS\Member::loggedIn()->language()->addToStack( $titleKey . '_area', FALSE, array( 'sprintf' => array( $term, $node->_title ) ) );
}
catch ( \OutOfRangeException $e ) { }
}
}
else
{
$title = \IPS\Member::loggedIn()->language()->addToStack( $titleKey, FALSE, array( 'sprintf' => array( $term ) ) );
}
$titleConditions = array();
$titleType = 'search_blurb_all_content';
/* Set content type */
if ( isset( \IPS\Request::i()->type ) and array_key_exists( \IPS\Request::i()->type, $types ) )
{
@@ -326,41 +284,58 @@ class _search extends \IPS\Dispatcher\Controller
$class = $types[ \IPS\Request::i()->type ];
try
{
$query->filterByItem( $class::load( \IPS\Request::i()->item ) );
$item = $class::loadAndCheckPerms( \IPS\Request::i()->item );
$query->filterByContent( array( \IPS\Content\Search\ContentFilter::init( $class )->onlyInItems( array( \IPS\Request::i()->item ) ) ) );
$baseUrl = $baseUrl->setQueryString( 'item', intval( \IPS\Request::i()->item ) );
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_in', FALSE, array( 'sprintf' => array( $item->mapped('title') ) ) );
}
catch ( \OutOfRangeException $e ) { }
}
else
{
$nodes = NULL;
$filter = \IPS\Content\Search\ContentFilter::init( $types[ \IPS\Request::i()->type ] );
$baseUrl = $baseUrl->setQueryString( 'type', \IPS\Request::i()->type );
if ( isset( \IPS\Request::i()->nodes ) )
{
$nodes = explode( ',', \IPS\Request::i()->nodes );
$nodeClass = $types[ \IPS\Request::i()->type ]::$containerNodeClass;
$node = $nodeClass::loadAndCheckPerms( \IPS\Request::i()->nodes );
$filter->onlyInContainers( explode( ',', \IPS\Request::i()->nodes ) );
$baseUrl = $baseUrl->setQueryString( 'nodes', \IPS\Request::i()->nodes );
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_in', FALSE, array( 'sprintf' => array( $node->_title ) ) );
}
else
{
$titleType = $types[ \IPS\Request::i()->type ]::$title . '_pl_lc';
}
$query->filterByContent( $types[ \IPS\Request::i()->type ], $nodes, isset( \IPS\Request::i()->comments ) ? \IPS\Request::i()->comments : ( isset( \IPS\Request::i()->replies ) ? ( \IPS\Request::i()->replies + 1 ) : NULL ), isset( \IPS\Request::i()->reviews ) ? \IPS\Request::i()->reviews : NULL, isset( \IPS\Request::i()->views ) ? \IPS\Request::i()->views : NULL );
$baseUrl = $baseUrl->setQueryString( 'type', \IPS\Request::i()->type );
if ( $nodes )
if ( isset( \IPS\Request::i()->search_min_comments ) )
{
$baseUrl = $baseUrl->setQueryString( 'nodes', \IPS\Request::i()->nodes );
$filter->minimumComments( \IPS\Request::i()->search_min_comments );
$baseUrl = $baseUrl->setQueryString( 'search_min_comments', \IPS\Request::i()->search_min_comments );
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_min_comments', FALSE, array( 'sprintf' => array( \IPS\Request::i()->search_min_comments ) ) );
}
if ( isset( \IPS\Request::i()->comments ) )
if ( isset( \IPS\Request::i()->search_min_replies ) )
{
$baseUrl = $baseUrl->setQueryString( 'comments', \IPS\Request::i()->comments );
$filter->minimumComments( \IPS\Request::i()->search_min_replies + 1 );
$baseUrl = $baseUrl->setQueryString( 'search_min_replies', \IPS\Request::i()->search_min_replies );
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_min_replies', FALSE, array( 'sprintf' => array( \IPS\Request::i()->search_min_replies ) ) );
}
if ( isset( \IPS\Request::i()->replies ) )
if ( isset( \IPS\Request::i()->search_min_reviews ) )
{
$baseUrl = $baseUrl->setQueryString( 'replies', \IPS\Request::i()->replies );
$filter->minimumReviews( \IPS\Request::i()->search_min_reviews );
$baseUrl = $baseUrl->setQueryString( 'search_min_reviews', \IPS\Request::i()->search_min_reviews );
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_min_reviews', FALSE, array( 'sprintf' => array( \IPS\Request::i()->search_min_reviews ) ) );
}
if ( isset( \IPS\Request::i()->reviews ) )
if ( isset( \IPS\Request::i()->search_min_views ) )
{
$baseUrl = $baseUrl->setQueryString( 'reviews', \IPS\Request::i()->reviews );
}
if ( isset( \IPS\Request::i()->views ) )
{
$baseUrl = $baseUrl->setQueryString( 'views', \IPS\Request::i()->views );
$filter->minimumViews( \IPS\Request::i()->search_min_views );
$baseUrl = $baseUrl->setQueryString( 'search_min_views', \IPS\Request::i()->search_min_views );
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_min_views', FALSE, array( 'sprintf' => array( \IPS\Request::i()->search_min_views ) ) );
}
$query->filterByContent( array( $filter ) );
}
}
@@ -372,6 +347,7 @@ class _search extends \IPS\Dispatcher\Controller
{
$query->filterByAuthor( $author );
$baseUrl = $baseUrl->setQueryString( 'author', $author->name );
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_author', FALSE, array( 'sprintf' => array( $author->name ) ) );
}
}
@@ -392,28 +368,36 @@ class _search extends \IPS\Dispatcher\Controller
{
case 'day':
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) );
$dateCondition = \IPS\Member::loggedIn()->language()->addToStack( "search_blurb_date_rel_{$l}", FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_date_rel_day' ) ) ) );
break;
case 'week':
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P1W' ) );
$dateCondition = \IPS\Member::loggedIn()->language()->addToStack( "search_blurb_date_rel_{$l}", FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_date_rel_week' ) ) ) );
break;
case 'month':
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) );
$dateCondition = \IPS\Member::loggedIn()->language()->addToStack( "search_blurb_date_rel_{$l}", FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_date_rel_month' ) ) ) );
break;
case 'six_months':
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P6M' ) );
$dateCondition = \IPS\Member::loggedIn()->language()->addToStack( "search_blurb_date_rel_{$l}", FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_date_rel_6months' ) ) ) );
break;
case 'year':
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P1Y' ) );
$dateCondition = \IPS\Member::loggedIn()->language()->addToStack( "search_blurb_date_rel_{$l}", FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_date_rel_year' ) ) ) );
break;
default:
$$l = \IPS\DateTime::ts( \IPS\Request::i()->$$key );
$dateCondition = \IPS\Member::loggedIn()->language()->addToStack( "search_blurb_date_{$l}", FALSE, array( 'sprintf' => array( $$l->localeDate() ) ) );
break;
}
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( "search_blurb_date_{$k}", FALSE, array( 'sprintf' => array( $dateCondition ) ) );
}
}
@@ -421,6 +405,51 @@ class _search extends \IPS\Dispatcher\Controller
}
}
/* Work out the title */
if ( \IPS\Request::i()->tags )
{
$tagList = array_map( function( $val )
{
return '\'' . htmlentities( $val, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . '\'';
}, explode( ',', \IPS\Request::i()->tags ) );
}
$title = '';
if ( \IPS\Request::i()->q )
{
if ( \IPS\Request::i()->tags )
{
if ( isset( \IPS\Request::i()->eitherTermsOrTags ) and \IPS\Request::i()->eitherTermsOrTags === 'and' )
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_term', FALSE, array( 'sprintf' => array( urldecode( \IPS\Request::i()->q ) ) ) );
$titleConditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_tag_condition', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $tagList, \IPS\Member::loggedIn()->language()->get('or_list_format') ) ) ) );
}
else
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_term_or_tag', FALSE, array( 'sprintf' => array( urldecode( \IPS\Request::i()->q ), \IPS\Member::loggedIn()->language()->formatList( $tagList, \IPS\Member::loggedIn()->language()->get('or_list_format') ) ) ) );
}
}
else
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_term', FALSE, array( 'sprintf' => array( urldecode( \IPS\Request::i()->q ) ) ) );
}
}
elseif ( \IPS\Request::i()->tags )
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_tag', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $tagList, \IPS\Member::loggedIn()->language()->get('or_list_format') ) ) ) );
}
if ( count( $titleConditions ) )
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_conditions', FALSE, array( 'sprintf' => array( $title, \IPS\Member::loggedIn()->language()->addToStack( $titleType ), \IPS\Member::loggedIn()->language()->formatList( $titleConditions ) ) ) );
}
elseif ( $titleType != 'search_blurb_all_content' )
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_with_type', FALSE, array( 'sprintf' => array( $title, \IPS\Member::loggedIn()->language()->addToStack( $titleType ) ) ) );
}
else
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'search_blurb_no_conditions', FALSE, array( 'sprintf' => array( $title ) ) );
}
/* Set page */
if ( isset( \IPS\Request::i()->page ) AND intval( \IPS\Request::i()->page ) > 0 )
{
@@ -446,15 +475,30 @@ class _search extends \IPS\Dispatcher\Controller
}
else
{
$query->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_CREATED );
$baseUrl = $baseUrl->setQueryString( 'sortby', 'newest' );
/* Default to relevancy which is a total score of relevancy + date + title weighted search */
$query->setOrder( \IPS\Content\Search\Query::ORDER_RELEVANCY );
$baseUrl = $baseUrl->setQueryString( 'sortby', 'relevancy' );
}
$flags = ( isset( \IPS\Request::i()->eitherTermsOrTags ) and \IPS\Request::i()->eitherTermsOrTags === 'and' ) ? \IPS\Content\Search\Query::TERM_AND_TAGS : \IPS\Content\Search\Query::TERM_OR_TAGS;
if ( isset( \IPS\Request::i()->search_and_or ) and \IPS\Request::i()->search_and_or === 'or' )
{
$flags = $flags | \IPS\Content\Search\Query::TERM_OR_MODE;
$baseUrl = $baseUrl->setQueryString( 'search_and_or', \IPS\Request::i()->search_and_or );
}
if ( isset( \IPS\Request::i()->search_in ) and \IPS\Request::i()->search_in === 'titles' )
{
$flags = $flags | \IPS\Content\Search\Query::TERM_TITLES_ONLY;
$baseUrl = $baseUrl->setQueryString( 'search_in', \IPS\Request::i()->search_in );
}
/* Run query */
$results = $query->excludeDisabledApps()->search(
$results = $query->search(
isset( \IPS\Request::i()->q ) ? ( \IPS\Request::i()->q ) : NULL,
isset( \IPS\Request::i()->tags ) ? explode( ',', \IPS\Request::i()->tags ) : NULL,
( isset( \IPS\Request::i()->eitherTermsOrTags ) and \IPS\Request::i()->eitherTermsOrTags === 'and' ) ? \IPS\Content\Search\Query::TERM_AND_TAGS : \IPS\Content\Search\Query::TERM_OR_TAGS
$flags
);
/* Get pagination */
@@ -466,13 +510,15 @@ class _search extends \IPS\Dispatcher\Controller
}
$pagination = trim( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $baseUrl, ceil( $results->count( TRUE ) / $query->resultsToGet ), $page, $query->resultsToGet ) );
/* Display results */
if ( \IPS\Request::i()->isAjax() )
{
$count = $results->count( TRUE );
\IPS\Output::i()->json( array(
'filters' => $this->_form()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ) ),
'content' => \IPS\Theme::i()->getTemplate( 'search' )->results( htmlentities( $term, \IPS\HTMLENTITIES, 'UTF-8', FALSE ), $title, $results, $pagination, $baseUrl, $results->count( TRUE ) ),
'filters' => $this->_form()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ), $baseUrl, $count ),
'hints' => \IPS\Theme::i()->getTemplate( 'search' )->hints( $baseUrl, $count ),
'content' => \IPS\Theme::i()->getTemplate( 'search' )->results( $this->_splitTermsForDisplay(), $title, $results, $pagination, $baseUrl, $count ),
'title' => $title,
'css' => array()
) );
@@ -483,9 +529,10 @@ class _search extends \IPS\Dispatcher\Controller
'Cache-Control' => "max-age=" . 30 * 60 . ", public" );
\IPS\Output::i()->httpHeaders += $httpHeaders;
\IPS\Output::i()->title = $title;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'search' )->search( htmlentities( $term, \IPS\HTMLENTITIES, 'UTF-8', FALSE ), $title, $results, $pagination, $baseUrl, $types, $this->_form()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ) ), $results->count( TRUE ) );
$count = $results->count( TRUE );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('search_results_title');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'search' )->search( $this->_splitTermsForDisplay(), $title, $results, $pagination, $baseUrl, $types, $this->_form()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'search' ), 'filters' ), $baseUrl, $count ), $count );
}
}
@@ -508,12 +555,26 @@ class _search extends \IPS\Dispatcher\Controller
/* Types */
$types = array( '' => 'search_everything' );
$contentTypes = $this->_contentTypes();
$contentToggles = array( 'tags', 'eitherTermsOrTags', 'author', 'elAdvancedSearch_dateFilters', 'startDate', 'updatedDate' );
$contentToggles = array();
$typeFields = array();
$typeFieldToggles = array( '' => $contentToggles );
$typeFieldToggles = array( '' => array( 'search_min_views', 'search_min_reviews', 'search_min_comments' ) );
$haveCommentClass = FALSE;
$haveReplyClass = FALSE;
$haveReviewClass = FALSE;
$dateOptions = array(
'any' => 'any',
'day' => 'last_24hr',
'week' => 'last_week',
'month' => 'last_month',
'six_months' => 'six_months',
'year' => 'year',
'custom' => 'custom'
);
/* Form tabs */
$form->addTab( 'search_tab_all' );
$form->addTab( 'search_tab_content' );
$form->addTab( 'search_tab_member' );
/* Figure out member fields to set toggles */
$memberToggles = array( 'joinedDate', 'core_members_group' );
@@ -540,10 +601,6 @@ class _search extends \IPS\Dispatcher\Controller
}
/* Type select */
if ( isset( \IPS\Request::i()->type ) and isset( $contentTypes[ \IPS\Request::i()->type ] ) )
{
$contentTypes = array( $contentTypes[ \IPS\Request::i()->type ] );
}
foreach ( $contentTypes as $k => $class )
{
$types[ $k ] = $k . '_pl';
@@ -569,36 +626,27 @@ class _search extends \IPS\Dispatcher\Controller
$typeFieldToggles[ $k ][] = 'search_min_reviews';
}
}
else
{
$typeFieldToggles[ $k ] = $memberToggles;
}
$typeFieldToggles[ $k ][] = 'elAdvancedSearch_appFilters';
}
$form->add( new \IPS\Helpers\Form\Radio( 'searchType', '', FALSE, array( 'options' => $types, 'toggles' => $typeFieldToggles ) ) );
$form->add( new \IPS\Helpers\Form\Radio( 'type', '', FALSE, array( 'options' => $types, 'toggles' => $typeFieldToggles ) ), NULL, 'search_tab_content' );
/* Term */
$form->add( new \IPS\Helpers\Form\Text( 'q' ) );
$form->add( new \IPS\Helpers\Form\Text( 'tags', \IPS\Request::i()->tags, FALSE, array( 'autocomplete' => array() ), NULL, NULL, NULL, 'tags' ) );
$form->add( new \IPS\Helpers\Form\Radio( 'eitherTermsOrTags', \IPS\Request::i()->eitherTermsOrTags, FALSE, array( 'options' => array( 'or' => 'termsortags_or_desc', 'and' => 'termsortags_and_desc' ) ), NULL, NULL, NULL, 'eitherTermsOrTags' ) );
$form->add( new \IPS\Helpers\Form\Text( 'q' ), NULL, 'search_tab_all' );
$form->add( new \IPS\Helpers\Form\Text( 'tags', \IPS\Request::i()->tags, FALSE, array( 'autocomplete' => array() ), NULL, NULL, NULL, 'tags' ), NULL, 'search_tab_content' );
$form->add( new \IPS\Helpers\Form\Radio( 'eitherTermsOrTags', \IPS\Request::i()->eitherTermsOrTags, FALSE, array( 'options' => array( 'or' => 'termsortags_or_desc', 'and' => 'termsortags_and_desc' ) ), NULL, NULL, NULL, 'eitherTermsOrTags' ), NULL, 'search_tab_content' );
/* Author */
$form->add( new \IPS\Helpers\Form\Member( 'author', NULL, FALSE, array(), NULL, NULL, NULL, 'author' ) );
$form->add( new \IPS\Helpers\Form\Member( 'author', NULL, FALSE, array(), NULL, NULL, NULL, 'author' ), NULL, 'search_tab_content' );
/* Dates */
$dateOptions = array(
'any' => 'any',
'day' => 'last_24hr',
'week' => 'last_week',
'month' => 'last_month',
'six_months' => 'six_months',
'year' => 'year',
'custom' => 'custom'
);
$form->add( new \IPS\Helpers\Form\Select( 'startDate', ( isset( \IPS\Request::i()->start_before ) or ( isset( \IPS\Request::i()->start_after ) and is_numeric( \IPS\Request::i()->start_after ) ) ) ? 'custom' : \IPS\Request::i()->start_after, FALSE, array( 'options' => $dateOptions, 'toggles' => array( 'custom' => array( 'elCustomDate_startDate' ) ) ), NULL, NULL, NULL, 'startDate' ) );
$form->add( new \IPS\Helpers\Form\DateRange( 'startDateCustom', array( 'start' => ( isset( \IPS\Request::i()->start_after ) and is_numeric( \IPS\Request::i()->start_after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->start_after ) : NULL, 'end' => isset( \IPS\Request::i()->start_before ) ? \IPS\DateTime::ts( \IPS\Request::i()->start_before ) : NULL ) ) );
$form->add( new \IPS\Helpers\Form\Select( 'updatedDate', ( isset( \IPS\Request::i()->updated_before ) or ( isset( \IPS\Request::i()->updated_after ) and is_numeric( \IPS\Request::i()->updated_after ) ) ) ? 'custom' : \IPS\Request::i()->updated_after, FALSE, array( 'options' => $dateOptions, 'toggles' => array( 'custom' => array( 'elCustomDate_updatedDate' ) ) ), NULL, NULL, NULL, 'updatedDate' ) );
$form->add( new \IPS\Helpers\Form\DateRange( 'updatedDateCustom', array( 'start' => ( isset( \IPS\Request::i()->updated_after ) and is_numeric( \IPS\Request::i()->updated_after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->updated_after ) : NULL, 'end' => isset( \IPS\Request::i()->updated_before ) ? \IPS\DateTime::ts( \IPS\Request::i()->updated_before ) : NULL ) ) );
$form->add( new \IPS\Helpers\Form\Select( 'startDate', ( isset( \IPS\Request::i()->start_before ) or ( isset( \IPS\Request::i()->start_after ) and is_numeric( \IPS\Request::i()->start_after ) ) ) ? 'custom' : \IPS\Request::i()->start_after, FALSE, array( 'options' => $dateOptions, 'toggles' => array( 'custom' => array( 'elCustomDate_startDate' ) ) ), NULL, NULL, NULL, 'startDate' ), NULL, 'search_tab_content' );
$form->add( new \IPS\Helpers\Form\DateRange( 'startDateCustom', array( 'start' => ( isset( \IPS\Request::i()->start_after ) and is_numeric( \IPS\Request::i()->start_after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->start_after ) : NULL, 'end' => isset( \IPS\Request::i()->start_before ) ? \IPS\DateTime::ts( \IPS\Request::i()->start_before ) : NULL ) ), NULL, 'search_tab_content' );
$form->add( new \IPS\Helpers\Form\Select( 'updatedDate', ( isset( \IPS\Request::i()->updated_before ) or ( isset( \IPS\Request::i()->updated_after ) and is_numeric( \IPS\Request::i()->updated_after ) ) ) ? 'custom' : \IPS\Request::i()->updated_after, FALSE, array( 'options' => $dateOptions, 'toggles' => array( 'custom' => array( 'elCustomDate_updatedDate' ) ) ), NULL, NULL, NULL, 'updatedDate' ), NULL, 'search_tab_content' );
$form->add( new \IPS\Helpers\Form\DateRange( 'updatedDateCustom', array( 'start' => ( isset( \IPS\Request::i()->updated_after ) and is_numeric( \IPS\Request::i()->updated_after ) ) ? \IPS\DateTime::ts( \IPS\Request::i()->updated_after ) : NULL, 'end' => isset( \IPS\Request::i()->updated_before ) ? \IPS\DateTime::ts( \IPS\Request::i()->updated_before ) : NULL ) ), NULL, 'search_tab_content' );
/* Other filters */
$form->add( new \IPS\Helpers\Form\Radio( 'search_in', \IPS\Request::i()->search_in, FALSE, array( 'options' => array( 'all' => 'titles_and_body', 'titles' => 'titles_only' ) ), NULL, NULL, NULL, 'searchIn' ), NULL, 'search_tab_content' );
$form->add( new \IPS\Helpers\Form\Radio( 'search_and_or', \IPS\Request::i()->search_and_or, FALSE, array( 'options' => array( 'and' => 'search_and', 'or' => 'search_or' ) ), NULL, NULL, NULL, 'andOr' ), NULL, 'search_tab_content' );
/* Nodes */
foreach ( $contentTypes as $k => $class )
@@ -608,36 +656,34 @@ class _search extends \IPS\Dispatcher\Controller
$nodeClass = $class::$containerNodeClass;
$field = new \IPS\Helpers\Form\Node( 'nodes', ( isset( \IPS\Request::i()->nodes ) ) ? \IPS\Request::i()->nodes : NULL, FALSE, array( 'class' => $nodeClass, 'multiple' => TRUE, 'permissionCheck' => 'view', ), NULL, NULL, NULL, $k . '_node' );
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $nodeClass::$nodeTitle );
$form->add( $field );
$form->add( $field, NULL, 'search_tab_content' );
}
}
/* Member group and joined */
if( ( isset( \IPS\Request::i()->searchType ) and \IPS\Request::i()->searchType === 'core_members' ) or !isset( \IPS\Request::i()->q ) )
{
$form->add(new \IPS\Helpers\Form\CheckboxSet('group', (isset(\IPS\Request::i()->group)) ? array_keys(\IPS\Request::i()->group) : array(), FALSE, array('options' => \IPS\Member\Group::groups(TRUE, FALSE), 'parse' => 'normal'), NULL, NULL, NULL, 'core_members_group'));
$form->add(new \IPS\Helpers\Form\Select('joinedDate', (isset(\IPS\Request::i()->start_before) or (isset(\IPS\Request::i()->start_after) and is_numeric(\IPS\Request::i()->start_after))) ? 'custom' : \IPS\Request::i()->start_after, FALSE, array('options' => $dateOptions, 'toggles' => array('custom' => array('elCustomDate_joinedDate'))), NULL, NULL, NULL, 'joinedDate'));
$form->add(new \IPS\Helpers\Form\DateRange('joinedDateCustom', array('start' => (isset(\IPS\Request::i()->start_after) and is_numeric(\IPS\Request::i()->start_after)) ? \IPS\DateTime::ts(\IPS\Request::i()->start_after) : NULL, 'end' => isset(\IPS\Request::i()->start_before) ? \IPS\DateTime::ts(\IPS\Request::i()->start_before) : NULL)));
}
/* Comments/Views */
$queryClass = \IPS\Content\Search\Query::init();
if ( $queryClass::SUPPORTS_JOIN_FILTERS )
{
if ( $haveCommentClass )
{
$form->add( new \IPS\Helpers\Form\Number( 'search_min_comments', isset( \IPS\Request::i()->comments ) ? \IPS\Request::i()->comments : 0, FALSE, array(), NULL, NULL, NULL, 'search_min_comments' ) );
$form->add( new \IPS\Helpers\Form\Number( 'search_min_comments', isset( \IPS\Request::i()->search_min_comments ) ? \IPS\Request::i()->search_min_comments : 0, FALSE, array(), NULL, NULL, NULL, 'search_min_comments' ), NULL, 'search_tab_content' );
}
if ( $haveReplyClass )
{
$form->add( new \IPS\Helpers\Form\Number( 'search_min_replies', isset( \IPS\Request::i()->replies ) ? \IPS\Request::i()->replies : 0, FALSE, array(), NULL, NULL, NULL, 'search_min_replies' ) );
$form->add( new \IPS\Helpers\Form\Number( 'search_min_replies', isset( \IPS\Request::i()->search_min_replies ) ? \IPS\Request::i()->search_min_replies : 0, FALSE, array(), NULL, NULL, NULL, 'search_min_replies' ), NULL, 'search_tab_content' );
}
if ( $haveReviewClass )
{
$form->add( new \IPS\Helpers\Form\Number( 'search_min_reviews', isset( \IPS\Request::i()->reviews ) ? \IPS\Request::i()->reviews : 0, FALSE, array(), NULL, NULL, NULL, 'search_min_reviews' ) );
$form->add( new \IPS\Helpers\Form\Number( 'search_min_reviews', isset( \IPS\Request::i()->search_min_reviews ) ? \IPS\Request::i()->search_min_reviews : 0, FALSE, array(), NULL, NULL, NULL, 'search_min_reviews' ), NULL, 'search_tab_content' );
}
$form->add( new \IPS\Helpers\Form\Number( 'search_min_views', isset( \IPS\Request::i()->views ) ? \IPS\Request::i()->views : 0, FALSE, array(), NULL, NULL, NULL, 'search_min_views' ) );
$form->add( new \IPS\Helpers\Form\Number( 'search_min_views', isset( \IPS\Request::i()->search_min_views ) ? \IPS\Request::i()->search_min_views : 0, FALSE, array(), NULL, NULL, NULL, 'search_min_views' ), NULL, 'search_tab_content' );
}
/* Member group and joined */
$groups = \IPS\Member\Group::groups(TRUE, FALSE);
$form->add(new \IPS\Helpers\Form\CheckboxSet('group', (isset(\IPS\Request::i()->group)) ? array_keys(\IPS\Request::i()->group) : array_keys( $groups ), FALSE, array('options' => $groups, 'parse' => 'normal'), NULL, NULL, NULL, 'core_members_group'), NULL, 'search_tab_member' );
$form->add(new \IPS\Helpers\Form\Select('joinedDate', (isset(\IPS\Request::i()->start_before) or (isset(\IPS\Request::i()->start_after) and is_numeric(\IPS\Request::i()->start_after))) ? 'custom' : \IPS\Request::i()->start_after, FALSE, array('options' => $dateOptions, 'toggles' => array('custom' => array('elCustomDate_joinedDate'))), NULL, NULL, NULL, 'joinedDate'), NULL, 'search_tab_member' );
$form->add(new \IPS\Helpers\Form\DateRange('joinedDateCustom', array('start' => (isset(\IPS\Request::i()->start_after) and is_numeric(\IPS\Request::i()->start_after)) ? \IPS\DateTime::ts(\IPS\Request::i()->start_after) : NULL, 'end' => isset(\IPS\Request::i()->start_before) ? \IPS\DateTime::ts(\IPS\Request::i()->start_before) : NULL)), NULL, 'search_tab_member' );
/* Profile fields for member searches */
$memberFields = array();
@@ -697,15 +743,15 @@ class _search extends \IPS\Dispatcher\Controller
{
foreach( $fieldsToAdd as $field )
{
$form->add( $field );
$form->add( $field, NULL, 'search_tab_member' );
}
}
}
}
/* If they submitted the advanced search form, redirect back (searching is a GET not a POST) */
if ( $values = $form->values() )
{
if( !\IPS\Request::i()->isAjax() AND ( ( $values['q'] or $values['tags'] ) or $values['searchType'] == 'core_members' ) )
if( !\IPS\Request::i()->isAjax() AND ( ( $values['q'] or $values['tags'] ) or $values['type'] == 'core_members' ) )
{
$url = \IPS\Http\Url::internal( 'app=core&module=search&controller=search', 'front', 'search' );
@@ -721,13 +767,13 @@ class _search extends \IPS\Dispatcher\Controller
{
$url = $url->setQueryString( 'eitherTermsOrTags', $values['eitherTermsOrTags'] );
}
if ( $values['searchType'] )
if ( $values['type'] )
{
$url = $url->setQueryString( 'type', $values['searchType'] );
$url = $url->setQueryString( 'type', $values['type'] );
if ( isset( $values[ $values['searchType'] . '_node' ] ) and !empty( $values[ $values['searchType'] . '_node' ] ) )
if ( isset( $values[ $values['type'] . '_node' ] ) and !empty( $values[ $values['type'] . '_node' ] ) )
{
$url = $url->setQueryString( 'nodes', implode( ',', array_keys( $values[ $values['searchType'] . '_node' ] ) ) );
$url = $url->setQueryString( 'nodes', implode( ',', array_keys( $values[ $values['type'] . '_node' ] ) ) );
}
if ( isset( $values['search_min_comments'] ) and $values['search_min_comments'] )
@@ -771,7 +817,7 @@ class _search extends \IPS\Dispatcher\Controller
$url = $url->setQueryString( $fieldName, $values[ $fieldName ] );
}
}
if( isset( $values['joinedDate'] ) AND $values['joinedDate'] != 'custom' )
{
$url = $url->setQueryString( 'start_after', $values['joinedDate'] );
@@ -825,19 +871,34 @@ class _search extends \IPS\Dispatcher\Controller
$types = array();
foreach ( \IPS\Content::routedClasses( TRUE, FALSE, TRUE ) as $class )
{
if( is_subclass_of( $class, 'IPS\Content\Searchable' ) )
if( is_subclass_of( $class, 'IPS\Content\Searchable' ) and $class::$includeInSiteSearch )
{
$key = mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) );
$types[ $key ] = $class;
}
}
if ( \IPS\Application\Module::get( 'core', 'members', 'front' )->can('view') )
{
$types['core_members'] = 'IPS\Member';
return $types;
}
/**
* Splits the search term into distinct matches
* e.g. one "two three" beccomes ['one', 'two three']
*
* @return string
*/
protected function _splitTermsForDisplay()
{
if( !isset( \IPS\Request::i()->q ) ){
return json_encode( array() );
}
return $types;
$words = preg_split("/[\s]*\\\"([^\\\"]+)\\\"[\s]*|[\s]*'([^']+)'[\s]*|[\s]+/", \IPS\Request::i()->q, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach( $words as $idx => $word ){
$words[ $idx ] = htmlentities( $word, \IPS\HTMLENTITIES, 'UTF-8', FALSE );
}
return json_encode( $words );
}
/**
@@ -847,6 +908,6 @@ class _search extends \IPS\Dispatcher\Controller
*/
protected function globalFilterOptions()
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'search' )->globalSearchMenuOptions() );
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'search' )->globalSearchMenuOptions( \IPS\Request::i()->checked ) );
}
}
@@ -33,7 +33,7 @@ class _ajaxcreate extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->error('node_error', '2C231/2', 403, '');
}
if ( \IPS\Member::loggedIn()->member_id and !\IPS\Member::loggedIn()->pp_setting_count_comments )
{
\IPS\Output::i()->redirect( \IPS\Member::loggedIn()->url()->setQueryString( 'tab', 'statuses' ) );
@@ -1,122 +0,0 @@
<?php
/**
* @brief Status Updates Feed
* @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 Aug 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\modules\front\status;
/* 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;
}
/**
* Status Updates Feed
*/
class _feed extends \IPS\Dispatcher\Controller
{
/**
* Status Updates Feed
*
* @return void
*/
protected function manage()
{
if ( !\IPS\Settings::i()->profile_comments )
{
\IPS\Output::i()->error( 'node_error', '2C231/2', 403, '' );
}
if ( isset( \IPS\Request::i()->following ) AND !\IPS\Member::loggedIn()->member_id )
{
\IPS\Output::i()->error( 'no_module_permission', '2C231/1', 403, '' );
}
$where = array();
$statuses = array();
if ( isset( \IPS\Request::i()->following ) )
{
$members = array();
foreach( \IPS\Db::i()->select( '*', 'core_follow', array( 'follow_app=? AND follow_area=? AND follow_member_id=?', 'core', 'member', \IPS\Member::loggedIn()->member_id ) ) AS $follow )
{
$members[] = $follow['follow_rel_id'];
}
if ( count( $members ) )
{
$where[] = array( \IPS\Db::i()->in( 'status_author_id', $members ) . ' OR ' . \IPS\Db::i()->in( 'status_member_id', $members ) );
}
}
$statuses = array();
if ( !isset( \IPS\Request::i()->following ) OR count( $where ) > 0 )
{
$offset = ( intval( ( \IPS\Request::i()->statusPage AND \IPS\Request::i()->statusPage > 0 ) ? \IPS\Request::i()->statusPage : 1 ) - 1 ) * 25;
$select = \IPS\core\Statuses\Status::getItemsWithPermission( $where, NULL, array( $offset, 25 ), 'read', NULL );
$statuses['count'] = (int) \IPS\Db::i()->select( 'COUNT(*)', 'core_member_status_updates' )->first();
$statuses['statuses'] = iterator_to_array( $select );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'status_updates' );
if ( isset( \IPS\Request::i()->following ) )
{
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'people_i_follow' ) );
}
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/statuses.css' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/statuses_responsive.css' ) );
}
if ( \IPS\core\Statuses\Status::canCreate( \IPS\Member::loggedIn() ) AND !isset( \IPS\Request::i()->following ) )
{
$form = new \IPS\Helpers\Form( 'new_status', 'status_new' );
foreach( \IPS\core\Statuses\Status::formElements() AS $k => $element )
{
$form->add( $element );
}
if ( $values = $form->values() )
{
$status = \IPS\core\Statuses\Status::createFromForm( $values );
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'profile', 'core', 'front' )->statusContainer( $status ) );
}
else
{
\IPS\Output::i()->redirect( $status->url() );
}
}
$formTpl = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'statusTemplate' ) );
if ( \IPS\core\Statuses\Status::moderateNewItems( \IPS\Member::loggedIn() ) )
{
$formTpl = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $formTpl;
}
}
else
{
$formTpl = NULL;
}
$pagination = ( isset( $statuses['count'] ) ) ? trim( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( isset( \IPS\Request::i()->following ) ? \IPS\Http\Url::internal( 'app=core&module=status&controller=feed&following=1', NULL, 'status_following' ) : \IPS\Http\Url::internal( 'app=core&module=status&controller=feed', NULL, 'status' ), ceil( $statuses['count'] / 25 ), \IPS\Request::i()->statusPage ?: 1, 25, TRUE, 'statusPage' ) ) : NULL;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'status' )->feed( $statuses, $formTpl, $pagination );
}
}
@@ -57,7 +57,7 @@ class _ajax extends \IPS\Dispatcher\Controller
$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 ),
'name' => \IPS\Dispatcher::i()->controllerLocation == 'admin' ? $member->group['prefix'] . htmlspecialchars( $member->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . $member->group['suffix'] : htmlspecialchars( $member->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'extra' => \IPS\Dispatcher::i()->controllerLocation == 'admin' ? $member->email : $member->groupName,
'photo' => (string) $member->photo,
);
@@ -194,7 +194,7 @@ class _ajax extends \IPS\Dispatcher\Controller
public function topContributors()
{
/* How many? */
$limit = intval( ( isset( \IPS\Request::i()->limit ) and \IPS\Request::i()->limit < 20 ) ? \IPS\Request::i()->limit : 5 );
$limit = intval( ( isset( \IPS\Request::i()->limit ) and \IPS\Request::i()->limit <= 25 ) ? \IPS\Request::i()->limit : 5 );
/* What timeframe? */
$where = array( array( 'member_received > 0' ) );
@@ -240,4 +240,86 @@ class _ajax extends \IPS\Dispatcher\Controller
\IPS\Output::i()->output = $output;
}
}
/**
* Menu Preview
*
* @retun void
*/
public function menuPreview()
{
if ( isset( \IPS\Request::i()->theme ) )
{
\IPS\Theme::switchTheme( \IPS\Request::i()->theme, FALSE );
}
$preview = \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->navBar( TRUE );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'system/menumanager.css', 'core', 'admin' ) );
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'applications', 'core', 'admin' )->menuPreviewWrapper( $preview ) );
}
/**
* Instant Notifications
*
* @retun void
*/
public function instantNotifications()
{
/* If auto-polling isn't enabled, kill the polling now */
if ( !\IPS\Settings::i()->auto_polling_enabled )
{
\IPS\Output::i()->json( array( 'error' => 'auto_polling_disabled' ) );
return;
}
/* Get the intitial counts */
$return = array( 'notifications' => array( 'count' => \IPS\Member::loggedIn()->notification_cnt, 'data' => array() ), 'messages' => array( 'count' => \IPS\Member::loggedIn()->msg_count_new, 'data' => array() ) );
/* If there's new notifications, get the actual data */
if ( \IPS\Request::i()->notifications < $return['notifications']['count'] )
{
$notificationsDifference = $return['notifications']['count'] - \IPS\Request::i()->notifications;
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_notifications', array( 'member=? AND ( read_time IS NULL OR read_time<? )', \IPS\Member::loggedIn()->member_id, time() ), 'updated_time DESC', $notificationsDifference ), 'IPS\Notification\Inline' ) as $notification )
{
$data = $notification->getData();
$return['notifications']['data'][] = array(
'id' => $notification->id,
'title' => $data['title'],
'url' => (string) $data['url'],
'content' => isset( $data['content'] ) ? $data['content'] : NULL,
'date' => $notification->updated_time->getTimestamp(),
'author_photo' => $data['author'] ? $data['author']->photo : NULL
);
}
}
/* If there's new messages, get the actual data */
if ( !\IPS\Member::loggedIn()->members_disable_pm and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'messaging' ) ) )
{
if ( \IPS\Request::i()->messages < $return['messages']['count'] )
{
$messagesDifference = $return['messages']['count'] - \IPS\Request::i()->messages;
foreach ( \IPS\Db::i()->select( 'map_topic_id', 'core_message_topic_user_map', array( 'map_user_id=? AND map_user_active=1 AND map_has_unread=1 AND map_ignore_notification=0', \IPS\Member::loggedIn()->member_id ), 'map_last_topic_reply DESC', $messagesDifference ) as $conversationId )
{
$conversation = \IPS\core\Messenger\Conversation::load( $conversationId );
$message = $conversation->comments( 1, 0, 'date', 'desc' );
$return['messages']['data'][] = array(
'id' => $conversation->id,
'title' => $conversation->title,
'url' => (string) $conversation->url()->setQueryString( 'latest', 1 ),
'message' => $message->truncated(),
'date' => $message->mapped('date'),
'author_photo' => (string) $message->author()->photo
);
}
}
}
/* And return */
\IPS\Output::i()->json( $return );
}
}
@@ -30,7 +30,18 @@ class _editor extends \IPS\Dispatcher\Controller
*/
protected function link()
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->link( \IPS\Request::i()->current, \IPS\Request::i()->editorId );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->link( \IPS\Request::i()->current, \IPS\Request::i()->editorId, isset( \IPS\Request::i()->block ) );
}
/**
* Code Dialog
*
* @return void
*/
protected function code()
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'codemirror/codemirror.css', 'core', 'interface' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->code( \IPS\Request::i()->val, \IPS\Request::i()->editorId, md5( uniqid() ), \IPS\Request::i()->lang ?: 'html' );
}
/**
@@ -43,21 +54,20 @@ class _editor extends \IPS\Dispatcher\Controller
$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];
$ratio = round( \IPS\Request::i()->height / \IPS\Request::i()->width, 2 );
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 );
\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()->float, \IPS\Request::i()->link, $ratio );
}
/**
@@ -139,6 +149,9 @@ class _editor extends \IPS\Dispatcher\Controller
$emoticons[ $row['emo_set'] ]['emoticons'][] = array(
'src' => \IPS\File::get( 'core_Emoticons', $row['image'] )->url,
'srcset' => $row['image_2x'] ? \IPS\File::get( 'core_Emoticons', $row['image_2x'] )->url . ' 2x' : FALSE,
'height' => $row['height'] ?: FALSE,
'width' => $row['width'] ?: FALSE,
'text' => $row['typed']
);
}
@@ -159,7 +172,7 @@ class _editor extends \IPS\Dispatcher\Controller
protected function myMedia()
{
/* Init */
$perPage = 7;
$perPage = 12;
$search = isset( \IPS\Request::i()->search ) ? \IPS\Request::i()->search : null;
/* Get all our available sources */
@@ -109,9 +109,10 @@ class _followed extends \IPS\Dispatcher\Controller
else
{
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('my_followed_content');
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_system.js', 'core' ) );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu_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()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('menu_followed_content') );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->followedContent( $types, $currentAppModule, $currentType, $output );
}
}
@@ -324,7 +324,10 @@ class _ignore extends \IPS\Dispatcher\Controller
$ignore->ignore_id = $member->member_id;
$ignore->save();
}
\IPS\Member::loggedIn()->members_bitoptions['has_no_ignored_users'] = FALSE;
\IPS\Member::loggedIn()->save();
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'result' => 'ok' ) );
@@ -91,6 +91,7 @@ class _login extends \IPS\Dispatcher\Controller
else
{
/* Display Login Form */
\IPS\Output::i()->allowDefaultWidgets = FALSE;
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('login');
@@ -117,7 +118,7 @@ class _login extends \IPS\Dispatcher\Controller
\IPS\Request::i()->setCookie( 'anon_login', 1 );
}
$member->checkLoginKey();
\IPS\Session::i()->setMember( $member );
if ( $rememberMe )
{
@@ -202,7 +203,16 @@ class _login extends \IPS\Dispatcher\Controller
}
}
$redirectUrl = ( !empty( $_SERVER['HTTP_REFERER'] ) ) ? \IPS\Http\Url::external( $_SERVER['HTTP_REFERER'] ) : \IPS\Http\Url::internal( '' );
if( !empty( $_SERVER['HTTP_REFERER'] ) )
{
$referrer = new \IPS\Http\Url( $_SERVER['HTTP_REFERER'] );
$redirectUrl = ( $referrer->isInternal and isset( $referrer->queryString['do'] ) and $referrer->queryString['do'] != 'validating' ) ? $referrer : \IPS\Http\Url::internal('');
}
else
{
$redirectUrl = \IPS\Http\Url::internal( '' );
}
$member = \IPS\Member::loggedIn();
/* Are we logging out back to an admin user? */
@@ -111,7 +111,7 @@ class _metatags extends \IPS\Dispatcher\Controller
\IPS\Output::i()->error( 'meta_editor_no_admin', '2C155/1', 403, '' );
}
if( !\IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'settings', 'seo_manage' ) )
if( !\IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'promotion', 'seo_manage' ) )
{
\IPS\Output::i()->error( 'meta_editor_no_acpperm', '3C155/2', 403, '' );
}
@@ -115,7 +115,21 @@ class _notifications extends \IPS\Dispatcher\Controller
'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'] ) );
/* Changed in 4.1: since email_notifications_once is new, combined show_pm_popup in and made a checkbox set for better organization */
$notificationPrefValues = array();
if ( \IPS\Member::loggedIn()->members_bitoptions['show_pm_popup'] )
{
$notificationPrefValues[] = 'show_pm_popup';
}
if ( \IPS\Member::loggedIn()->members_bitoptions['email_notifications_once'] )
{
$notificationPrefValues[] = 'email_notifications_once';
}
if ( !\IPS\Member::loggedIn()->members_bitoptions['disable_notification_sounds'] )
{
$notificationPrefValues[] = 'enable_notification_sounds';
}
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'notification_prefs', $notificationPrefValues, FALSE, array( 'options' => array( 'show_pm_popup' => 'show_pm_popup', 'email_notifications_once' => 'email_notifications_once', 'enable_notification_sounds' => 'enable_notification_sounds' ), 'multiple' => TRUE ) ) );
$form->addMatrix( 'notifications', \IPS\Notification::buildMatrix( \IPS\Member::loggedIn() ) );
/* Handle submissions */
@@ -127,21 +141,34 @@ class _notifications extends \IPS\Dispatcher\Controller
'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['show_pm_popup'] = ( is_array( $values['notification_prefs'] ) AND in_array( 'show_pm_popup', $values['notification_prefs'] ) ) ? 1 : 0;
\IPS\Member::loggedIn()->members_bitoptions['email_notifications_once'] = ( is_array( $values['notification_prefs'] ) AND in_array( 'email_notifications_once', $values['notification_prefs'] ) ) ? 1 : 0;
\IPS\Member::loggedIn()->members_bitoptions['disable_notification_sounds'] = ( is_array( $values['notification_prefs'] ) AND in_array( 'enable_notification_sounds', $values['notification_prefs'] ) ) ? 0 : 1;
\IPS\Notification::saveMatrix( \IPS\Member::loggedIn(), $values );
/* Refetch config to see if inline report center notification is set. We have to do this because if toggling report center
option is disabled but inline is forced on by the admin, the setting won't be included in the $values array but the saveMatrix()
method will automatically set it and calling notificationsConfiguration() will pull the data directly from the db. */
$config = \IPS\Member::loggedIn()->notificationsConfiguration();
if ( isset( $config['report_center'] ) and !in_array( 'inline', $config['report_center'] ) )
{
\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');
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=notifications&do=options', 'front', 'notifications_options' ), 'saved' );
}
/* Display */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_system.js', 'core' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/notification_settings.css' ) );
\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') );
@@ -218,6 +245,7 @@ class _notifications extends \IPS\Dispatcher\Controller
/* Get thing */
$thing = NULL;
$indexId = NULL;
try
{
if ( in_array( 'IPS\Node\Model', class_parents( $class ) ) )
@@ -240,6 +268,13 @@ class _notifications extends \IPS\Dispatcher\Controller
{
$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') ) ) );
/* Work out the index ID */
try
{
$indexId = \IPS\Content\Search\Index::i()->getIndexId( $thing );
}
catch ( \UnderflowException $e ) { }
/* Set navigation */
$container = NULL;
@@ -259,7 +294,8 @@ class _notifications extends \IPS\Dispatcher\Controller
}
else
{
$thing = $class::load( \IPS\Request::i()->follow_id );
$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 */
@@ -386,7 +422,8 @@ class _notifications extends \IPS\Dispatcher\Controller
'follow_notify_meta' => '',
'follow_notify_freq' => ( $class == "IPS\Member" ) ? 'immediate' : $values['follow_type'],
'follow_notify_sent' => 0,
'follow_visible' => 1
'follow_visible' => 1,
'follow_index_id' => $indexId,
);
if ( $current )
{
@@ -634,13 +671,27 @@ class _notifications extends \IPS\Dispatcher\Controller
\IPS\Output::i()->error( 'node_error', '2C154/6', 404, '' );
}
if ( \IPS\Request::i()->follow_area == 'member' )
if ( \IPS\Request::i()->follow_area == 'member' && ( !isset( \IPS\Request::i()->button_type ) || \IPS\Request::i()->button_type === 'search' ) )
{
\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 );
if ( isset( \IPS\Request::i()->button_type ) && \IPS\Request::i()->button_type === 'search' )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile' )->memberSearchFollowButton( \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( '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 );
if ( \IPS\Request::i()->button_type == 'manage' )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system' )->manageFollowButton( \IPS\Request::i()->follow_app, \IPS\Request::i()->follow_area, \IPS\Request::i()->follow_id );
}
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 );
}
}
}
}
@@ -36,7 +36,8 @@ class _register extends \IPS\Dispatcher\Controller
}
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' )
and \IPS\Request::i()->do !== 'changeEmail' and \IPS\Request::i()->do !== 'validate'
and \IPS\Request::i()->do !== 'validating' and \IPS\Request::i()->do !== 'reconfirm' )
{
\IPS\Output::i()->error( 'reg_disabled', '2S129/5', 403, '' );
}
@@ -152,7 +153,7 @@ class _register extends \IPS\Dispatcher\Controller
/* 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()->allowDefaultWidgets = FALSE;
\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 );
}
@@ -447,10 +448,20 @@ class _register extends \IPS\Dispatcher\Controller
{
\IPS\Member::loggedIn()->email = $values['email_address'];
if( \IPS\Member::loggedIn()->spamService() == 4 )
if( \IPS\Settings::i()->spam_service_enabled )
{
\IPS\Member::loggedIn()->delete();
\IPS\Output::i()->error( 'spam_denied_account', '2S272/1', 403, '' );
if( \IPS\Member::loggedIn()->spamService() == 4 )
{
$action = \IPS\Settings::i()->spam_service_action_4;
/* Any other action will automatically be handled by the call to spamService() */
if( $action == 4 )
{
\IPS\Member::loggedIn()->delete();
}
\IPS\Output::i()->error( 'spam_denied_account', '2S272/1', 403, '' );
}
}
/* If email validation is enabled add a validating record */
@@ -570,4 +581,37 @@ class _register extends \IPS\Dispatcher\Controller
/* Redirect */
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ), 'reg_canceled' );
}
/**
* Reconfirm terms or privacy policy
*
* @return void
*/
protected function reconfirm()
{
/* Generate form */
$form = new \IPS\Helpers\Form;
$form->class = 'ipsForm_vertical';
$form->add( new \IPS\Helpers\Form\Checkbox( 'reconfirm_checkbox', NULL, FALSE, array(), function( $val )
{
if ( !$val )
{
throw new \InvalidArgumentException('reg_not_agreed_terms');
}
} ) );
/* Handle submissions */
if ( $values = $form->values() )
{
\IPS\Member::loggedIn()->members_bitoptions['must_reaccept_privacy'] = FALSE;
\IPS\Member::loggedIn()->members_bitoptions['must_reaccept_terms'] = FALSE;
\IPS\Member::loggedIn()->save();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('') );
}
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('terms_of_use');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('system')->reconfirmTerms( \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_terms'], \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_privacy'], $form );
}
}
@@ -507,7 +507,7 @@ class _settings extends \IPS\Dispatcher\Controller
{
$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');
$options['none'] = \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 ) ),
@@ -1,694 +0,0 @@
<?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 );
}
}
@@ -126,7 +126,7 @@ class _vse extends \IPS\Dispatcher\Controller
}
$field = new $class( "core_theme_setting_title_{$data['sc_id']}", $value, false, $options );
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $data['sc_title'] );
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $data['sc_title'], FALSE, array( 'escape' => true ) );
$form->add( $field );
}
}
@@ -283,7 +283,7 @@ class _warnings extends \IPS\Content\Controller
$reason = \IPS\core\Warnings\Reason::load( \IPS\Request::i()->id );
/* Add in the remove properties */
if ( $reason->remove )
if ( $reason->remove AND $reason->remove != -1 )
{
$date = \IPS\DateTime::create();
if ( $reason->remove_unit == 'h' )