Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

@@ -11,7 +11,7 @@
namespace IPS\core\modules\front\members;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -48,7 +48,14 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
if( !\IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_profile.js', 'core' ) );
/* Don't index new empty profiles */
if( ! $this->member->member_posts )
{
\IPS\Output::i()->metaTags['robots'] = 'noindex, follow';
}
\IPS\Output::i()->linkTags['canonical'] = (string)$this->member->url();
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_statuses.js', 'core' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_core.js', 'core', 'global' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/profiles.css' ) );
@@ -60,6 +67,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/profiles_responsive.css' ) );
}
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_profile.js', 'core' ) );
/* Go */
parent::execute();
@@ -99,6 +107,8 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
*/
protected function manage()
{
\IPS\Output::i()->linkTags['canonical'] = (string) $this->member->url();
/* Can we access this member's statuses */
$canAccessSingleStatuses = ( \IPS\Settings::i()->profile_comments and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'status' ) ) );
$canAccessStatuses = $canAccessSingleStatuses and ( $this->member->pp_setting_count_comments or \IPS\Member::loggedIn()->member_id == $this->member->member_id );
@@ -134,24 +144,33 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$sidebarFields = array();
if( !empty( $profileFieldValues ) )
{
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( 'pfd.*', array('core_pfields_data', 'pfd'), array('pfd.pf_admin_only=0'), 'pfg.pf_group_order, pfd.pf_position' )->join(
if( \IPS\Member::loggedIn()->isAdmin() OR \IPS\Member::loggedIn()->modPermissions() )
{
$where = array( "pfd.pf_member_hide='owner' OR pfd.pf_member_hide='staff' OR pfd.pf_member_hide='all'" );
}
elseif( \IPS\Member::loggedIn()->member_id == $this->member->member_id )
{
$where = array( "pfd.pf_member_hide='owner' OR pfd.pf_member_hide='all'" );
}
else
{
$where = array( "pfd.pf_member_hide='all'" );
}
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( 'pfd.*', array('core_pfields_data', 'pfd'), $where, 'pfg.pf_group_order, pfd.pf_position' )->join(
array('core_pfields_groups', 'pfg'),
"pfd.pf_group_id=pfg.pf_group_id"
), 'IPS\core\ProfileFields\Field' ) as $field )
{
if( $profileFieldValues[ 'field_' . $field->id ] !== '' AND $profileFieldValues[ 'field_' . $field->id ] !== NULL )
{
/** check if the field isn't hidden and if it is hidden, show it only to admins and to the user */
if( !$field->member_hide or ( \IPS\Member::loggedIn()->isAdmin() OR \IPS\Member::loggedIn()->member_id === $this->member->member_id ) )
if( $field->type == 'Editor' )
{
if( $field->type == 'Editor' )
{
$mainFields['core_pfieldgroups_' . $field->group_id]['core_pfield_' . $field->id] = $field->displayValue( $profileFieldValues['field_' . $field->id] );
}
else
{
$sidebarFields['core_pfieldgroups_' . $field->group_id]['core_pfield_' . $field->id] = $field->displayValue( $profileFieldValues['field_' . $field->id] );
}
$mainFields['core_pfieldgroups_' . $field->group_id]['core_pfield_' . $field->id] = $field->displayValue( $profileFieldValues['field_' . $field->id], FALSE, \IPS\core\ProfileFields\Field::PROFILE, $this->member );
}
else
{
$sidebarFields['core_pfieldgroups_' . $field->group_id]['core_pfield_' . $field->id] = array( 'value' => $field->displayValue( $profileFieldValues['field_' . $field->id], FALSE, \IPS\core\ProfileFields\Field::PROFILE, $this->member ), 'custom' => $field->profile_format ? TRUE : FALSE );
}
}
}
@@ -170,16 +189,19 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
$mainContent = \IPS\Theme::i()->getTemplate( 'profile' )->singleStatus( $this->member, $status );
\IPS\Output::i()->linkTags['canonical'] = (string) $status->url();
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'viewing_single_status_of', FALSE, array('sprintf' => array( \IPS\DateTime::ts( $status->mapped('date') )->localeDate() , $status->author()->name ) ) );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->get( 'viewing_single_status' ) );
/* Remove the robots tag we set earlier, the page can be indexed if a status exists, but the member doesn't have any posts */
unset( \IPS\Output::i()->metaTags['robots'] );
}
else
{
/* What tabs are available? */
$tabs = array( 'activity' => 'users_activity_feed' );
if ( \IPS\Settings::i()->clubs and count( \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), NULL, 'created', $this->member ) ) )
if ( \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'clubs', 'front' ) ) and \IPS\Settings::i()->clubs and \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), NULL, 'created', $this->member, array(), NULL, TRUE ) )
{
$tabs['clubs'] = 'users_clubs';
}
@@ -224,7 +246,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$latestActivity->init( TRUE );
$extra = array();
foreach ( array( 'register', 'follow_member', 'follow_content', 'photo', 'like', 'rep_neg' ) as $k )
foreach ( array( 'register', 'follow_member', 'follow_content', 'photo', 'votes', 'like', 'rep_neg' ) as $k )
{
$key = "all_activity_{$k}";
if ( \IPS\Settings::i()->$key )
@@ -269,7 +291,13 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
if ( \IPS\core\Statuses\Status::moderateNewItems( \IPS\Member::loggedIn() ) )
{
$statusForm = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $statusForm;
$statusForm = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->postingInformation( NULL, TRUE, FALSE ) . $statusForm;
}
if( isset( \IPS\Output::i()->httpHeaders['X-IPS-FormError'] ) AND \IPS\Output::i()->httpHeaders['X-IPS-FormError'] AND \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->sendOutput( $statusForm, 500 );
return;
}
}
@@ -277,17 +305,18 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
elseif ( $tab == 'clubs' )
{
if ( !\IPS\Settings::i()->clubs )
{
\IPS\Output::i()->error( 'no_module_permission', '2C138/J', 403, '' );
}
/* Get All User Clubs */
$baseUrl = \IPS\Request::i()->url()->setQueryString('tab', 'clubs');
$perPage = 24;
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
$allClubs = \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), array( ( $page - 1 ) * $perPage, $perPage ), 'last_activity', $this->member );
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $baseUrl, ( ceil( is_object( $allClubs ) ? $allClubs->count( TRUE ) : 0 ) / $perPage ), $page, $perPage );
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
$clubsCount = \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), array( ( $page - 1 ) * $perPage, $perPage ), 'last_activity', $this->member, array(), NULL, TRUE );
$allClubs = \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), array( ( $page - 1 ) * $perPage, $perPage ), 'last_activity', $this->member );
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $baseUrl, ( ceil( $clubsCount / $perPage ) ), $page, $perPage );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/clubs.css', 'core', 'front' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
@@ -348,7 +377,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$visitors = $this->member->profileVisitors;
/* Get followers */
$followers = $this->member->followers( ( \IPS\Member::loggedIn()->isAdmin() OR \IPS\Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Member::FOLLOW_PUBLIC + \IPS\Member::FOLLOW_ANONYMOUS : \IPS\Member::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly' ), NULL, array( 0, 12 ) );
$followers = $this->member->followers( ( \IPS\Member::loggedIn()->isAdmin() OR \IPS\Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Member::FOLLOW_PUBLIC + \IPS\Member::FOLLOW_ANONYMOUS : \IPS\Member::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly', 'none' ), NULL, array( 0, 12 ) );
/* Update online location */
$module = \IPS\Application\Module::get( 'core', 'members', 'front' )->permissions();
@@ -394,8 +423,6 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
),
);
\IPS\Output::i()->linkTags['canonical'] = (string) $this->member->url();
/* Output */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_profile.js', 'core' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile' )->profile( $this->member, $mainContent, $visitors, $sidebarFields, $followers, $addWarningUrl );
@@ -439,13 +466,13 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) ) ] = $class;
}
$supportsComments = ( in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::supportsComments( \IPS\Member::loggedIn() ) );
$supportsComments = ( \in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::supportsComments( \IPS\Member::loggedIn() ) );
if ( $supportsComments )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$commentClass, 4 ) ) ) ] = $class::$commentClass;
}
$supportsReviews = ( in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::supportsReviews( \IPS\Member::loggedIn() ) );
$supportsReviews = ( \in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::supportsReviews( \IPS\Member::loggedIn() ) );
if ( $supportsReviews )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class::$reviewClass, 4 ) ) ) ] = $class::$reviewClass;
@@ -484,17 +511,18 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
}
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
$baseUrl = NULL;
if( $page < 1 )
{
$page = 1;
}
/* Build Output */
if ( !$currentType )
{
$query = \IPS\Content\Search\Query::init()->filterByAuthor( $this->member )->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_UPDATED )->setPage( $page );
$query = \IPS\Content\Search\Query::init()->filterByAuthor( $this->member )->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_CREATED )->setPage( $page );
$results = $query->search();
/* If we requested a higher page than is allowed, redirect back to last page */
@@ -506,11 +534,12 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
if ( $highestPage > 0 OR ( $highestPage == 0 AND $page > 1 ) )
{
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->setQueryString( 'page', $highestPage ?: 1 ), NULL, 303 );
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->setPage( 'page', $highestPage ?: 1 ), NULL, 303 );
}
}
$pagination = trim( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $this->member->url()->setQueryString( array( 'do' => 'content', 'all_activity' => 1 ) ), ceil( $results->count( TRUE ) / $query->resultsToGet ), $page, $query->resultsToGet ) );
$baseUrl = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$this->member->member_id}&do=content", 'front', 'profile_content', $this->member->members_seo_name );
$pagination = trim( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $baseUrl->setQueryString( array( 'all_activity' => 1 ) ), ceil( $results->count( TRUE ) / $query->resultsToGet ), $page, $query->resultsToGet ) );
if ( \IPS\Request::i()->isAjax() AND \IPS\Request::i()->all_activity )
{
\IPS\Output::i()->json( array( 'rows' => \IPS\Theme::i()->getTemplate('profile')->userContentStream( $this->member, $results, $pagination ) ) );
@@ -548,8 +577,9 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
{
$where[] = $currentClass::commentWhere();
}
$output = new \IPS\Helpers\Table\Content( $currentClass, \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$this->member->member_id}&do=content", 'front', 'profile_content', $this->member->members_seo_name )->setQueryString( array( 'type' => $currentType ) ), $where, NULL, NULL, 'read', FALSE );
$baseUrl = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$this->member->member_id}&do=content", 'front', 'profile_content', $this->member->members_seo_name );
$output = new \IPS\Helpers\Table\Content( $currentClass, $baseUrl->setQueryString( array( 'type' => $currentType ) ), $where, NULL, NULL, 'read', FALSE );
}
if ( $currentType == 'core_statuses_status' )
@@ -570,6 +600,21 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
/* Display */
$profileTitle = \IPS\Member::loggedIn()->language()->addToStack( 'members_content', FALSE, array( 'sprintf' => array( $this->member->name ) ) );
$title = ( isset( \IPS\Request::i()->page ) and \IPS\Request::i()->page > 1 ) ? \IPS\Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( $profileTitle, \IPS\Request::i()->page ) ) ) : $profileTitle;
if ( $baseUrl )
{
if ( isset( \IPS\Request::i()->type ) )
{
$baseUrl = $baseUrl->setQueryString( 'type', \IPS\Request::i()->type );
}
if ( isset( \IPS\Request::i()->page ) and \IPS\Request::i()->page > 1 )
{
$baseUrl = $baseUrl->setPage( 'page', \IPS\Request::i()->page );
}
\IPS\Output::i()->linkTags['canonical'] = (string) $baseUrl;
}
\IPS\Output::i()->title = $title;
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/statuses.css' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile' )->userContent( $this->member, $types, $currentAppModule, $currentType, (string) $output );
@@ -595,7 +640,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'profile.css', $class::$application ) );
if ( \IPS\IPS::classUsesTrait( $class, 'IPS\Content\Reactable' ) )
if ( \IPS\IPS::classUsesTrait( $class, 'IPS\Content\Reactable' ) and !$class::$firstCommentRequired )
{
$types[ $class::$application . '_' . $class::$module ][ mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) ) ] = $class;
}
@@ -641,11 +686,64 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$currentClass = $types[ $currentAppModule ][ $currentType ];
$currentAppArray = explode( '_', $currentAppModule );
$currentApp = $currentAppArray[0];
$member = $this->member;
/* Build a callback to merge in reputation data */
$callback = function( $rows ) use ( $member, $currentClass )
{
$ids = array();
$idColumn = $currentClass::$databaseColumnId;
foreach( $rows as $id => $row )
{
$ids[ $id ] = $row->$idColumn;
}
if ( \count( $ids ) )
{
$rep = iterator_to_array(
\IPS\Db::i()->select( 'core_reputation_index.type_id, core_reputation_index.id AS rep_id, core_reputation_index.rep_date, core_reputation_index.rep_rating, core_reputation_index.member_received as rep_member_received, core_reputation_index.member_id as rep_member, core_reputation_index.reaction as rep_reaction',
'core_reputation_index',
array( \IPS\Db::i()->in( 'core_reputation_index.type_id', array_values( $ids ) ) . " AND ( core_reputation_index.member_id=? OR core_reputation_index.member_received=? ) AND core_reputation_index.app=? AND core_reputation_index.type=?", $member->member_id, $member->member_id, $currentClass::$application, $currentClass::reactionType() ),
'rep_date desc'
)->setKeyField('rep_id')
);
$mapped = array();
foreach( $rep as $repId => $data )
{
$mapped[ $data['type_id' ] ][] = $data;
}
/* Now overwrite the data */
foreach( $rows as $id => $row )
{
if ( isset( $mapped[ $row->$idColumn ] ) )
{
/* Shift it to remove it from the stack as we always sort by desc */
$useThisRep = \array_shift( $mapped[ $row->$idColumn ] );
/* We now want to clone the object so we can make a separate copy, thus not updating the one object used multiple times */
$row->skipCloneDuplication = TRUE;
$rows[ $id ] = clone $row;
/* Now overwrite the data in $row */
foreach( array( 'rep_id', 'rep_date', 'rep_rating', 'rep_member_received', 'rep_member', 'rep_reaction' ) as $field )
{
$rows[ $id ]->$field = $useThisRep[ $field ];
}
}
}
}
return $rows;
};
/* 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 ) );
$table = new \IPS\Helpers\Table\Content( $currentClass, $url, NULL, NULL, \IPS\Content\Hideable::FILTER_AUTOMATIC, 'read', FALSE );
$table = new \IPS\Helpers\Table\Content( $currentClass, $url, NULL, NULL, \IPS\Content\Hideable::FILTER_AUTOMATIC, 'read', FALSE, FALSE, $callback );
$table->joinContainer = TRUE;
$table->sortOptions = array( 'rep_date' );
$table->sortBy = 'rep_date';
@@ -672,7 +770,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
/* Get the reputation summary */
$reactions = array( 'given' => array(), 'received' => array() );
foreach( \IPS\Db::i()->select( 'reaction, COUNT(*) as count', 'core_reputation_index', array( 'member_id=?', $this->member->member_id ), NULL, NULL, 'reaction' ) as $reaction )
foreach( \IPS\Db::i()->select( 'reaction, count(*) as count', 'core_reputation_index', array( 'member_id=?', $this->member->member_id ), NULL, NULL, 'reaction' ) as $reaction )
{
try
{
@@ -689,7 +787,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
catch( \UnderflowException $e ){}
}
foreach( \IPS\Db::i()->select( 'reaction, COUNT(*) as count', 'core_reputation_index', array( 'member_received=?', $this->member->member_id ), NULL, NULL, 'reaction' ) as $reaction )
foreach( \IPS\Db::i()->select( 'reaction, count(*) as count', 'core_reputation_index', array( 'member_received=?', $this->member->member_id ), NULL, NULL, 'reaction' ) as $reaction )
{
try
{
@@ -781,7 +879,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
\IPS\Output::i()->redirect( $status->url() );
}
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
catch ( \Exception $e )
{
@@ -810,6 +908,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$form->add( new \IPS\Helpers\Form\Editor( 'comment_value', $reply->content, TRUE, array(
'app' => 'core',
'key' => 'Members',
'maxLength' => 65535,
'autoSaveKey' => 'editComment-core/members-' . $reply->id,
'attachIds' => $reply->attachmentIds()
) ) );
@@ -829,7 +928,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
}
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
catch( \Exception $e )
{
@@ -863,13 +962,13 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
/* Set Session Location */
\IPS\Session::i()->setLocation( $this->member->url(), array(), 'loc_editing_profile', array( $this->member->name => FALSE ) );
if( !count( $form->elements ) )
if( !\count( $form->elements ) )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->genericBlock( \IPS\Member::loggedIn()->language()->addToStack( 'profile_nothing_to_edit' ), NULL, 'ipsPad' );
}
else if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
else
{
@@ -925,9 +1024,14 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
try
{
new \IPS\DateTime( $year."-".$month."-" . $date );
if( ( $month AND !$date ) OR ( !$month AND $date ) )
{
throw new \UnexpectedValueException;
}
new \IPS\DateTime( $year . "-" . $month . "-" . $date );
}
catch ( \Exception $e)
catch ( \Exception $e )
{
throw new \InvalidArgumentException( 'invalid_bdate') ;
}
@@ -954,7 +1058,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$values = array();
}
foreach ( \IPS\core\ProfileFields\Field::fields( $values, \IPS\core\ProfileFields\Field::PROFILE ) as $group => $fields )
foreach ( \IPS\core\ProfileFields\Field::fields( $values, \IPS\core\ProfileFields\Field::EDIT, $this->member ) as $group => $fields )
{
$form->addHeader( "core_pfieldgroups_{$group}" );
foreach ( $fields as $field )
@@ -966,7 +1070,10 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
/* Moderator stuff */
if ( ( \IPS\Member::loggedIn()->modPermission('can_modify_profiles') OR \IPS\Member::loggedIn()->modPermission('can_unban') ) AND \IPS\Member::loggedIn()->member_id != $this->member->member_id )
{
$form->add( new \IPS\Helpers\Form\Editor( 'signature', $this->member->signature, FALSE, array( 'app' => 'core', 'key' => 'Signatures', 'autoSaveKey' => "frontsig-" . $this->member->member_id, 'attachIds' => array( $this->member->member_id ) ) ) );
if( \IPS\Settings::i()->signatures_enabled )
{
$form->add( new \IPS\Helpers\Form\Editor( 'signature', $this->member->signature, FALSE, array( 'app' => 'core', 'key' => 'Signatures', 'autoSaveKey' => "frontsig-" . $this->member->member_id, 'attachIds' => array( $this->member->member_id ) ) ) );
}
if ( \IPS\Member::loggedIn()->modPermission('can_unban') )
{
@@ -1034,11 +1141,11 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
if ( $values['enable_status_updates'] )
{
\IPS\Content\Search\Index::i()->massUpdate( 'IPS\core\Statuses\Status', NULL, NULL, '*', NULL, NULL, $this->member->member_id );
\IPS\Content\Search\Index::i()->massUpdate( 'IPS\core\Statuses\Status', $this->member->member_id, NULL, '*', NULL, NULL, $this->member->member_id );
}
else
{
\IPS\Content\Search\Index::i()->massUpdate( 'IPS\core\Statuses\Status', NULL, NULL, '', NULL, NULL, $this->member->member_id );
\IPS\Content\Search\Index::i()->massUpdate( 'IPS\core\Statuses\Status', $this->member->member_id, NULL, '', NULL, NULL, $this->member->member_id );
}
}
@@ -1053,14 +1160,14 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
/* If the row only contains one column (eg. member_id) then the result of the query is a string, we do not want this */
if ( !is_array( $profileFields ) )
if ( !\is_array( $profileFields ) )
{
$profileFields = array();
}
$profileFields['member_id'] = $this->member->member_id;
foreach ( \IPS\core\ProfileFields\Field::fields( $profileFields, \IPS\core\ProfileFields\Field::PROFILE ) as $group => $fields )
foreach ( \IPS\core\ProfileFields\Field::fields( $profileFields, \IPS\core\ProfileFields\Field::EDIT, $this->member ) as $group => $fields )
{
foreach ( $fields as $id => $field )
{
@@ -1127,12 +1234,12 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
$photoVars = explode( ':', $this->member->group['g_photo_max_vars'] );
/* Init */
$form = new \IPS\Helpers\Form;
$form = new \IPS\Helpers\Form( 'profile_photo', 'continue' );
$form->ajaxOutput = TRUE;
$toggles = array( 'custom' => array( 'member_photo_upload' ), 'url' => array( 'member_photo_url' ) );
$extra = array();
$toggles = array( 'custom' => array( 'member_photo_upload' ) );
$options = array();
$defaultType = ( $this->member->pp_photo_type == 'letter' ) ? 'none' : $this->member->pp_photo_type;
@@ -1140,7 +1247,6 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
if ( $photoVars[0] )
{
$options['custom'] = 'member_photo_upload';
$options['url'] = 'member_photo_url';
}
/* Can we use gallery images? */
@@ -1149,17 +1255,6 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$options['gallery_Images'] = 'member_gallery_image';
}
/* Can we use Gravatar? */
if ( \IPS\Settings::i()->allow_gravatars )
{
$options['gravatar'] = 'member_photo_gravatar';
if ( $this->member->member_id === \IPS\Member::loggedIn()->member_id or \IPS\Member::loggedIn()->modPermission('can_see_emails') )
{
$extra[] = new \IPS\Helpers\Form\Email( 'photo_gravatar_email_public', $this->member->pp_gravatar ?: $this->member->email, FALSE, array( 'maxLength' => 255 ), NULL, NULL, NULL, 'member_photo_gravatar' );
$toggles['gravatar'] = array( 'member_photo_gravatar' );
}
}
/* And of course we can always not have a photo... except when we can't */
$photoRequired = FALSE;
foreach( \IPS\Member\ProfileStep::loadAll() AS $step )
@@ -1172,7 +1267,14 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
if ( $photoRequired === FALSE )
{
$options['none'] = 'member_photo_none';
if ( $this->member->pp_photo_type != 'none' )
{
$options['none'] = 'member_photo_remove';
}
else
{
$options['none'] = 'member_photo_none';
}
}
/* iOS doesn't like upload forms being hidden by a toggle; and it makes sense if we do not have a profile photo to show the upload as the selected option */
@@ -1182,54 +1284,42 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
/* Create that selection */
$form->add( new \IPS\Helpers\Form\Radio( 'pp_photo_type', $defaultType, TRUE, array( 'options' => $options, 'toggles' => $toggles ) ) );
if( \count( $options ) > 1 )
{
$form->add( new \IPS\Helpers\Form\Radio( 'pp_photo_type', $defaultType, TRUE, array( 'options' => $options, 'toggles' => $toggles ) ) );
}
else
{
$form->hiddenValues['pp_photo_type'] = $defaultType;
}
/* Create the upload field */
if ( $photoVars[0] )
{
$form->add( new \IPS\Helpers\Form\Upload( 'member_photo_upload', NULL, FALSE, array( 'image' => array( 'maxWidth' => $photoVars[1], 'maxHeight' => $photoVars[2] ), 'storageExtension' => 'core_Profile', 'maxFileSize' => $photoVars[0] ? $photoVars[0] / 1024 : NULL ), function( $val ) {
if ( $val instanceof \IPS\File )
$form->add( new \IPS\Helpers\Form\Upload( 'member_photo_upload', ( $this->member->pp_main_photo and $this->member->pp_photo_type == 'custom') ? \IPS\File::get( 'core_Profile', $this->member->pp_main_photo ) : NULL, FALSE, array( 'supportsDelete' => FALSE, 'image' => array( 'maxWidth' => $photoVars[1], 'maxHeight' => $photoVars[2] ), 'allowStockPhotos' => TRUE, 'storageExtension' => 'core_Profile', 'maxFileSize' => $photoVars[0] ? $photoVars[0] / 1024 : NULL ), function( $val ) {
if( \IPS\Request::i()->pp_photo_type == 'custom' AND !$val )
{
$image = \IPS\Image::create( $val->contents() );
if( $image->isAnimatedGif and !$this->member->group['g_upload_animated_photos'] )
{
throw new \DomainException('member_photo_upload_no_animated');
}
throw new \DomainException('form_required');
}
}, NULL, NULL, 'member_photo_upload' ) );
/* Create the URL */
$form->add( new \IPS\Helpers\Form\Url( 'member_photo_url', NULL, FALSE, array( 'file' => 'core_Profile', 'image' => TRUE, 'maxFileSize' => $photoVars[0] ? $photoVars[0] / 1024 : NULL, 'maxDimensions' => array( 'width' => $photoVars[1], 'height' => $photoVars[2] ) ), function( $val ) {
if ( $val instanceof \IPS\Http\Url )
if ( $val instanceof \IPS\File )
{
try
{
$image = \IPS\Image::create( (string) $val->request()->get() );
}
catch ( \InvalidArgumentException $e )
{
throw new \DomainException('member_photo_bad_url');
}
$image = \IPS\Image::create( $val->contents() );
if( $image->isAnimatedGif and !$this->member->group['g_upload_animated_photos'] )
{
throw new \DomainException( 'member_photo_upload_no_animated' );
}
} catch ( \IPS\File\Exception $e ){}
if( $image->isAnimatedGif and !$this->member->group['g_upload_animated_photos'] )
{
throw new \DomainException('member_photo_upload_no_animated');
}
}
}, NULL, NULL, 'member_photo_url' ) );
}, NULL, NULL, 'member_photo_upload' ) );
}
/* Add additional elements */
foreach ( $extra as $element )
{
$form->add( $element );
}
/* Handle submissions */
if ( $values = $form->values() )
{
$this->member->pp_photo_type = $values['pp_photo_type'];
{
/* Disable syncing */
$profileSync = $this->member->profilesync;
if ( isset( $profileSync['photo'] ) )
@@ -1237,16 +1327,16 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
unset( $profileSync['photo'] );
$this->member->profilesync = $profileSync;
}
switch ( $values['pp_photo_type'] )
{
case 'custom':
if ( $photoVars[0] and $values['member_photo_upload'] )
{
if ( (string) $values['member_photo_upload'] !== '' )
if ( (string) $values['member_photo_upload'] !== '' and $this->member->pp_main_photo !== (string) $values['member_photo_upload'] )
{
$this->member->pp_photo_type = 'custom';
$this->member->pp_main_photo = NULL;
$this->member->pp_main_photo = (string) $values['member_photo_upload'];
$thumbnail = $values['member_photo_upload']->thumbnail( 'core_Profile', \IPS\PHOTO_THUMBNAIL_SIZE, \IPS\PHOTO_THUMBNAIL_SIZE, TRUE );
@@ -1256,31 +1346,12 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
}
break;
case 'url':
if( $photoVars[0] and $values['member_photo_url'] )
{
$this->member->pp_photo_type = 'custom';
$this->member->pp_main_photo = NULL;
$this->member->pp_main_photo = (string) $values['member_photo_url'];
$thumbnail = $values['member_photo_url']->thumbnail( 'core_Profile', \IPS\PHOTO_THUMBNAIL_SIZE, \IPS\PHOTO_THUMBNAIL_SIZE, TRUE );
$this->member->pp_thumb_photo = (string) $thumbnail;
$this->member->photo_last_update = time();
}
break;
case 'none':
$this->member->pp_photo_type = NULL;
$this->member->pp_main_photo = NULL;
$this->member->members_bitoptions['bw_disable_gravatar'] = 1;
$this->member->photo_last_update = NULL;
break;
case 'gravatar':
$this->member->pp_gravatar = ( !isset( $values['photo_gravatar_email_public'] ) or $values['photo_gravatar_email_public'] === $this->member->email ) ? NULL : $values['photo_gravatar_email_public'];
break;
}
/* Reset Profile Complete flag in case this was an optional step */
@@ -1317,7 +1388,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
/* Display */
\IPS\Session::i()->setLocation( $this->member->url(), array(), 'loc_editing_profile', array( $this->member->name => FALSE ) );
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'editing_profile', FALSE, array( 'sprintf' => array( $this->member->name ) ) );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'editing_profile', FALSE, array( 'sprintf' => array( $this->member->name ) ) ) );
}
@@ -1427,7 +1498,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
/* Display */
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
@@ -1499,7 +1570,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
{
\IPS\Output::i()->json( array(
'status' => 'ok',
'count' => count( $item->reactions() ),
'count' => \count( $item->reactions() ),
'score' => $item->reactionCount(),
'blurb' => ( \IPS\Settings::i()->reaction_count_display == 'count' ) ? '' : \IPS\Theme::i()->getTemplate( 'global', 'core' )->reactionBlurb( $item )
));
@@ -1535,13 +1606,15 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
try
{
$item = ( \IPS\Request::i()->type == 'status' ) ? \IPS\core\Statuses\Status::load( \IPS\Request::i()->status ) : \IPS\core\Statuses\Reply::load( \IPS\Request::i()->reply );
$item->removeReaction();
$member = ( isset( \IPS\Request::i()->member ) and \IPS\Member::loggedIn()->modPermission('can_remove_reactions') ) ? \IPS\Member::load( \IPS\Request::i()->member ) : \IPS\Member::loggedIn();
$item->removeReaction( $member );
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array(
'status' => 'ok',
'count' => count( $item->reactions() ),
'count' => \count( $item->reactions() ),
'score' => $item->reactionCount(),
'blurb' => ( \IPS\Settings::i()->reaction_count_display == 'count' ) ? '' : \IPS\Theme::i()->getTemplate( 'global', 'core' )->reactionBlurb( $item )
));
@@ -1574,38 +1647,54 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
try
{
$item = ( \IPS\Request::i()->type == 'status' ) ? \IPS\core\Statuses\Status::load( \IPS\Request::i()->status ) : \IPS\core\Statuses\Reply::load( \IPS\Request::i()->reply );
$tabs = array();
$tabs['all'] = \IPS\Member::loggedIn()->language()->addToStack('all');
foreach( \IPS\Content\Reaction::roots() AS $reaction )
if ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->tooltip ) and isset( \IPS\Request::i()->reaction ) )
{
if ($reaction->_enabled !== FALSE)
{
$tabs[$reaction->id] = $reaction->_title;
}
}
$activeTab = 'all';
if ( isset( \IPS\Request::i()->reaction ) )
{
$activeTab = \IPS\Request::i()->reaction;
}
$url = $item->url('showReactions');
$url = $url->setQueryString( 'changed', 1 );
if ( $activeTab !== 'all' )
{
$url = $url->setQueryString( 'reaction', $activeTab );
}
if ( \IPS\Request::i()->isAjax() AND isset( \IPS\Request::i()->changed ) )
{
\IPS\Output::i()->output = $item->reactionTable( $activeTab !== 'all' ? $activeTab : NULL, $url, 'reaction', FALSE );
$reaction = \IPS\Content\Reaction::load( \IPS\Request::i()->reaction );
$numberToShowInPopup = 10;
$where = $item->getReactionWhereClause( $reaction );
$total = \IPS\Db::i()->select( 'COUNT(*)', 'core_reputation_index', $where )->join( 'core_reactions', 'reaction=reaction_id' )->first();
$names = \IPS\Db::i()->select( 'name', 'core_reputation_index', $where, 'rep_date DESC', $numberToShowInPopup )->join( 'core_reactions', 'reaction=reaction_id' )->join( 'core_members', 'core_reputation_index.member_id=core_members.member_id' );
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->reactionTooltip( $reaction, $total ? $names : [], ( $total > $numberToShowInPopup ) ? ( $total - $numberToShowInPopup ) : 0 ) );
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, $item->reactionTable( $activeTab !== 'all' ? $activeTab : NULL ), $url, 'reaction', FALSE );
{
$tabs = array();
$tabs['all'] = \IPS\Member::loggedIn()->language()->addToStack('all');
foreach( \IPS\Content\Reaction::roots() AS $reaction )
{
if ($reaction->_enabled !== FALSE)
{
$tabs[$reaction->id] = $reaction->_title;
}
}
$activeTab = 'all';
if ( isset( \IPS\Request::i()->reaction ) )
{
$activeTab = \IPS\Request::i()->reaction;
}
$url = $item->url('showReactions');
$url = $url->setQueryString( 'changed', 1 );
if ( $activeTab !== 'all' )
{
$url = $url->setQueryString( 'reaction', $activeTab );
}
\IPS\Output::i()->metaTags['robots'] = 'noindex';
if ( \IPS\Content\Reaction::isLikeMode() or ( \IPS\Request::i()->isAjax() AND isset( \IPS\Request::i()->changed ) ) )
{
\IPS\Output::i()->output = $item->reactionTable( $activeTab !== 'all' ? $activeTab : NULL, $url, 'reaction', FALSE );
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, $item->reactionTable( $activeTab !== 'all' ? $activeTab : NULL ), $url, 'reaction', FALSE );
}
}
}
catch( \OutOfRangeException $e )
@@ -1631,8 +1720,8 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$commentClass = '\IPS\core\Statuses\Reply';
$item = ( \IPS\Request::i()->type == 'status' ) ? $itemClass::load( \IPS\Request::i()->status ) : $commentClass::load( \IPS\Request::i()->reply );
$canReport = $item->canReport();
if ( $canReport !== TRUE )
if ( $canReport !== TRUE AND !( $canReport == 'report_err_already_reported' AND \IPS\Settings::i()->automoderation_enabled ) )
{
\IPS\Output::i()->error( $canReport, '1C138/6', 403, '' );
}
@@ -1641,6 +1730,30 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
$form->class = 'ipsForm_vertical';
$idColumn = ( \IPS\Request::i()->type == 'status' ) ? $itemClass::$databaseColumnId : $commentClass::$databaseColumnId;
$autoSaveKey = ( \IPS\Request::i()->type == 'status' ) ? "report-{$itemClass::$application}-{$itemClass::$module}-{$item->$idColumn}" : "report-{$itemClass::$application}-{$itemClass::$module}-{$item->status_id}-{$item->$idColumn}";
/* As we group by user id to determine if max points have been reached, guests cannot contribute to counts */
if ( \IPS\Member::loggedIn()->member_id and \IPS\Settings::i()->automoderation_enabled )
{
/* Has this member already reported this in the past 24 hours */
try
{
$index = \IPS\core\Reports\Report::loadByClassAndId( \get_class( $item ), $item->$idColumn );
$report = \IPS\Db::i()->select( '*', 'core_rc_reports', array( 'rid=? and report_by=? and date_reported > ?', $index->id, \IPS\Member::loggedIn()->member_id, time() - ( \IPS\Settings::i()->automoderation_report_again_mins * 60 ) ) )->first();
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'system', 'core' )->reportedAlready( $index, $report, $item );
return;
}
catch( \Exception $e ) { }
$options = array( \IPS\core\Reports\Report::TYPE_MESSAGE => \IPS\Member::loggedIn()->language()->addToStack('report_message_item') );
foreach( \IPS\core\Reports\Types::roots() as $type )
{
$options[ $type->id ] = $type->_title;
}
$form->add( new \IPS\Helpers\Form\Radio( 'report_type', NULL, FALSE, array( 'options' => $options ) ) );
}
$form->add( new \IPS\Helpers\Form\Editor( 'report_message', NULL, FALSE, array( 'app' => 'core', 'key' => 'Reports', 'autoSaveKey' => $autoSaveKey, 'minimize' => 'report_message_placeholder' ) ) );
if( !\IPS\Member::loggedIn()->member_id )
{
@@ -1648,7 +1761,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
if ( $values = $form->values() )
{
$report = $item->report( $values['report_message'] );
$report = $item->report( $values['report_message'], ( isset( $values['report_type'] ) ) ? $values['report_type'] : 0 );
\IPS\File::claimAttachments( $autoSaveKey, $report->id );
if ( \IPS\Request::i()->isAjax() )
{
@@ -1661,7 +1774,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'report_content' );
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
catch( \LogicException $e )
{
@@ -1676,7 +1789,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
*/
protected function followers()
{
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
@@ -1684,7 +1797,8 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
}
$limit = array( ( $page - 1 ) * 50, 50 );
$followers = $this->member->followers( ( \IPS\Member::loggedIn()->isAdmin() OR \IPS\Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Member::FOLLOW_PUBLIC + \IPS\Member::FOLLOW_ANONYMOUS : \IPS\Member::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly' ), NULL, $limit, 'name' );
$followers = $this->member->followers( ( \IPS\Member::loggedIn()->isAdmin() OR \IPS\Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Member::FOLLOW_PUBLIC + \IPS\Member::FOLLOW_ANONYMOUS : \IPS\Member::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly', 'none' ), NULL, $limit, 'name' );
$followersCount = $this->member->followersCount( ( \IPS\Member::loggedIn()->isAdmin() OR \IPS\Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Member::FOLLOW_PUBLIC + \IPS\Member::FOLLOW_ANONYMOUS : \IPS\Member::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly', 'none' ) );
if ( \IPS\Request::i()->isAjax() )
{
@@ -1693,7 +1807,7 @@ class _profile extends \IPS\Helpers\CoverPhoto\Controller
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('members_followers', FALSE, array( 'sprintf' => array( $this->member->name ) ) );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('members_followers', FALSE, array( 'sprintf' => array( $this->member->name ) ) ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile' )->allFollowers( $this->member, $followers );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'profile' )->allFollowers( $this->member, $followers, $followersCount );
}
/**