Version 4.7.0
This commit is contained in:
1 parent
517a5e1f70
commit
8ba7d43898
1933 files changed
+65613
-11332
No files matched your search
@@ -22,6 +22,18 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _directory extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
* @example array(
|
||||
'community_area' => array( 'value' => 'search', 'odkUpdate' => 'true' )
|
||||
* )
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'clubs', 'odkUpdate' => 'true']
|
||||
);
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
|
||||
@@ -27,6 +27,14 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
* @brief Page
|
||||
*/
|
||||
protected $page;
|
||||
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'clubs', 'odkUpdate' => 'true']
|
||||
);
|
||||
|
||||
/**
|
||||
* Execute
|
||||
|
||||
@@ -31,6 +31,14 @@ class _view extends \IPS\Helpers\CoverPhoto\Controller
|
||||
* @brief The logged in user's status
|
||||
*/
|
||||
protected $memberStatus;
|
||||
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'clubs', 'odkUpdate' => 'true']
|
||||
);
|
||||
|
||||
/**
|
||||
* Execute
|
||||
@@ -135,15 +143,6 @@ class _view extends \IPS\Helpers\CoverPhoto\Controller
|
||||
{
|
||||
\IPS\Output::i()->redirect( (string) $firstTab[ $key ]['href'] );
|
||||
}
|
||||
|
||||
/* If this is a closed club, and we don't have permission to read it, show the member page instead */
|
||||
if ( $this->club->type == \IPS\Member\Club::TYPE_CLOSED && !$this->club->canRead() )
|
||||
{
|
||||
$this->members();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( $key == 'club_members' )
|
||||
{
|
||||
$this->members();
|
||||
@@ -153,7 +152,6 @@ class _view extends \IPS\Helpers\CoverPhoto\Controller
|
||||
$this->overview();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1124,7 +1122,6 @@ class _view extends \IPS\Helpers\CoverPhoto\Controller
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->club->url()->setQueryString( 'rulesAcknowledged', 1 ), 'accepted' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->club->acknowledgeRules( \IPS\Member::loggedIn() );
|
||||
@@ -1553,7 +1550,7 @@ class _view extends \IPS\Helpers\CoverPhoto\Controller
|
||||
/* Build Form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$node->clubForm( $form );
|
||||
$node->clubForm( $form, $this->club );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
@@ -1584,13 +1581,14 @@ class _view extends \IPS\Helpers\CoverPhoto\Controller
|
||||
|
||||
/* Load */
|
||||
$class = \IPS\Request::i()->type;
|
||||
|
||||
if( !$class instanceof \IPS\Node\Model )
|
||||
{
|
||||
throw new \Exception;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if ( !\in_array( 'IPS\Node\Model', class_parents( $class ) ) )
|
||||
{
|
||||
throw new \Exception;
|
||||
}
|
||||
|
||||
$node = $class::load( (int) \IPS\Request::i()->node );
|
||||
$club = $node->club();
|
||||
if ( !$club or $club->id !== $this->club->id )
|
||||
|
||||
@@ -54,6 +54,11 @@ class _popular extends \IPS\Dispatcher\Controller
|
||||
$tabs[] = $addTab;
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Application::appIsEnabled('cloud') and \IPS\cloud\Application::featureIsEnabled('trending') )
|
||||
{
|
||||
$tabs[] = 'trending';
|
||||
}
|
||||
|
||||
$activeTab = ( isset( \IPS\Request::i()->tab ) and \in_array(\IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : \IPS\Settings::i()->reputation_leaderboard_default_tab;
|
||||
|
||||
@@ -63,7 +68,13 @@ class _popular extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_tabs_' . $activeTab );
|
||||
|
||||
$content = $this->$activeTab();
|
||||
|
||||
|
||||
/* Data Layer Context Property */
|
||||
if ( \IPS\Settings::i()->core_datalayer_enabled AND ! \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\core\DataLayer::i()->addContextProperty( 'community_area', 'leaderboard', true );
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $content ), 200, 'text/html' );
|
||||
@@ -148,12 +159,12 @@ class _popular extends \IPS\Dispatcher\Controller
|
||||
if ( \IPS\Content\Reaction::isLikeMode() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['leader_rep_total'] = \IPS\Member::loggedIn()->language()->addToStack( 'leader_rep_total_likes' );
|
||||
\IPS\Member::loggedIn()->language()->words['leaderboard_history__desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_history_desc', NULL, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_history_likes') ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['leaderboard_history__desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_history_desc', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_history_likes') ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['leader_rep_total'] = \IPS\Member::loggedIn()->language()->addToStack( 'leader_rep_total_rep' );
|
||||
\IPS\Member::loggedIn()->language()->words['leaderboard_history__desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_history_desc', NULL, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_history_rep') ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['leaderboard_history__desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_history_desc', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_history_rep') ) ) );
|
||||
}
|
||||
|
||||
/* Parsers */
|
||||
@@ -179,7 +190,7 @@ class _popular extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( \IPS\Output::i()->title, $table->page ) ) );
|
||||
}
|
||||
|
||||
|
||||
return (string) $table;
|
||||
}
|
||||
}
|
||||
@@ -287,8 +298,8 @@ class _popular extends \IPS\Dispatcher\Controller
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'popular_date', 'continue' );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$customStart = isset( \IPS\Request::i()->custom_date_start ) ? \IPS\Request::i()->custom_date_start : NULL;
|
||||
$customEnd = isset( \IPS\Request::i()->custom_date_end ) ? \IPS\Request::i()->custom_date_end : NULL;
|
||||
$customStart = ( isset( \IPS\Request::i()->custom_date_start ) and \is_numeric( \IPS\Request::i()->custom_date_start ) ) ? (int) \IPS\Request::i()->custom_date_start : NULL;
|
||||
$customEnd = ( isset( \IPS\Request::i()->custom_date_end ) and \is_numeric( \IPS\Request::i()->custom_date_end ) ) ? (int) \IPS\Request::i()->custom_date_end : NULL;
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\DateRange( 'custom_date', array( 'start' => $customStart, 'end' => $customEnd ), FALSE, array( 'start' => array( 'min' => $dates[ 'oldest' ], 'time' => false ) ) ) );
|
||||
|
||||
@@ -327,7 +338,7 @@ class _popular extends \IPS\Dispatcher\Controller
|
||||
if ( isset( \IPS\Request::i()->in ) and isset( $areas[ \IPS\Request::i()->in ] ) )
|
||||
{
|
||||
$appWhere = " AND rep_class='" . \IPS\Db::i()->escape_string( $areas[ \IPS\Request::i()->in ][ 0 ] ) . "'";
|
||||
$descApp = \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_in_app', NULL, array( 'sprintf' => array( $areas[ \IPS\Request::i()->in ][ 1 ] ) ) );
|
||||
$descApp = \IPS\Member::loggedIn()->language()->addToStack( 'leaderboard_in_app', FALSE, array( 'sprintf' => array( $areas[ \IPS\Request::i()->in ][ 1 ] ) ) );
|
||||
$customApp = TRUE;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -50,7 +50,7 @@ class _rss extends \IPS\Dispatcher\Controller
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->member_id );
|
||||
|
||||
/* Make sure we have an actual member, and that the key matches. If it doesn't, we can bubble up and see if the feed works for guests, and just use that */
|
||||
if ( $member->member_id AND \IPS\Login::compareHashes( (string) \IPS\Request::i()->key, md5( $member->member_id . $member->email . $member->member_pass_hash . $member->member_pass_salt ) ) )
|
||||
if ( $member->member_id AND \IPS\Login::compareHashes( $member->getUniqueMemberHash(), (string) \IPS\Request::i()->key ) )
|
||||
{
|
||||
/* Make sure we have access to this feed. */
|
||||
if ( $feed->groups == '*' OR $member->inGroup( $feed->groups ) )
|
||||
|
||||
@@ -22,6 +22,14 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _streams extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'activity_stream', 'odkUpdate' => 'true']
|
||||
);
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
@@ -73,16 +81,26 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* RSS validate? */
|
||||
$member = NULL;
|
||||
|
||||
|
||||
if ( isset( \IPS\Request::i()->rss ) )
|
||||
{
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->member );
|
||||
if ( !\IPS\Login::compareHashes( md5( ( $member->members_pass_hash ?: $member->email ) . $member->members_pass_salt ), (string) \IPS\Request::i()->key ) )
|
||||
if ( isset( \IPS\Request::i()->member ) AND isset( \IPS\Request::i()->key ) )
|
||||
{
|
||||
$member = NULL;
|
||||
$member = \IPS\Member::load( \IPS\Request::i()->member );
|
||||
|
||||
if ( !$member->member_id OR !\IPS\Login::compareHashes( $member->getUniqueMemberHash(), (string) \IPS\Request::i()->key ) )
|
||||
{
|
||||
$member = NULL;
|
||||
}
|
||||
|
||||
/* If we do not have a specific member, and this member is not allowed to view the site, throw an error as they do not have permission */
|
||||
if ( ! $member and ! \IPS\Member::loggedIn()->group['g_view_board'] )
|
||||
{
|
||||
\IPS\Output::i()->error( 'stream_no_permission', '2C280/G', 403, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$form = NULL;
|
||||
/* Viewing a particular stream? */
|
||||
if ( isset( \IPS\Request::i()->id ) )
|
||||
@@ -205,7 +223,7 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
/* but only if we haven't submitted the form on this request */
|
||||
if( !\IPS\Request::i()->stream_submitted )
|
||||
{
|
||||
$streamFields = array( 'include_comments', 'classes', 'ownership', 'custom_members', 'read', 'follow', 'followed_types', 'date_type', 'date_start', 'date_end', 'date_relative_days', 'sort', 'tags' );
|
||||
$streamFields = array( 'include_comments', 'classes', 'ownership', 'custom_members', 'read', 'follow', 'followed_types', 'date_type', 'date_start', 'date_end', 'date_relative_days', 'sort', 'tags', 'solved' );
|
||||
|
||||
/* Clubs enabled? */
|
||||
if( \IPS\Settings::i()->clubs )
|
||||
@@ -296,10 +314,40 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
$form = $this->_buildForm( $stream );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Condensed or expanded? */
|
||||
$view = 'expanded';
|
||||
$streamID = ( \IPS\Request::i()->id ) ? \IPS\Request::i()->id : 'all';
|
||||
|
||||
if( isset( \IPS\Request::i()->view ) AND \IPS\Login::compareHashes( (string) \IPS\Session::i()->csrfKey, (string) \IPS\Request::i()->csrfKey ) )
|
||||
{
|
||||
$view = \IPS\Request::i()->view;
|
||||
|
||||
\IPS\Request::i()->setCookie( 'stream_view_' . $streamID, \IPS\Request::i()->view, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y' ) ) );
|
||||
|
||||
if( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $stream->url() );
|
||||
}
|
||||
}
|
||||
elseif ( isset( \IPS\Request::i()->cookie['stream_view_' . $streamID] ) )
|
||||
{
|
||||
$view = \IPS\Request::i()->cookie['stream_view_' . $streamID];
|
||||
}
|
||||
else
|
||||
{
|
||||
$view = $stream->default_view;
|
||||
}
|
||||
|
||||
/* Ensure correct params are set for view mode */
|
||||
if ( $view === 'condensed' )
|
||||
{
|
||||
$stream->include_comments = FALSE;
|
||||
}
|
||||
|
||||
/* Build the query */
|
||||
$query = $stream->query( $member );
|
||||
|
||||
|
||||
/* Set page or the before/after date */
|
||||
$currentPage = 1;
|
||||
if ( isset( \IPS\Request::i()->page ) AND \intval( \IPS\Request::i()->page ) > 0 )
|
||||
@@ -308,8 +356,8 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
$query->setPage( $currentPage );
|
||||
}
|
||||
|
||||
$before = isset( \IPS\Request::i()->before ) ? \IPS\Request::i()->before : null;
|
||||
$after = isset( \IPS\Request::i()->after ) ? \IPS\Request::i()->after : null;
|
||||
$before = ( isset( \IPS\Request::i()->before ) and \is_numeric( \IPS\Request::i()->before ) ) ? (int) \IPS\Request::i()->before : null;
|
||||
$after = ( isset( \IPS\Request::i()->after ) and \is_numeric( \IPS\Request::i()->after ) ) ? (int) \IPS\Request::i()->after : null;
|
||||
|
||||
/* If we sort by oldest, then we need to switch these values */
|
||||
if ( $stream->sort == 'oldest' )
|
||||
@@ -380,30 +428,6 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
$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()->view ) AND \IPS\Login::compareHashes( (string) \IPS\Session::i()->csrfKey, (string) \IPS\Request::i()->csrfKey ) )
|
||||
{
|
||||
$view = \IPS\Request::i()->view;
|
||||
|
||||
\IPS\Request::i()->setCookie( 'stream_view_' . $streamID, \IPS\Request::i()->view, \IPS\DateTime::create()->add( new \DateInterval( 'P1Y' ) ) );
|
||||
|
||||
if( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $stream->url() );
|
||||
}
|
||||
}
|
||||
elseif ( isset( \IPS\Request::i()->cookie['stream_view_' . $streamID] ) )
|
||||
{
|
||||
$view = \IPS\Request::i()->cookie['stream_view_' . $streamID];
|
||||
}
|
||||
else
|
||||
{
|
||||
$view = $stream->default_view;
|
||||
}
|
||||
|
||||
/* If this is an AJAX request, just show the results */
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
@@ -453,7 +477,7 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
$rssLink = \IPS\Http\Url::internal( "app=core&module=discover&controller=streams&id={$stream->id}", 'front', 'discover_rss' );
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$rssLink = $rssLink->setQueryString( 'member', \IPS\Member::loggedIn()->member_id )->setQueryString( 'key', md5( ( \IPS\Member::loggedIn()->members_pass_hash ?: \IPS\Member::loggedIn()->email ) . \IPS\Member::loggedIn()->members_pass_salt ) );
|
||||
$rssLink = $rssLink->setQueryString( 'member', \IPS\Member::loggedIn()->member_id )->setQueryString( 'key', \IPS\Member::loggedIn()->getUniqueMemberHash() );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -634,7 +658,7 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
$url = $stream ? $stream->baseUrl->setQueryString( 'className', $class ) : \IPS\Request::i()->url()->setQueryString( 'className', $class );
|
||||
$containerClass = $class::$containerNodeClass;
|
||||
$field = new \IPS\Helpers\Form\Node( 'stream_containers_' . $class::$title, isset( $currentContainers[ $class ] ) ? $currentContainers[ $class ] : array(), NULL, array( 'url' => $url, 'class' => $class::$containerNodeClass, 'multiple' => TRUE, 'permissionCheck' => $containerClass::searchableNodesPermission(), 'clubs' => ( \IPS\Settings::i()->clubs AND \IPS\IPS::classUsesTrait( $containerClass, 'IPS\Content\ClubContainer' ) ) ), NULL, NULL, NULL, 'stream_containers_' . $class::$title );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( 'stream_narrow_by_container_label', NULL, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $containerClass::$nodeTitle ) ) ) );
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( 'stream_narrow_by_container_label', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $containerClass::$nodeTitle ) ) ) );
|
||||
|
||||
return \IPS\Output::i()->json( array( 'node' => \IPS\Theme::i()->getTemplate('streams')->filterFormContentTypeContent( $field, $class, \IPS\Request::i()->key ) ) );
|
||||
}
|
||||
@@ -761,7 +785,7 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$formattedValues = $stream->formatFormValues( $values );
|
||||
|
||||
foreach ( array( 'include_comments', 'classes', 'containers', 'clubs', 'ownership', 'custom_members', 'read', 'follow', 'followed_types', 'date_type', 'date_start', 'date_end', 'date_relative_days', 'sort', 'tags' ) as $k )
|
||||
foreach ( array( 'include_comments', 'classes', 'containers', 'clubs', 'ownership', 'custom_members', 'read', 'follow', 'followed_types', 'date_type', 'date_start', 'date_end', 'date_relative_days', 'sort', 'tags', 'solved' ) as $k )
|
||||
{
|
||||
$requestKey = 'stream_' . $k;
|
||||
|
||||
@@ -802,6 +826,172 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
/* Display */
|
||||
return $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'streams', 'core' ), $stream->id ? 'filterInlineForm' : 'filterCreateForm' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function subscribe()
|
||||
{
|
||||
/* Get it */
|
||||
try
|
||||
{
|
||||
$stream = \IPS\core\Stream::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C280/C', 404, '' );
|
||||
}
|
||||
|
||||
if( !$stream->canSubscribe() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'stream_no_permission', '2C280/D', 403, '' );
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form('subscribe', 'stream_subscribe_button');
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form->add( new \IPS\Helpers\Form\Radio('stream_subscription_frequency', NULL , TRUE, ['options' => ['daily' => 'stream_daily', 'weekly' => 'stream_weekly']] ));
|
||||
|
||||
if( $values = $form->values() )
|
||||
{
|
||||
$streamSub = new \IPS\core\Stream\Subscription();
|
||||
$streamSub->member_id = \IPS\Member::loggedIn()->member_id;
|
||||
$streamSub->stream_id = $stream->id;
|
||||
$streamSub->frequency = $values['stream_subscription_frequency'];
|
||||
|
||||
/* Set the fake last sent time to get the next run populated correct */
|
||||
$streamSub->sent = $values['stream_subscription_frequency'] == 'daily' ? \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp() : \IPS\DateTime::create()->sub( new \DateInterval( 'P1W' ) )->getTimestamp();
|
||||
$streamSub->added = time();
|
||||
$streamSub->save();
|
||||
|
||||
/* Enable the task */
|
||||
$taskKey = $values['stream_subscription_frequency'] == 'daily' ? 'dailyStreamSubscriptions' : 'weeklyStreamSubscriptions';
|
||||
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 1 ), array( '`key`=?', $taskKey ) );
|
||||
|
||||
\IPS\Output::i()->redirect( $stream->url(), 'subscribed' );
|
||||
}
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Output::i()->output );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output, array( 'app' => \IPS\Dispatcher::i()->application->directory, 'module' => \IPS\Dispatcher::i()->module->key, 'controller' => \IPS\Dispatcher::i()->controller ) ), 200, 'text/html' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from a stream
|
||||
*/
|
||||
protected function unsubscribe()
|
||||
{
|
||||
/* Get it */
|
||||
try
|
||||
{
|
||||
$stream = \IPS\core\Stream::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException|\UnderflowException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C280/F', 404, '' );
|
||||
}
|
||||
\IPS\Request::i()->confirmedDelete( 'stream_unsubscribe', 'confirm_stream_unsubscribe', 'stream_unsubscribe_button');
|
||||
if ( $streamSubscription = \IPS\core\Stream\Subscription::loadByStreamAndMember( $stream ) )
|
||||
{
|
||||
$streamSubscription->delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'stream_no_permission', '2C280/E', 403, '' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $stream->url(), 'unsubscribed' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from a stream or from all streams from email
|
||||
* If we're logged in, we can send them right to the normal form.
|
||||
* Otherwise, they get a special guest page using the gkey as an authentication key.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function unSubscribeFromEmail()
|
||||
{
|
||||
/* Logged in? */
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
/* Go to the normal page */
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString('do','unsubscribe')->setQueryString('id', \IPS\Request::i()->id));
|
||||
}
|
||||
|
||||
if ( !empty( \IPS\Request::i()->gkey ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$current = \IPS\Db::i()->select( '*', 'core_stream_subscriptions', [ 'id=?', \IPS\Request::i()->id ])->first();
|
||||
}
|
||||
catch ( \UnderFlowException $e )
|
||||
{
|
||||
\IPS\Output::i()->error('node_error', '2C280/E');
|
||||
}
|
||||
|
||||
$member = \IPS\Member::load( $current['member_id'] );
|
||||
|
||||
if ( md5( $member->email . ';' . $member->ip_address . ';' . $member->joined->getTimestamp() ) != \IPS\Request::i()->gkey )
|
||||
{
|
||||
\IPS\Output::i()->error( 'stream_no_permission', '2C280/E', 403, '' );
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( '', 'update_stream_subscriptions' );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
|
||||
if ( $streams = \IPS\core\Stream\Subscription::getSubscribedStreams( $member ) AND $count = \count( $streams ) AND $count == 1 )
|
||||
{
|
||||
$title = \IPS\core\Stream\Subscription::constructFromData($current)->stream->_title;
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'streamsubscription_guest_thing', FALSE, array('sprintf' => array($title)) );
|
||||
$form->add( new \IPS\Helpers\Form\Checkbox( 'guest_unsubscribe_single', 'single', FALSE, array('disabled' => true) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['guest_unsubscribe_single'] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_subscription_unsubscribe_thing', FALSE, array('sprintf' => array($title)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$title = \IPS\Member::loggedIn()->language()->addToStack( 'stream_subscriptions');
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'streamsubscription_guest_all' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'guest_unsubscribe_choice', 'single', FALSE, array(
|
||||
'options' => array(
|
||||
'single' => \IPS\Member::loggedIn()->language()->addToStack( 'streamsubscription_guest_thing', FALSE, array('sprintf' => array( \IPS\core\Stream\Subscription::constructFromData($current)->stream->_title ) ) ),
|
||||
'all' => \IPS\Member::loggedIn()->language()->addToStack( 'streamsubscription_guest_all', FALSE, array('pluralize' => array( $count )) ),
|
||||
),
|
||||
'descriptions' => array(
|
||||
'single' => \IPS\Member::loggedIn()->language()->addToStack( 'follow_guest_unfollow_thing_desc' ),
|
||||
'all' => \IPS\Member::loggedIn()->language()->addToStack( 'follow_guest_unfollow_all_desc', FALSE, array('sprintf' => array(base64_encode( \IPS\Http\Url::internal( 'app=core&module=system&controller=followed' ) ))) )
|
||||
)
|
||||
) ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if( isset( $values['guest_unsubscribe_choice'] ) and $values['guest_unsubscribe_choice'] == 'all' )
|
||||
{
|
||||
foreach ( \IPS\core\Stream\Subscription::getSubscribedStreams( $member ) as $subscription )
|
||||
{
|
||||
$subscription->delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$subscription = \IPS\core\Stream\Subscription::loadByStreamAndMember( \IPS\core\Stream::load( $current['stream_id'] ), $member );
|
||||
$subscription->delete();
|
||||
}
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ), 'unsubscribed' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['enabled'] = FALSE;
|
||||
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'streams' )->unsubscribeStream( $title, $member, $form, !isset( \IPS\Request::i()->activity_stream_subscription ) ? FALSE : \IPS\Request::i()->activity_stream_subscription );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rebuild logged in member's streams
|
||||
@@ -814,4 +1004,4 @@ class _streams extends \IPS\Dispatcher\Controller
|
||||
\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 ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->setKeyField('id')->setValueField('title') ) ) );
|
||||
\IPS\Member::loggedIn()->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,14 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
* [Content\Controller] Class
|
||||
*/
|
||||
protected static $contentModel = 'IPS\core\Statuses\Status';
|
||||
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'profile', 'odkUpdate' => 'true']
|
||||
);
|
||||
|
||||
/**
|
||||
* Main execute entry point - used to override breadcrumb
|
||||
@@ -372,6 +380,27 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
NULL,
|
||||
\IPS\Db::LOW_PRIORITY
|
||||
);
|
||||
|
||||
/* Data Layer Stuff */
|
||||
if ( \IPS\Settings::i()->core_datalayer_enabled )
|
||||
{
|
||||
try
|
||||
{
|
||||
$groupName = \IPS\Member\Group::load( $this->member->member_group_id )->formattedName;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$groupName = null;
|
||||
}
|
||||
$properties = array(
|
||||
'profile_group' => $groupName,
|
||||
'profile_group_id' => $this->member->member_group_id ?: null,
|
||||
'profile_id' => \intval( $this->member->member_id ) ?: null,
|
||||
'profile_name' => $this->member->name ?: null,
|
||||
'view_location' => 'page',
|
||||
);
|
||||
\IPS\core\DataLayer::i()->addEvent( 'social_view', $properties );
|
||||
}
|
||||
|
||||
/* Get visitor data */
|
||||
$visitors = $this->member->profileVisitors;
|
||||
@@ -986,6 +1015,26 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
{
|
||||
$this->_saveMember( $form, $values );
|
||||
|
||||
/* Data Layer Stuff */
|
||||
if ( \IPS\Settings::i()->core_datalayer_enabled )
|
||||
{
|
||||
try
|
||||
{
|
||||
$groupName = \IPS\Member\Group::load( $this->member->member_group_id )->formattedName;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$groupName = null;
|
||||
}
|
||||
$properties = array(
|
||||
'profile_group' => $groupName,
|
||||
'profile_group_id' => $this->member->member_group_id ?: null,
|
||||
'profile_id' => \intval( $this->member->member_id ) ?: null,
|
||||
'profile_name' => $this->member->name ?: null,
|
||||
);
|
||||
\IPS\core\DataLayer::i()->addEvent( 'social_update', $properties );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $this->member->url() );
|
||||
}
|
||||
|
||||
@@ -1968,7 +2017,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
$currentClass = $types[ $currentType ];
|
||||
|
||||
/* Build Output */
|
||||
$url = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$this->member->member_id}&do=reputation&type={$currentType}", 'front', 'profile_reputation', array( $this->member->members_seo_name ) );
|
||||
$url = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$this->member->member_id}&do=solutions&type={$currentType}", 'front', 'profile_solutions', array( $this->member->members_seo_name ) );
|
||||
|
||||
$table = new \IPS\Helpers\Table\Content( $currentClass, $url, NULL, NULL, \IPS\Content\Hideable::FILTER_AUTOMATIC, 'read', FALSE );
|
||||
$table->joinContainer = TRUE;
|
||||
@@ -2006,7 +2055,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
* @return void
|
||||
*/
|
||||
protected function recognize()
|
||||
{
|
||||
{
|
||||
$class = \IPS\Request::i()->content_class;
|
||||
$id = \IPS\Request::i()->content_id;
|
||||
|
||||
@@ -2041,27 +2090,27 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
$message = NULL;
|
||||
if ( $this->member->todaysRecognizePoints() and $this->member->todaysRecognizeBadges() )
|
||||
{
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack('recognize_points_so_far_both', NULL, [
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_so_far_both', FALSE, [
|
||||
'sprintf' => [
|
||||
$this->member->name,
|
||||
\IPS\Member::loggedIn()->language()->addToStack('recognize_points_pluralize', NULL, [ 'sprintf' => [ $this->member->todaysRecognizePoints() ], 'pluralize' => [ $this->member->todaysRecognizePoints() ] ]),
|
||||
\IPS\Member::loggedIn()->language()->addToStack('recognize_badges_pluralize', NULL, [ 'sprintf' => [ $this->member->todaysRecognizeBadges() ], 'pluralize' => [ $this->member->todaysRecognizeBadges() ] ]),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_pluralize', FALSE, [ 'sprintf' => [ $this->member->todaysRecognizePoints() ], 'pluralize' => [ $this->member->todaysRecognizePoints() ] ]),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'recognize_badges_pluralize', FALSE, [ 'sprintf' => [ $this->member->todaysRecognizeBadges() ], 'pluralize' => [ $this->member->todaysRecognizeBadges() ] ]),
|
||||
] ] );
|
||||
}
|
||||
else if ( $this->member->todaysRecognizePoints() )
|
||||
{
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack('recognize_points_so_far_single', NULL, [
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_so_far_single', FALSE, [
|
||||
'sprintf' => [
|
||||
$this->member->name,
|
||||
\IPS\Member::loggedIn()->language()->addToStack('recognize_points_pluralize', NULL, [ 'sprintf' => [ $this->member->todaysRecognizePoints() ], 'pluralize' => [ $this->member->todaysRecognizePoints() ] ])
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_pluralize', FALSE, [ 'sprintf' => [ $this->member->todaysRecognizePoints() ], 'pluralize' => [ $this->member->todaysRecognizePoints() ] ])
|
||||
] ] );
|
||||
}
|
||||
else if ( $this->member->todaysRecognizeBadges() )
|
||||
{
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack('recognize_points_so_far_single', NULL, [
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_so_far_single', FALSE, [
|
||||
'sprintf' => [
|
||||
$this->member->name,
|
||||
\IPS\Member::loggedIn()->language()->addToStack('recognize_points_pluralize', NULL, [ 'sprintf' => [ $this->member->todaysRecognizeBadges() ], 'pluralize' => [ $this->member->todaysRecognizeBadges() ] ])
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_pluralize', FALSE, [ 'sprintf' => [ $this->member->todaysRecognizeBadges() ], 'pluralize' => [ $this->member->todaysRecognizeBadges() ] ])
|
||||
] ] );
|
||||
}
|
||||
|
||||
@@ -2072,11 +2121,11 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
$maxPoints = \IPS\Settings::i()->achievements_recognize_max_per_user_day - $this->member->todaysRecognizePoints();
|
||||
if ( $maxPoints > 0 )
|
||||
{
|
||||
$message .= \IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_so_far_limit', NULL, ['sprintf' => [$this->member->name, $maxPoints]] );
|
||||
$message .= \IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_so_far_limit', FALSE, ['sprintf' => [$this->member->name, $maxPoints]] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$message .= \IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_so_far_limit_none', NULL, ['sprintf' => [$this->member->name]] );
|
||||
$message .= \IPS\Member::loggedIn()->language()->addToStack( 'recognize_points_so_far_limit_none', FALSE, ['sprintf' => [$this->member->name]] );
|
||||
$disabled = TRUE;
|
||||
}
|
||||
|
||||
@@ -2112,7 +2161,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'recognize_message', NULL, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'recognize_public', TRUE, FALSE ) );
|
||||
|
||||
\IPS\Member::loggedIn()->language()->words['recognize_message_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'recognize_message__desc', NULL, [ 'sprintf' => [ $content->author()->name ] ] );
|
||||
\IPS\Member::loggedIn()->language()->words['recognize_message_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'recognize_message__desc', FALSE, [ 'sprintf' => [ $content->author()->name ] ] );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( ! $values['recognize_badge'] and ! $values['recognize_points'] )
|
||||
@@ -2134,7 +2183,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('recognize_author', NULL, [ 'sprintf' => [ $content->author()->name ] ] );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'recognize_author', FALSE, [ 'sprintf' => [ $content->author()->name ] ] );
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
|
||||
@@ -44,11 +44,7 @@ class _messenger extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->error( 'no_module_permission_guest', '2C137/1', 403, '' );
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->members_disable_pm AND \IPS\Member::loggedIn()->members_disable_pm != 2 AND \IPS\Request::i()->do != 'enableMessenger' )
|
||||
{
|
||||
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack('messenger_disabled_can_enable', FALSE, array( 'sprintf' => array( \IPS\Http\URL::internal( 'app=core&module=messaging&controller=messenger&do=enableMessenger', 'front', 'messaging' )->csrf() ) ) ), '2C137/A', 403, '' );
|
||||
}
|
||||
else if ( \IPS\Member::loggedIn()->members_disable_pm == 2 )
|
||||
if ( \IPS\Member::loggedIn()->members_disable_pm == 2 )
|
||||
{
|
||||
\IPS\Output::i()->error( 'messenger_disabled', '2C137/9', 403, '' );
|
||||
}
|
||||
@@ -79,7 +75,8 @@ class _messenger extends \IPS\Content\Controller
|
||||
protected function manage()
|
||||
{
|
||||
$baseUrl = \IPS\Http\Url::internal( "app=core&module=messaging&controller=messenger", 'front', 'messaging' );
|
||||
|
||||
$alert = NULL;
|
||||
|
||||
/* Get folders */
|
||||
$folders = array( 'myconvo' => \IPS\Member::loggedIn()->language()->addToStack('messenger_folder_inbox') );
|
||||
if ( \IPS\Member::loggedIn()->pconversation_filters )
|
||||
@@ -201,6 +198,20 @@ class _messenger extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->redirect( $message->url() );
|
||||
}
|
||||
}
|
||||
|
||||
if( $conversation->alert )
|
||||
{
|
||||
try
|
||||
{
|
||||
$alert = \IPS\core\Alerts\Alert::load( $conversation->alert );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
|
||||
if( !$alert->forMember( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
$alert = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Default folder */
|
||||
@@ -259,14 +270,21 @@ class _messenger extends \IPS\Content\Controller
|
||||
|
||||
if ( isset( \IPS\Request::i()->search ) and $searchValues = \IPS\Request::i()->valueFromArray('search') )
|
||||
{
|
||||
if ( isset( $searchValues['topic'] ) )
|
||||
if ( isset( $searchValues['topic'] ) or isset( $searchValues['post'] ) )
|
||||
{
|
||||
$query[] = \IPS\Content\Search\Mysql\Query::matchClause( "core_message_topics.mt_title", \IPS\Request::i()->q, '+', FALSE );
|
||||
}
|
||||
if ( isset( $searchValues['post'] ) )
|
||||
{
|
||||
$query[] = \IPS\Content\Search\Mysql\Query::matchClause( "core_message_posts.msg_post", \IPS\Request::i()->q, '+', FALSE );
|
||||
$fulltext = [];
|
||||
if ( isset( $searchValues['topic'] ) )
|
||||
{
|
||||
$fulltext[] = \IPS\Content\Search\Mysql\Query::matchClause( "core_message_topics.mt_title", \IPS\Request::i()->q, '+', FALSE );
|
||||
}
|
||||
if ( isset( $searchValues['post'] ) )
|
||||
{
|
||||
$fulltext[] = \IPS\Content\Search\Mysql\Query::matchClause( "core_message_posts.msg_post", \IPS\Request::i()->q, '+', FALSE );
|
||||
}
|
||||
|
||||
$query[] = "core_message_posts.msg_id IN( SELECT msg_id FROM {$prefix}core_message_posts as core_message_posts LEFT JOIN {$prefix}core_message_topics as core_message_topics ON core_message_posts.msg_topic_id=core_message_topics.mt_id WHERE (" . implode( " OR ", $fulltext ) . ") )";
|
||||
}
|
||||
|
||||
if ( isset( $searchValues['recipient'] ) )
|
||||
{
|
||||
$query[] = "core_message_posts.msg_topic_id IN ( SELECT sender_map.map_topic_id FROM {$prefix}core_message_topic_user_map AS sender_map WHERE sender_map.map_is_starter=1 AND sender_map.map_user_id IN ( SELECT member_id FROM {$prefix}core_members AS sm WHERE name LIKE '" . \IPS\Db::i()->escape_string( \IPS\Request::i()->q ) . "%' ) )";
|
||||
@@ -421,7 +439,7 @@ class _messenger extends \IPS\Content\Controller
|
||||
{
|
||||
if( \IPS\Request::i()->id )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('messaging')->conversation( $conversation, $folders );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('messaging')->conversation( $conversation, $folders, $alert );
|
||||
}
|
||||
elseif( \IPS\Request::i()->q )
|
||||
{
|
||||
@@ -453,7 +471,7 @@ class _messenger extends \IPS\Content\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('messaging')->template( $folder, $folders, $folderCounts, $conversations, $pagination, $conversation, $baseUrl, ( $conversation ? 'messenger_convo' : 'messenger' ), ( \IPS\Request::i()->sortBy ? htmlspecialchars( \IPS\Request::i()->sortBy, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE ): 'mt_last_post_time' ), ( \IPS\Request::i()->filter ? htmlspecialchars( \IPS\Request::i()->filter, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE ) : '' ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('messaging')->template( $folder, $folders, $folderCounts, $conversations, $pagination, $conversation, $baseUrl, ( $conversation ? 'messenger_convo' : 'messenger' ), ( \IPS\Request::i()->sortBy ? htmlspecialchars( \IPS\Request::i()->sortBy, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE ): 'mt_last_post_time' ), ( \IPS\Request::i()->filter ? htmlspecialchars( \IPS\Request::i()->filter, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE ) : '' ), $alert );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,6 +487,20 @@ class _messenger extends \IPS\Content\Controller
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('compose_new');
|
||||
|
||||
if( \IPS\Request::i()->alert )
|
||||
{
|
||||
try
|
||||
{
|
||||
$alert = \IPS\core\Alerts\Alert::load( \IPS\Request::i()->alert );
|
||||
|
||||
if( $alert->forMember( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('alert_modal_title', FALSE, array( 'sprintf' => array( $alert->title ) ) );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
@@ -779,7 +811,7 @@ class _messenger extends \IPS\Content\Controller
|
||||
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack('messenger_member_left', FALSE, array( 'sprintf' => array( $member->name ) ) ) );
|
||||
}
|
||||
|
||||
if ( !$conversation::memberCanReceiveNewMessage( $member, \IPS\Member::loggedIn() ) )
|
||||
if ( !$conversation::memberCanReceiveNewMessage( $member, \IPS\Member::loggedIn(), 'new' ) )
|
||||
{
|
||||
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack('meesnger_err_bad_recipient', FALSE, array( 'sprintf' => array( $member->name ) ) ) );
|
||||
}
|
||||
@@ -945,7 +977,7 @@ class _messenger extends \IPS\Content\Controller
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\Member::loggedIn()->members_disable_pm = 1;
|
||||
\IPS\Member::loggedIn()->save();
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( '' ), 'messenger_disabled' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=messaging&controller=messenger', 'front', 'messaging' ), 'messenger_disabled' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,11 @@ class _modcp extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function __call( $method, $args )
|
||||
{
|
||||
if ( \IPS\Settings::i()->core_datalayer_enabled )
|
||||
{
|
||||
\IPS\core\DataLayer::i()->addContextProperty( 'community_area', \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->addToStack('modcp'), true );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->do ) )
|
||||
{
|
||||
$activeTab = \IPS\Request::i()->tab ?: 'overview';
|
||||
|
||||
@@ -22,6 +22,14 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _online extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'online_user_list', 'odkUpdate' => 'true']
|
||||
);
|
||||
|
||||
/**
|
||||
* Show Online Users
|
||||
*
|
||||
|
||||
@@ -22,6 +22,15 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _ourpicks extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'our_picks', 'odkUpdate' => 'true']
|
||||
);
|
||||
|
||||
/**
|
||||
* List promoted internally promoted items
|
||||
*
|
||||
|
||||
@@ -589,7 +589,7 @@ class _promote extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( is_subclass_of( $class, 'IPS\Content' ) )
|
||||
{
|
||||
$promote->author_id = $object->author()->member_id;
|
||||
$promote->author_id = $object->author()->member_id ?: 0;
|
||||
}
|
||||
|
||||
$promote->save();
|
||||
@@ -597,7 +597,7 @@ class _promote extends \IPS\Dispatcher\Controller
|
||||
if ( $isNew )
|
||||
{
|
||||
/* Points */
|
||||
$promote->author()->achievementAction( 'core', 'ContentPromotion', [
|
||||
$promote->object()->author()->achievementAction( 'core', 'ContentPromotion', [
|
||||
'content' => $promote->object(),
|
||||
'promotype' => 'promote'
|
||||
] );
|
||||
|
||||
@@ -27,6 +27,17 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected $_cacheTimeout = 30 * 60;
|
||||
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
* @example array(
|
||||
'community_area' => array( 'value' => 'search', 'odkUpdate' => 'true' )
|
||||
)
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => array( 'value' => 'search', 'odkUpdate' => 'true' )
|
||||
);
|
||||
|
||||
/**
|
||||
* Check if this was a cached result we should just return a 304 against
|
||||
*
|
||||
@@ -80,7 +91,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$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' and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members', 'front' ) ) ) )
|
||||
if ( ( \IPS\Request::i()->isAjax() and ! isset( \IPS\Request::i()->_nodeSelectName ) ) 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' ) ) ) )
|
||||
{
|
||||
$showForm = ( \IPS\Request::i()->type == 'core_members' ) ? FALSE : ( !\IPS\Request::i()->isAjax() and !\IPS\Request::i()->q and !\IPS\Request::i()->tags );
|
||||
|
||||
@@ -105,6 +116,12 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Data Layer Event */
|
||||
if ( \IPS\Settings::i()->core_datalayer_enabled AND !\IPS\Request::i()->isAjax() AND \IPS\Request::i()->q )
|
||||
{
|
||||
\IPS\core\DataLayer::i()->addEvent( 'search', array( 'query' => \IPS\Request::i()->q, ) );
|
||||
}
|
||||
|
||||
return $this->_results();
|
||||
}
|
||||
@@ -153,7 +170,12 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$baseUrl = $baseUrl->setQueryString( 'eitherTermsOrTags', \IPS\Request::i()->eitherTermsOrTags );
|
||||
}
|
||||
|
||||
|
||||
if( isset( \IPS\Request::i()->quick ) )
|
||||
{
|
||||
$baseUrl = $baseUrl->setQueryString( 'quick', \IPS\Request::i()->quick );
|
||||
}
|
||||
|
||||
$types = static::contentTypes();
|
||||
|
||||
/* Flood control */
|
||||
@@ -178,7 +200,8 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
|
||||
\IPS\Request::i()->start_after = \IPS\Request::i()->joinedDate;
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->start_before ) or isset( \IPS\Request::i()->start_after ) )
|
||||
|
||||
if ( ( isset( \IPS\Request::i()->start_before ) ) or ( isset( \IPS\Request::i()->start_after ) ) )
|
||||
{
|
||||
foreach ( array( 'before', 'after' ) as $l )
|
||||
{
|
||||
@@ -428,7 +451,7 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$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 ) )
|
||||
if ( isset( \IPS\Request::i()->nodes ) and isset( $types[ \IPS\Request::i()->type ]::$containerNodeClass ) )
|
||||
{
|
||||
/* It's ok to just pass the (potential) parent IDs into the URL */
|
||||
$baseUrl = $baseUrl->setQueryString( 'nodes', \IPS\Request::i()->nodes );
|
||||
@@ -748,24 +771,27 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
/* Search tracking, only if there's a term for a non-member search and we're on the first page */
|
||||
if( \IPS\Request::i()->q AND $page == 1 )
|
||||
{
|
||||
try
|
||||
if( !\IPS\Member::loggedIn()->inGroup( json_decode( \IPS\Settings::i()->searchlog_exclude_groups ) ) )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_statistics', array(
|
||||
'type' => 'search',
|
||||
'time' => time(),
|
||||
'value_4' => mb_substr( \IPS\Request::i()->q, 0, 255 ), // Some search queries can be unnecessarily long
|
||||
'value_2' => $count,
|
||||
'extra_data' => md5( \IPS\Member::loggedIn()->email . \IPS\Member::loggedIn()->joined ) // Intentionally anonymized
|
||||
) );
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_statistics', array(
|
||||
'type' => 'search',
|
||||
'time' => time(),
|
||||
'value_4' => mb_substr( \IPS\Request::i()->q, 0, 255 ), // Some search queries can be unnecessarily long
|
||||
'value_2' => $count,
|
||||
'extra_data' => md5( \IPS\Member::loggedIn()->email . \IPS\Member::loggedIn()->joined ) // Intentionally anonymized
|
||||
) );
|
||||
}
|
||||
catch( \IPS\Db\Exception $e ) {}
|
||||
}
|
||||
catch( \IPS\Db\Exception $e ) {}
|
||||
}
|
||||
|
||||
/* Enable caching for the search results request */
|
||||
if ( !\IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$httpHeaders = array( 'Expires' => \IPS\DateTime::create()->add( new \DateInterval( 'PT3M' ) )->rfc1123(),
|
||||
'Cache-Control' => "max-age=" . $this->_cacheTimeout . ", s-maxage=" . $this->_cacheTimeout . ", public, stale-if-error, stale-while-revalidate" );
|
||||
'Cache-Control' => 'no-cache="Set-Cookie", max-age=' . $this->_cacheTimeout . ", s-maxage=" . $this->_cacheTimeout . ", public, stale-if-error, stale-while-revalidate" );
|
||||
|
||||
\IPS\Output::i()->httpHeaders += $httpHeaders;
|
||||
}
|
||||
@@ -813,6 +839,16 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$form->hiddenValues['sortdirection'] = \IPS\Request::i()->sortdirection;
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->nodes ) )
|
||||
{
|
||||
$form->hiddenValues['nodes'] = \IPS\Request::i()->nodes;
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->quick ) )
|
||||
{
|
||||
$form->hiddenValues['quick'] = \IPS\Request::i()->quick;
|
||||
}
|
||||
|
||||
/* If we do a quick search the type is set to 'all' but we want it as '' for the form to work properly */
|
||||
if( isset( \IPS\Request::i()->type ) AND \IPS\Request::i()->type === 'all' )
|
||||
|
||||
@@ -22,6 +22,14 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _directory extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'staff', 'odkUpdate' => 'true']
|
||||
);
|
||||
|
||||
/**
|
||||
* Main execute entry point - used to override breadcrumb
|
||||
*
|
||||
|
||||
@@ -656,15 +656,58 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Return current CSRF token
|
||||
*
|
||||
* @return string|null
|
||||
* @return void
|
||||
*/
|
||||
public function getCsrfKey(): ?string
|
||||
public function getCsrfKey()
|
||||
{
|
||||
if ( ! \IPS\Member::loggedIn()->member_id )
|
||||
if ( isset( \IPS\Request::i()->path ) )
|
||||
{
|
||||
\IPS\Output::i()->json( [ 'key' => \IPS\Session::i()->csrfKey ] );
|
||||
$baseUrlData = parse_url( \IPS\Http\Url::baseUrl() );
|
||||
|
||||
/* If the baseURL was site.com/forums/, JS returns pathname which is /forums/foo
|
||||
so we need to check for a path in the baseURL and make sure its removed from the
|
||||
incoming path. We want to look for 'admin', so 'forums/admin' would confuse it */
|
||||
$pathToUse = '';
|
||||
if ( isset( $baseUrlData['path'] ) and $baseUrlData['path'] )
|
||||
{
|
||||
$pathToUse .= trim( $baseUrlData['path'], '/' );
|
||||
}
|
||||
|
||||
$path = trim( \IPS\Request::i()->path, '/' );
|
||||
|
||||
if ( $pathToUse )
|
||||
{
|
||||
$path = trim( preg_replace( '#^' . $pathToUse . '#', '', $path ), '/' );
|
||||
}
|
||||
|
||||
$bits = explode( '/', $path );
|
||||
|
||||
/* This is an ACP URL, so we need the admin session */
|
||||
if ( $bits[0] == \IPS\CP_DIRECTORY )
|
||||
{
|
||||
/* Ask ajax to follow the redirect for the Admin session CSRF */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=login&do=getCsrfKey', 'admin' ) );
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
\IPS\Output::i()->json( [ 'key' => \IPS\Session::i()->csrfKey ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any events in the session cache and clear the cache
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getDataLayerEvents()
|
||||
{
|
||||
$payload = '{}';
|
||||
if ( \IPS\Settings::i()->core_datalayer_enabled AND \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$payload = \IPS\core\DataLayer::i()->jsonEvents;
|
||||
\IPS\core\DataLayer::i()->clearCache();
|
||||
}
|
||||
|
||||
/* Using this instead of \IPS\Output::i()->json because it's already JSON encoded */
|
||||
\IPS\Output::i()->sendOutput( \IPS\Member::loggedIn()->language()->stripVLETags( $payload ), 200, 'application/json', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief alerts
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
|
||||
* @since 12 May 2022
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* alerts
|
||||
*/
|
||||
class _alerts extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss alert
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function dismiss()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Update user last seen */
|
||||
try
|
||||
{
|
||||
$alert = \IPS\core\Alerts\Alert::load( \IPS\Request::i()->id );
|
||||
|
||||
if( $alert->reply == 2 and $alert->author()->member_id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'alert_cant_dismiss', '3C428/1', 403, '' );
|
||||
}
|
||||
|
||||
$alert->dismiss();
|
||||
}
|
||||
catch( \OutOfRangeException $e ) {}
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( base64_decode( \IPS\Request::i()->ref ) );
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,7 @@ class _announcement extends \IPS\Content\Controller
|
||||
/* Get groups that cannot view the item */
|
||||
$groups = $item->cannotViewGroups();
|
||||
|
||||
if( !\count( $groups ) )
|
||||
if( !$groups )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'status' => 'all_permissions' ) );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Easy mode controller
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 15 Oct 2021
|
||||
*/
|
||||
|
||||
namespace IPS\core\modules\front\system;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect
|
||||
*/
|
||||
class _easymode extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* Proxy remote CSS URLs to allow for JS to select classes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function proxy()
|
||||
{
|
||||
if ( \IPS\Theme::isUsingEasyModeEditor() )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->f ) )
|
||||
{
|
||||
$url = base64_decode( \IPS\Request::i()->f );
|
||||
$storage = \IPS\File::getClass( 'core_Theme' );
|
||||
$storageUrl = parse_url( $storage->baseUrl() );
|
||||
$test = parse_url( $url );
|
||||
|
||||
/* Does this URL match the host of the storage URL? */
|
||||
if ( preg_match( "/\.css(\.gz)?(\?|$)/", $url ) and isset( $test['host'] ) and $test['host'] == $storageUrl['host'] )
|
||||
{
|
||||
$encoded = ( preg_match( "/\.css\.gz?(\?|$)/", $url ) );
|
||||
|
||||
try
|
||||
{
|
||||
$css = \IPS\Http\Url::external( $url )->setScheme('https')->request()->get();
|
||||
|
||||
if ( $encoded )
|
||||
{
|
||||
$css = gzdecode( $css );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( $css, 200, 'text/css' );
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* still here? */
|
||||
\IPS\Output::i()->sendOutput( '/* Could not read ' . $url . '*/', 200, 'text/css' );
|
||||
}
|
||||
}
|
||||
@@ -344,7 +344,7 @@ class _editor extends \IPS\Dispatcher\Controller
|
||||
$results = '';
|
||||
if ( mb_strlen( \IPS\Request::i()->input ) > 0 )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_members', array( \IPS\Db::i()->like( 'name', \IPS\Request::i()->input ) ), 'name', 10 ) as $row )
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_members', array( \IPS\Db::i()->like( 'name', \IPS\Request::i()->input ), array( 'temp_ban !=?', '-1' ) ), 'name', 10 ) as $row )
|
||||
{
|
||||
$results .= \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->mentionRow( \IPS\Member::constructFromData( $row ) );
|
||||
}
|
||||
@@ -440,4 +440,48 @@ class _editor extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->json( $results );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stored replies
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function storedReplies()
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->id ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$reply = \IPS\core\StoredReplies::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
|
||||
\IPS\Output::i()->json( [
|
||||
'id' => $reply->id,
|
||||
'title' => $reply->title,
|
||||
'reply' => $reply->text
|
||||
] );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->json( [ 'error' => \IPS\Theme::i()->getTemplate( 'system', 'core' )->noResults() ] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$results = [];
|
||||
foreach ( \IPS\core\StoredReplies::roots() as $reply )
|
||||
{
|
||||
if ( $reply->enabled )
|
||||
{
|
||||
$results[] = ['id' => $reply->id, 'title' => $reply->title];
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $results ) )
|
||||
{
|
||||
\IPS\Output::i()->json( [ 'error' => \IPS\Theme::i()->getTemplate( 'system', 'core' )->noResults() ] );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->json( $results );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,6 +136,10 @@ class _lostpass extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/* If we have an existing validation record, we can just reuse it */
|
||||
$sendEmail = TRUE;
|
||||
|
||||
/* Delete any lost pass validating records that are older than 45 minutes - These records are only valid for one hour. */
|
||||
\IPS\Db::i()->delete( 'core_validating', [ 'member_id=? AND lost_pass=1 AND entry_date<?', $member->member_id, time() - 2700 ] );
|
||||
|
||||
try
|
||||
{
|
||||
$existing = \IPS\Db::i()->select( array( 'vid', 'email_sent' ), 'core_validating', array( 'member_id=? AND lost_pass=1', $member->member_id ) )->first();
|
||||
@@ -200,6 +204,12 @@ class _lostpass extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_validation_key', '2S151/1', 410, '' );
|
||||
}
|
||||
|
||||
/* Show a nicer error message if their link has expired */
|
||||
if( $record['entry_date'] < \IPS\DateTime::create()->sub( new \DateInterval( 'PT1H' ) )->getTimestamp() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'lost_pass_expired', '2S151/4', 410, '' );
|
||||
}
|
||||
|
||||
/* Show form for new password */
|
||||
$form = new \IPS\Helpers\Form( "resetpass", 'save' );
|
||||
|
||||
@@ -177,7 +177,7 @@ class _metatags extends \IPS\Dispatcher\Controller
|
||||
$manifest = json_decode( \IPS\Settings::i()->manifest_details, TRUE );
|
||||
|
||||
$output = array(
|
||||
'scope' => '/',
|
||||
'scope' => rtrim( \IPS\Settings::i()->base_url, '/' ) . '/',
|
||||
'name' => \IPS\Settings::i()->board_name,
|
||||
'theme_color' => \IPS\Theme::i()->settings['header']
|
||||
);
|
||||
@@ -191,6 +191,7 @@ class _metatags extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$homeScreen = json_decode( \IPS\Settings::i()->icons_homescreen, TRUE ) ?? array();
|
||||
$homeScreenMaskable = json_decode( \IPS\Settings::i()->icons_homescreen_maskable, TRUE ) ?? array();
|
||||
|
||||
foreach( $homeScreen as $k => $v )
|
||||
{
|
||||
@@ -206,35 +207,30 @@ class _metatags extends \IPS\Dispatcher\Controller
|
||||
$output['icons'][] = array(
|
||||
'src' => (string) $file->url,
|
||||
'type' => \IPS\File::getMimeType( $file->originalFilename ),
|
||||
'sizes' => $v['width'] . 'x' . $v['height']
|
||||
);
|
||||
'sizes' => $v['width'] . 'x' . $v['height'],
|
||||
'purpose' => 'any'
|
||||
);;
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Settings::i()->mobile_app_prompt )
|
||||
|
||||
foreach( $homeScreenMaskable as $k => $v )
|
||||
{
|
||||
if ( !isset( $output['short_name'] ) )
|
||||
if( mb_strpos( $k, 'android' ) !== FALSE )
|
||||
{
|
||||
$output['short_name'] = \IPS\Settings::i()->board_name;
|
||||
if( !isset( $output['icons'] ) )
|
||||
{
|
||||
$output['icons'] = array();
|
||||
}
|
||||
|
||||
$file = \IPS\File::get( 'core_Icons', $v['url'] );
|
||||
|
||||
$output['icons'][] = array(
|
||||
'src' => (string) $file->url,
|
||||
'type' => \IPS\File::getMimeType( $file->originalFilename ),
|
||||
'sizes' => $v['width'] . 'x' . $v['height'],
|
||||
'purpose' => 'maskable'
|
||||
);;
|
||||
}
|
||||
if ( !isset( $output['display'] ) )
|
||||
{
|
||||
$output['display'] = 'standalone';
|
||||
}
|
||||
|
||||
$output['prefer_related_applications'] = TRUE;
|
||||
$output['related_applications'] = array(
|
||||
array(
|
||||
'platform' => 'play',
|
||||
'id' => \IPS\Settings::i()->mobile_app_play_id ?: \IPS\APP_MULTICOMMUNITY_PLAY_ID,
|
||||
'url' => \IPS\Settings::i()->mobile_app_play_url ?: \IPS\APP_MULTICOMMUNITY_PLAY_URL,
|
||||
),
|
||||
array(
|
||||
'platform' => 'itunes',
|
||||
'id' => \IPS\Settings::i()->mobile_app_itunes_id ?: \IPS\APP_MULTICOMMUNITY_ITUNES_ID, // Note: this is also defined in includeMeta because iOS handles this different.
|
||||
'url' => \IPS\Settings::i()->mobile_app_itunes_url ?: \IPS\APP_MULTICOMMUNITY_ITUNES_URL,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Data\Store::i()->manifest = $output;
|
||||
|
||||
@@ -519,8 +519,8 @@ class _notifications extends \IPS\Dispatcher\Controller
|
||||
$form->hiddenValues[ $k ] = $v;
|
||||
if ( empty( $notificationConfiguration ) )
|
||||
{
|
||||
$type = $type == 'follower_content' ? 'core_Content' : $type;
|
||||
$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack( 'follow_type_no_config' ) . ' <a href="' . \IPS\Http\Url::internal( 'app=core&module=system&controller=notifications&do=options&type=' . $type, 'front', 'notifications_options' ) . '">' . \IPS\Member::loggedIn()->language()->addToStack( 'notification_options', FALSE ) . '</a>', 'ipsPadding:none', FALSE );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -601,15 +601,18 @@ class _notifications extends \IPS\Dispatcher\Controller
|
||||
/* Send notification if following member */
|
||||
if( $class == "IPS\Member" )
|
||||
{
|
||||
/* Give points */
|
||||
$receiver = \IPS\Member::load( \IPS\Request::i()->follow_rel_id );
|
||||
$receiver->achievementAction( 'core', 'FollowMember', [
|
||||
'giver' => \IPS\Member::loggedIn()
|
||||
] );
|
||||
if( $values['follow_public'] )
|
||||
{
|
||||
/* Give points */
|
||||
$receiver = \IPS\Member::load( \IPS\Request::i()->follow_id );
|
||||
$receiver->achievementAction( 'core', 'FollowMember', [
|
||||
'giver' => \IPS\Member::loggedIn()
|
||||
] );
|
||||
|
||||
$notification = new \IPS\Notification( \IPS\Application::load( 'core' ), 'member_follow', \IPS\Member::loggedIn(), array( \IPS\Member::loggedIn() ) );
|
||||
$notification->recipients->attach( $thing );
|
||||
$notification->send();
|
||||
$notification = new \IPS\Notification( \IPS\Application::load( 'core' ), 'member_follow', \IPS\Member::loggedIn(), array( \IPS\Member::loggedIn() ) );
|
||||
$notification->recipients->attach( $thing );
|
||||
$notification->send();
|
||||
}
|
||||
}
|
||||
else if ( \in_array( 'IPS\Node\Model', class_parents( $class ) ) )
|
||||
{
|
||||
@@ -1061,8 +1064,9 @@ class _notifications extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_follow', array( 'follow_app=? AND follow_area=? AND follow_rel_id=?', \IPS\Request::i()->follow_app, \IPS\Request::i()->follow_area, \IPS\Request::i()->follow_id ) );
|
||||
|
||||
if( \IPS\Request::i()->follow_area == 'club' )
|
||||
\IPS\Db::i()->delete( 'core_follow_count_cache', array( 'id=? AND class=?', \IPS\Request::i()->follow_id, 'IPS\\' . \IPS\Request::i()->follow_app . '\\' . mb_ucfirst( \IPS\Request::i()->follow_area ) ) );
|
||||
|
||||
if( \IPS\Request::i()->follow_area == 'club' )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -34,11 +34,12 @@ class _redirect extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
/* First check the key to make sure this actually came from HTMLPurifier */
|
||||
if ( \IPS\Login::compareHashes( hash_hmac( "sha256", \IPS\Request::i()->url, \IPS\Settings::i()->site_secret_key ), (string) \IPS\Request::i()->key ) OR \IPS\Login::compareHashes( hash_hmac( "sha256", \IPS\Request::i()->url, \IPS\Settings::i()->site_secret_key . 'r' ), (string) \IPS\Request::i()->key ) )
|
||||
/* The URL may have had a line-break added in the outbound email if it's a long URL, we need to fix that. Then check the key matches. */
|
||||
$url = str_replace( [ '%20','%0D' ], '', (string) \IPS\Http\Url::createFromString( \IPS\Request::i()->url ) );
|
||||
if ( \IPS\Login::compareHashes( hash_hmac( "sha256", $url, \IPS\Settings::i()->site_secret_key ), (string) \IPS\Request::i()->key ) OR \IPS\Login::compareHashes( hash_hmac( "sha256", $url, \IPS\Settings::i()->site_secret_key . 'r' ), (string) \IPS\Request::i()->key ) )
|
||||
{
|
||||
/* Construct the URL */
|
||||
$url = \IPS\Http\Url::external( \IPS\Request::i()->url );
|
||||
$url = \IPS\Http\Url::external( $url );
|
||||
|
||||
/* If this is coming from email tracking, log the click */
|
||||
if( isset( \IPS\Request::i()->email ) AND \IPS\Settings::i()->prune_log_emailstats != 0 )
|
||||
|
||||
@@ -42,7 +42,8 @@ class _register extends \IPS\Dispatcher\Controller
|
||||
if( \IPS\Request::i()->do !== 'complete' and \IPS\Request::i()->do !== 'setPassword'
|
||||
and \IPS\Request::i()->do !== 'changeEmail' and \IPS\Request::i()->do !== 'validate'
|
||||
and \IPS\Request::i()->do !== 'validating' and \IPS\Request::i()->do !== 'reconfirm'
|
||||
and \IPS\Request::i()->do !== 'finish' and \IPS\Request::i()->do !== 'cancel' )
|
||||
and \IPS\Request::i()->do !== 'finish' and \IPS\Request::i()->do !== 'cancel'
|
||||
and \IPS\Request::i()->do !== 'resend' )
|
||||
{
|
||||
if ( \IPS\Login::registrationType() == 'redirect' )
|
||||
{
|
||||
@@ -60,6 +61,7 @@ class _register extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimalNoHome';
|
||||
}
|
||||
\IPS\Output::i()->sidebar['enabled'] = FALSE;
|
||||
\IPS\Output::i()->pageCaching = FALSE;
|
||||
\IPS\Output::i()->linkTags['canonical'] = (string) \IPS\Http\Url::internal( 'app=core&module=system&controller=register', 'front', 'register' );
|
||||
}
|
||||
|
||||
@@ -1057,9 +1059,11 @@ class _register extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function cancel()
|
||||
{
|
||||
/* This bit is kind of important */
|
||||
/* This bit is kind of important - don't allow externally created accounts to be deleted, they could already have commerce data */
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
if ( \IPS\Member::loggedIn()->name and \IPS\Member::loggedIn()->email and !\IPS\Db::i()->select( 'COUNT(*)', 'core_validating', array( 'member_id=? AND new_reg=1', \IPS\Member::loggedIn()->member_id ) )->first() )
|
||||
if ( (\IPS\Member::loggedIn()->name and \IPS\Member::loggedIn()->email
|
||||
and !\IPS\Db::i()->select( 'COUNT(*)', 'core_validating', array( 'member_id=? AND new_reg=1', \IPS\Member::loggedIn()->member_id ) )->first() )
|
||||
OR \IPS\Member::loggedIn()->members_bitoptions['created_externally'] )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2C223/1', 403, '' );
|
||||
}
|
||||
@@ -1279,7 +1283,7 @@ class _register extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->error( 'node_error', '2C223/G', 403, '' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'set_password_title', NULL, array( 'sprintf' => array( $member->name ) ) );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'set_password_title', FALSE, array( 'sprintf' => array( $member->name ) ) );
|
||||
if ( $mfa = \IPS\MFA\MFAHandler::accessToArea( 'core', 'AuthenticateFront', \IPS\Request::i()->url(), $member ) )
|
||||
{
|
||||
\IPS\Output::i()->output = $mfa;
|
||||
|
||||
@@ -51,8 +51,6 @@ class _serviceworker extends \IPS\Dispatcher\Controller
|
||||
|
||||
/* VARIABLES TO PASS THROUGH TO JS */
|
||||
$DEBUG = ( ( \IPS\IN_DEV and \IPS\DEV_DEBUG_JS ) or \IPS\DEBUG_JS ) ? 'true' : 'false'; // Weird casting is intentional.
|
||||
$SW_CACHE_BUST = \IPS\SW_CACHE_BUST ? 'true' : 'false'; // Weird casting is intentional.
|
||||
$HTTP_CACHE_DURATION = \IPS\CACHE_PAGE_TIMEOUT;
|
||||
$BASE_URL = \IPS\Settings::i()->base_url;
|
||||
$CACHED_ASSETS = json_encode( $cachedUrls, JSON_UNESCAPED_SLASHES );
|
||||
$OFFLINE_URL = (string) \IPS\Http\Url::internal("app=core&module=system&controller=offline", "front", "user_offline");
|
||||
@@ -64,12 +62,9 @@ class _serviceworker extends \IPS\Dispatcher\Controller
|
||||
$output = <<<JAVASCRIPT
|
||||
"use strict";
|
||||
const DEBUG = {$DEBUG};
|
||||
const SW_CACHE_BUST = {$SW_CACHE_BUST};
|
||||
const BASE_URL = "{$BASE_URL}";
|
||||
const CACHED_ASSETS = {$CACHED_ASSETS};
|
||||
const CACHE_NAME = 'invision-community-{$CACHE_VERSION}';
|
||||
const HTTP_CACHE_DURATION = {$HTTP_CACHE_DURATION};
|
||||
const HTTP_CACHE_BUFFER = 60;
|
||||
const OFFLINE_URL = "{$OFFLINE_URL}";
|
||||
const NOTIFICATION_ICON = {$NOTIFICATION_ICON};
|
||||
const DEFAULT_NOTIFICATION_TITLE = "{$DEFAULT_NOTIFICATION_TITLE}";
|
||||
|
||||
@@ -22,6 +22,13 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _settings extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
*
|
||||
*/
|
||||
public static $dataLayerContext = array(
|
||||
'community_area' => [ 'value' => 'settings', 'odkUpdate' => true]
|
||||
);
|
||||
|
||||
/**
|
||||
* Execute
|
||||
@@ -384,7 +391,10 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->class = 'ipsForm_collapseTablet';
|
||||
$form->add( new \IPS\Helpers\Form\Password( 'current_password', '', TRUE, array( 'protect' => TRUE, 'validateFor' => \IPS\Member::loggedIn(), 'bypassProfanity' => \IPS\Helpers\Form\Text::BYPASS_PROFANITY_ALL, 'htmlAutocomplete' => "current-password" ) ) );
|
||||
if ( !\IPS\Member::loggedIn()->members_bitoptions['password_reset_forced'] )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Password( 'current_password', '', TRUE, array( 'protect' => TRUE, 'validateFor' => \IPS\Member::loggedIn(), 'bypassProfanity' => \IPS\Helpers\Form\Text::BYPASS_PROFANITY_ALL, 'htmlAutocomplete' => "current-password" ) ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Password( 'new_password', '', TRUE, array( 'protect' => TRUE, 'showMeter' => \IPS\Settings::i()->password_strength_meter, 'checkStrength' => TRUE, 'strengthMember' => \IPS\Member::loggedIn(), 'bypassProfanity' => \IPS\Helpers\Form\Text::BYPASS_PROFANITY_ALL, 'htmlAutocomplete' => "new-password" ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Password( 'confirm_new_password', '', TRUE, array( 'protect' => TRUE, 'confirm' => 'new_password', 'bypassProfanity' => \IPS\Helpers\Form\Text::BYPASS_PROFANITY_ALL, 'htmlAutocomplete' => "new-password" ) ) );
|
||||
|
||||
@@ -597,6 +607,8 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function _mfa()
|
||||
{
|
||||
\IPS\Output::i()->bypassCsrfKeyCheck = true;
|
||||
|
||||
/* Validate password */
|
||||
if ( !isset( $_SESSION['passwordValidatedForMfa'] ) )
|
||||
{
|
||||
@@ -646,11 +658,11 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
return $output . $mfaOutput;
|
||||
}
|
||||
|
||||
/* Do any enabling/diabling */
|
||||
/* Do any enabling/disabling */
|
||||
if ( isset( \IPS\Request::i()->act ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
|
||||
/* Get the handler */
|
||||
$key = \IPS\Request::i()->type;
|
||||
if ( !isset( $handlers[ $key ] ) or \IPS\MFA\MFAHandler::accessToArea( 'core', 'SecurityQuestions', \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front', 'settings_mfa' ) ) )
|
||||
@@ -671,11 +683,11 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
|
||||
\IPS\Member::loggedIn()->members_bitoptions['security_questions_opt_out'] = FALSE;
|
||||
\IPS\Member::loggedIn()->save();
|
||||
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa', 'front', 'settings_mfa' ) );
|
||||
}
|
||||
|
||||
/* Show the configruation modal */
|
||||
|
||||
/* Show the configuration modal */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('settings');
|
||||
return $output . \IPS\Theme::i()->getTemplate( 'system' )->settingsMfaSetup( $handlers[ $key ]->configurationScreen( \IPS\Member::loggedIn(), FALSE, \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa&act=enable&type=' . $key, 'front', 'settings_mfa' ) ), \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&area=mfa&act=enable&type=' . $key, 'front', 'settings_mfa' ) );
|
||||
}
|
||||
@@ -1708,7 +1720,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
|
||||
$this->_performRedirect( \IPS\Http\Url::internal( "app=core&module=system&controller=settings", 'front', 'settings' ), 'block_newsletter_subscribed' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Toggle Anonymously Online
|
||||
*
|
||||
@@ -1717,26 +1729,57 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
protected function updateAnon()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
|
||||
/* Check this value can be toggled */
|
||||
if( \IPS\Member::loggedIn()->group['g_hide_online_list'] >= 1 )
|
||||
{
|
||||
\IPS\Output::i()->error( 'online_status_cannot_change', '2C122/X', 403, '' );
|
||||
}
|
||||
|
||||
/* Update the bitwise flag */
|
||||
\IPS\Member::loggedIn()->members_bitoptions['is_anon'] = (bool) \IPS\Request::i()->value;
|
||||
\IPS\Member::loggedIn()->save();
|
||||
|
||||
|
||||
/* Update users devices */
|
||||
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_members_known_devices', array( "member_id=?", \IPS\Member::loggedIn()->member_id ) ), 'IPS\Member\Device' ) AS $device )
|
||||
{
|
||||
$device->anonymous = ( (bool) \IPS\Request::i()->value ) ? 1 : 0;
|
||||
$device->save();
|
||||
}
|
||||
|
||||
|
||||
/* Update the session */
|
||||
\IPS\Session::i()->setType( ( (bool) \IPS\Request::i()->value ) ? \IPS\Session\Front::LOGIN_TYPE_ANONYMOUS : \IPS\Session\Front::LOGIN_TYPE_MEMBER );
|
||||
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( 'OK' );
|
||||
}
|
||||
|
||||
|
||||
$this->_performRedirect( \IPS\Http\Url::internal( "app=core&module=system&controller=settings&area=mfa", 'front', 'settings_mfa' ), 'saved' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle Whether PII is included in the data layer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function togglePii()
|
||||
{
|
||||
if ( ! \IPS\Settings::i()->core_datalayer_member_pii_choice )
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_not_found', '3T251/7', 404 );
|
||||
}
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Update the bitwise flag */
|
||||
\IPS\Member::loggedIn()->datalayer_collect_pii = (bool) ! \IPS\Member::loggedIn()->datalayer_collect_pii;
|
||||
\IPS\Member::loggedIn()->save();
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( 'OK' );
|
||||
}
|
||||
|
||||
$this->_performRedirect( \IPS\Http\Url::internal( "app=core&module=system&controller=settings&area=mfa", 'front', 'settings_mfa' ), 'saved' );
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ class _vse extends \IPS\Dispatcher\Controller
|
||||
$rgb[] = hexdec( \substr( $colorValue, 4, 2 ) );
|
||||
}
|
||||
|
||||
$colorValues[ $key ] = implode( $rgb, ', ');
|
||||
$colorValues[ $key ] = implode( ', ', $rgb );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ class _widgets extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->json( 'OK' );
|
||||
}
|
||||
|
||||
\IPS\Member::loggedIn()->language()->words['widget_adv__custom_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'widget_adv__custom__desc', NULL, array( 'sprintf' => array( \IPS\Request::i()->block ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['widget_adv__custom_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'widget_adv__custom__desc', FALSE, array( 'sprintf' => array( \IPS\Request::i()->block ) ) );
|
||||
\IPS\Output::i()->output = $configurationForm->customTemplate( array( \IPS\Theme::i()->getTemplate( 'widgets', 'core' ), 'formTemplate' ), $widget );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user