Version 4.1.2
This commit is contained in:
1 parent
3ba79295ee
commit
28bd025b35
1131 files changed
+63658
-20579
No files matched your search
@@ -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' )
|
||||
|
||||
Reference in new issue
Block a user