Version 4.1.2
This commit is contained in:
1 parent
3ba79295ee
commit
28bd025b35
1131 files changed
+63658
-20579
No files matched your search
+357
-202
@@ -94,6 +94,10 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
'remove_gallery_upload' => 4, // Remove permission to upload images in Gallery
|
||||
'no_report_count' => 8, // 1 means the report count will not show
|
||||
'has_no_ignored_users' => 16, // If we know the user has no ignored users, we don't have to query for them
|
||||
'must_reaccept_privacy' => 32, // 1 means the member needs to re-accept the privacy policy
|
||||
'must_reaccept_terms' => 64, // 1 means the member needs to re-accept the registration terms
|
||||
'email_notifications_once' => 128, // 1 means the member only wants one email per notification item until they revisit the community
|
||||
'disable_notification_sounds' => 256 // 1 means notification sounds are disabled, 0 is enabled
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -347,7 +351,7 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
/* Run member sync, but not if the only change is the last_activity timestamp */
|
||||
if( count( $changes ) > 1 OR !isset( $changes['last_activity'] ) )
|
||||
{
|
||||
$this->memberSync( 'onProfileUpdate', array( 'changes' => $changes ) );
|
||||
$this->memberSync( 'onProfileUpdate', array( 'changes' => array_merge( $changes, $this->changedCustomFields ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,6 +390,17 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public $markers = array();
|
||||
protected $markersResetTimes = array();
|
||||
protected $haveAllMarkers = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Default stream ID
|
||||
*/
|
||||
protected $defaultStreamId = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Keep track of any changed profile fields
|
||||
*/
|
||||
public $changedCustomFields = array();
|
||||
|
||||
/**
|
||||
* Get name, do not return "guest" name if not set
|
||||
@@ -408,8 +423,8 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('guest');
|
||||
}
|
||||
|
||||
return $this->_data['name'];
|
||||
|
||||
return $this->member_id ? $this->_data['name'] : \IPS\Member::loggedIn()->language()->addToStack( 'guest_name_shown', NULL, array( 'sprintf' => array( $this->_data['name'] ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -546,8 +561,8 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
/* Edited member, so clear widget caches (stats, widgets that contain photos, names and so on) */
|
||||
\IPS\Widget::deleteCaches();
|
||||
|
||||
/* Send to the queue */
|
||||
foreach ( \IPS\Content::routedClasses( FALSE, FALSE, FALSE ) as $class )
|
||||
/* Send to the queue, include archived content */
|
||||
foreach ( \IPS\Content::routedClasses( FALSE, TRUE, FALSE ) as $class )
|
||||
{
|
||||
if ( isset( $class::$databaseColumnMap['author'] ) and ( $action == 'delete' or in_array( 'IPS\Content\Hideable', class_implements( $class ) ) ) )
|
||||
{
|
||||
@@ -629,9 +644,9 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function get_group()
|
||||
{
|
||||
/* Load primary group */
|
||||
if ( $this->_group === NULL )
|
||||
{
|
||||
/* Load primary group */
|
||||
try
|
||||
{
|
||||
$group = \IPS\Member\Group::load( $this->_data['member_group_id'] );
|
||||
@@ -642,138 +657,140 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
|
||||
$this->_group = array_merge( $group->data(), $group->g_bitoptions->asArray() );
|
||||
}
|
||||
|
||||
/* Merge in secondary group data */
|
||||
if ( !empty( $this->_data['mgroup_others'] ) )
|
||||
{
|
||||
$groups = array_filter( explode( ',', $this->_data['mgroup_others'] ) );
|
||||
$exclude = array();
|
||||
$lessIsMore = array();
|
||||
$neg1IsBest = array();
|
||||
$zeroIsBest = array();
|
||||
$callback = array();
|
||||
|
||||
/* Get the limits we need to work out from apps */
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'GroupLimits', FALSE, 'core' ) as $key => $extension )
|
||||
/* Merge in secondary group data */
|
||||
if ( !empty( $this->_data['mgroup_others'] ) )
|
||||
{
|
||||
if( method_exists( $extension, 'getLimits' ) )
|
||||
$groups = array_filter( explode( ',', $this->_data['mgroup_others'] ) );
|
||||
$exclude = array();
|
||||
$lessIsMore = array();
|
||||
$neg1IsBest = array();
|
||||
$zeroIsBest = array();
|
||||
$callback = array();
|
||||
|
||||
/* Get the limits we need to work out from apps */
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'GroupLimits', FALSE, 'core' ) as $key => $extension )
|
||||
{
|
||||
$appLimits = $extension->getLimits();
|
||||
|
||||
if( !empty( $appLimits['neg1IsBest'] ) )
|
||||
if( method_exists( $extension, 'getLimits' ) )
|
||||
{
|
||||
$neg1IsBest = array_merge( $neg1IsBest, $appLimits['neg1IsBest'] );
|
||||
}
|
||||
$appLimits = $extension->getLimits();
|
||||
|
||||
if( !empty( $appLimits['zeroIsBest'] ) )
|
||||
{
|
||||
$zeroIsBest = array_merge( $zeroIsBest, $appLimits['zeroIsBest'] );
|
||||
}
|
||||
|
||||
if( !empty( $appLimits['lessIsMore'] ) )
|
||||
{
|
||||
$lessIsMore = array_merge( $lessIsMore, $appLimits['lessIsMore'] );
|
||||
}
|
||||
|
||||
if( !empty( $appLimits['exclude'] ) )
|
||||
{
|
||||
$exclude = array_merge( $exclude, $appLimits['exclude'] );
|
||||
}
|
||||
|
||||
if( !empty( $appLimits['callback'] ) )
|
||||
{
|
||||
$callback = array_merge( $callback, $appLimits['callback'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the merging */
|
||||
$skippedGroups = array();
|
||||
|
||||
foreach( $groups as $gid )
|
||||
{
|
||||
try
|
||||
{
|
||||
$group = \IPS\Member\Group::load( $gid );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
$skippedGroups[] = $gid;
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach( $group->_data as $k => $v )
|
||||
{
|
||||
if ( ! in_array( $k, $exclude ) )
|
||||
{
|
||||
if ( in_array( $k, $zeroIsBest ) )
|
||||
if( !empty( $appLimits['neg1IsBest'] ) )
|
||||
{
|
||||
if ( empty( $this->_group[ $k ] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if( $v == 0 )
|
||||
{
|
||||
$this->_group[ $k ] = 0;
|
||||
}
|
||||
else if ( $v > $this->_group[ $k ] )
|
||||
{
|
||||
$this->_group[ $k ] = $v;
|
||||
}
|
||||
$neg1IsBest = array_merge( $neg1IsBest, $appLimits['neg1IsBest'] );
|
||||
}
|
||||
else if( in_array( $k, $neg1IsBest ) )
|
||||
{
|
||||
|
||||
if ( $this->_group[ $k ] == -1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if( $v == -1 )
|
||||
{
|
||||
$this->_group[ $k ] = -1;
|
||||
}
|
||||
else if ( $v > $this->_group[ $k ] )
|
||||
{
|
||||
$this->_group[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
else if ( in_array( $k, $lessIsMore ) )
|
||||
if( !empty( $appLimits['zeroIsBest'] ) )
|
||||
{
|
||||
if ( $v < $this->_group[ $k ] )
|
||||
{
|
||||
$this->_group[ $k ] = $v;
|
||||
}
|
||||
$zeroIsBest = array_merge( $zeroIsBest, $appLimits['zeroIsBest'] );
|
||||
}
|
||||
else if ( array_key_exists( $k, $callback ) )
|
||||
|
||||
if( !empty( $appLimits['lessIsMore'] ) )
|
||||
{
|
||||
$result = call_user_func( $callback[ $k ], $this->_group, array_merge( $group->_data, $group->g_bitoptions->asArray() ), $k, $this->_data );
|
||||
|
||||
if( is_array( $result ) )
|
||||
{
|
||||
$this->_group = array_merge( $this->_group, $result );
|
||||
}
|
||||
else if( $result !== NULL )
|
||||
{
|
||||
$this->_group[ $k ] = $result;
|
||||
}
|
||||
$lessIsMore = array_merge( $lessIsMore, $appLimits['lessIsMore'] );
|
||||
}
|
||||
else
|
||||
|
||||
if( !empty( $appLimits['exclude'] ) )
|
||||
{
|
||||
if ( !isset( $this->_group[ $k ] ) OR $v > $this->_group[ $k ] )
|
||||
$exclude = array_merge( $exclude, $appLimits['exclude'] );
|
||||
}
|
||||
|
||||
if( !empty( $appLimits['callback'] ) )
|
||||
{
|
||||
$callback = array_merge( $callback, $appLimits['callback'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the merging */
|
||||
$skippedGroups = array();
|
||||
|
||||
foreach( $groups as $gid )
|
||||
{
|
||||
try
|
||||
{
|
||||
$group = \IPS\Member\Group::load( $gid );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
$skippedGroups[] = $gid;
|
||||
continue;
|
||||
}
|
||||
|
||||
$_data = array_merge( $group->_data, $group->g_bitoptions->asArray() );
|
||||
|
||||
foreach( $_data as $k => $v )
|
||||
{
|
||||
if ( ! in_array( $k, $exclude ) )
|
||||
{
|
||||
if ( in_array( $k, $zeroIsBest ) )
|
||||
{
|
||||
$this->_group[ $k ] = $v;
|
||||
if ( empty( $this->_group[ $k ] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if( $v == 0 )
|
||||
{
|
||||
$this->_group[ $k ] = 0;
|
||||
}
|
||||
else if ( $v > $this->_group[ $k ] )
|
||||
{
|
||||
$this->_group[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
else if( in_array( $k, $neg1IsBest ) )
|
||||
{
|
||||
|
||||
if ( $this->_group[ $k ] == -1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if( $v == -1 )
|
||||
{
|
||||
$this->_group[ $k ] = -1;
|
||||
}
|
||||
else if ( $v > $this->_group[ $k ] )
|
||||
{
|
||||
$this->_group[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
else if ( in_array( $k, $lessIsMore ) )
|
||||
{
|
||||
if ( $v < $this->_group[ $k ] )
|
||||
{
|
||||
$this->_group[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
else if ( array_key_exists( $k, $callback ) )
|
||||
{
|
||||
$result = call_user_func( $callback[ $k ], $this->_group, $_data, $k, $this->_data );
|
||||
|
||||
if( is_array( $result ) )
|
||||
{
|
||||
$this->_group = array_merge( $this->_group, $result );
|
||||
}
|
||||
else if( $result !== NULL )
|
||||
{
|
||||
$this->_group[ $k ] = $result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isset( $this->_group[ $k ] ) OR $v > $this->_group[ $k ] )
|
||||
{
|
||||
$this->_group[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( count( $skippedGroups ) )
|
||||
{
|
||||
$this->mgroup_others = implode( ',', array_diff( $groups, $skippedGroups ) );
|
||||
|
||||
parent::save();
|
||||
|
||||
if( count( $skippedGroups ) )
|
||||
{
|
||||
$this->mgroup_others = implode( ',', array_diff( $groups, $skippedGroups ) );
|
||||
|
||||
parent::save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -967,59 +984,7 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function get_photo( $thumb=TRUE )
|
||||
{
|
||||
$url = NULL;
|
||||
if ( mb_substr( $this->pp_photo_type, 0, 5 ) === 'sync-' or $this->pp_photo_type === 'custom' )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( !$this->pp_main_photo )
|
||||
{
|
||||
return \IPS\Theme::i()->resource( 'default_photo.png', 'core', 'global' );
|
||||
}
|
||||
|
||||
return \IPS\File::get( 'core_Profile', ( $thumb and $this->pp_thumb_photo ) ? $this->pp_thumb_photo : $this->pp_main_photo )->url;
|
||||
}
|
||||
catch ( \InvalidArgumentException $e ) { }
|
||||
}
|
||||
elseif ( $this->pp_photo_type === 'gravatar' )
|
||||
{
|
||||
$url = \IPS\Theme::i()->resource( 'default_photo.png', 'core', 'global' );
|
||||
if ( \IPS\IN_DEV ) // Gravatar will error for localhost URLs. We'll assume anyone on localhost is IN_DEV. This way also allows us to easily see what is loading from Gravatar.
|
||||
{
|
||||
$url = '';
|
||||
}
|
||||
$photoVars = explode( ':', $this->group['g_photo_max_vars'] );
|
||||
|
||||
$url = \IPS\Http\Url::external( "https://secure.gravatar.com/avatar/" . md5( trim( mb_strtolower( $this->pp_gravatar ?: $this->email ) ) ) . ( $photoVars[0] ? ( "?size=" . min( $photoVars[1], $photoVars[2] ) ) : '' ) . "&d=" . urlencode( $url ) );
|
||||
if ( \IPS\Dispatcher::hasInstance() AND \IPS\Dispatcher::i()->controllerLocation === 'admin' )
|
||||
{
|
||||
return $url->makeSafeForAcp( TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
elseif( $this->pp_photo_type and $this->pp_photo_type != 'none' )
|
||||
{
|
||||
/* This allows an app (such as Gallery) to set the pp_photo_type to a storage container to support custom images without duplicating them */
|
||||
try
|
||||
{
|
||||
return \IPS\File::get( $this->pp_photo_type, $this->pp_main_photo )->url;
|
||||
}
|
||||
catch ( \InvalidArgumentException $e )
|
||||
{
|
||||
/* If there was an exception, clear these values out - most likely the image or storage container is no longer valid */
|
||||
$this->pp_photo_type = NULL;
|
||||
$this->pp_main_photo = NULL;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$url )
|
||||
{
|
||||
return \IPS\Theme::i()->resource( 'default_photo.png', 'core', 'global' );
|
||||
}
|
||||
return static::photoUrl( $this->_data, $thumb );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1197,6 +1162,51 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
|
||||
$this->_data['members_day_posts'] = implode( ',', $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get member's default stream
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_defaultStream()
|
||||
{
|
||||
if ( $this->defaultStreamId === FALSE )
|
||||
{
|
||||
if ( $this->member_streams and $streams = json_decode( $this->member_streams, TRUE ) and count( $streams ) )
|
||||
{
|
||||
$this->defaultStreamId = ( isset( $streams['default'] ) ? $streams['default'] : NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->defaultStreamId = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->defaultStreamId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set member's default stream
|
||||
*
|
||||
* @param null|int $value Null or stream ID. 0 is for 'all activity'
|
||||
* @return void
|
||||
*/
|
||||
public function set_defaultStream( $value )
|
||||
{
|
||||
if ( $this->member_streams and $streams = json_decode( $this->member_streams, TRUE ) and count( $streams ) )
|
||||
{
|
||||
$streams['default'] = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$streams = array( 'streams' => array(), 'default' => $value );
|
||||
}
|
||||
|
||||
$this->member_streams = json_encode( $streams );
|
||||
$this->save();
|
||||
|
||||
$this->defaultStreamId = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get member location
|
||||
@@ -1311,6 +1321,95 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
$this->failed_login_count = $highest;
|
||||
}
|
||||
|
||||
/* !Photos */
|
||||
|
||||
/**
|
||||
* Columns needed to build photos
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function columnsForPhoto()
|
||||
{
|
||||
$return = array( 'member_id', 'name', 'members_seo_name', 'member_group_id', 'pp_photo_type', 'pp_main_photo', 'pp_thumb_photo' );
|
||||
|
||||
if ( true or \IPS\Settings::i()->allow_gravatars )
|
||||
{
|
||||
$return[] = 'pp_gravatar';
|
||||
$return[] = 'email';
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get photo from data
|
||||
*
|
||||
* @param array $memberData Array of member data, must include values for at least the keys returned by columnsForPhoto()
|
||||
* @param bool $thumb Use thumbnail?
|
||||
* @return string
|
||||
*/
|
||||
public static function photoUrl( $memberData, $thumb = TRUE )
|
||||
{
|
||||
$url = NULL;
|
||||
|
||||
/* Either uploaded or synced from social media */
|
||||
if ( $memberData['pp_main_photo'] and ( mb_substr( $memberData['pp_photo_type'], 0, 5 ) === 'sync-' or $memberData['pp_photo_type'] === 'custom' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
return (string) \IPS\File::get( 'core_Profile', ( $thumb and $memberData['pp_thumb_photo'] ) ? $memberData['pp_thumb_photo'] : $memberData['pp_main_photo'] )->url;
|
||||
}
|
||||
catch ( \InvalidArgumentException $e ) { }
|
||||
}
|
||||
|
||||
/* Gravatar */
|
||||
elseif ( \IPS\Settings::i()->allow_gravatars and $memberData['pp_photo_type'] === 'gravatar' )
|
||||
{
|
||||
/* Default URL we send to Gravatar for it to fallback for. Gravatar will error for localhost URLs, so if IN_DEV, don't send this (this way also allows us to easily see what is loading from Gravatar). */
|
||||
$defaultUrl = \IPS\IN_DEV ? '' : \IPS\Theme::i()->resource( 'default_photo.png', 'core', 'global' );
|
||||
|
||||
/* We need to know how big the photo can be */
|
||||
$photoVars = explode( ':', \IPS\Member::load( $memberData['member_id'] )->group['g_photo_max_vars'] );
|
||||
|
||||
/* Construct the URL */
|
||||
$url = \IPS\Http\Url::external( "https://secure.gravatar.com/avatar/" . md5( trim( mb_strtolower( $memberData['pp_gravatar'] ?: $memberData['email'] ) ) ) )->setQueryString( array(
|
||||
'd' => $defaultUrl
|
||||
) );
|
||||
|
||||
/* If we're in the ACP, munge because this is an external resource */
|
||||
if ( \IPS\Dispatcher::hasInstance() AND \IPS\Dispatcher::i()->controllerLocation === 'admin' )
|
||||
{
|
||||
$url = $url->makeSafeForAcp( TRUE );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return (string) $url;
|
||||
}
|
||||
|
||||
/* Other - This allows an app (such as Gallery) to set the pp_photo_type to a storage container to support custom images without duplicating them */
|
||||
elseif( $memberData['pp_photo_type'] and $memberData['pp_photo_type'] != 'none' )
|
||||
{
|
||||
try
|
||||
{
|
||||
return (string) \IPS\File::get( $memberData['pp_photo_type'], $memberData['pp_main_photo'] )->url;
|
||||
}
|
||||
catch ( \InvalidArgumentException $e )
|
||||
{
|
||||
/* If there was an exception, clear these values out - most likely the image or storage container is no longer valid */
|
||||
$member = \IPS\Member::load( $memberData['member_id'] );
|
||||
$member->pp_photo_type = NULL;
|
||||
$member->pp_main_photo = NULL;
|
||||
$member->save();
|
||||
}
|
||||
}
|
||||
|
||||
/* Still here? Return default photo */
|
||||
if ( !$url )
|
||||
{
|
||||
return \IPS\Theme::i()->resource( 'default_photo.png', 'core', 'global' );
|
||||
}
|
||||
}
|
||||
|
||||
/* !Get Calculated Properties */
|
||||
|
||||
@@ -1705,7 +1804,10 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
else
|
||||
{
|
||||
$return[ $ip ] = $data;
|
||||
if ( $ip )
|
||||
{
|
||||
$return[ $ip ] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1736,7 +1838,7 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function markersItems( $app, $key )
|
||||
{
|
||||
if ( !isset( $this->markers[ $app ][ $key ] ) )
|
||||
if ( !isset( $this->markers[ $app ] ) or !array_key_exists( $key, $this->markers[ $app ] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1745,74 +1847,105 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
return array();
|
||||
$this->markers[ $app ][ $key ] = NULL;
|
||||
}
|
||||
}
|
||||
return json_decode( $this->markers[ $app ][ $key ]['item_read_array'], TRUE );
|
||||
return $this->markers[ $app ][ $key ] ? json_decode( $this->markers[ $app ][ $key ]['item_read_array'], TRUE ) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get read/unread markers for containers
|
||||
*
|
||||
* @param string $app Application key
|
||||
* @param string|NULL $app Application key or NULL for all applications
|
||||
* @return array
|
||||
*/
|
||||
public function markersResetTimes( $app )
|
||||
{
|
||||
if ( !isset( $this->markersResetTimes[ $app ] ) )
|
||||
if ( ( !$app and !$this->haveAllMarkers ) or ( $app and !isset( $this->markersResetTimes[ $app ] ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->markersResetTimes[ $app ] = array();
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_item_markers', array( 'item_member_id=? AND item_app=?', $this->member_id, $app ) ) as $row )
|
||||
$where = array( array( 'item_member_id=?', $this->member_id ) );
|
||||
if ( $app )
|
||||
{
|
||||
$this->markersResetTimes[ $app ] = array();
|
||||
$where[] = array( 'item_app=?', $app );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->markersResetTimes = array();
|
||||
}
|
||||
|
||||
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_item_markers', $where ) as $row )
|
||||
{
|
||||
if( !is_array( $this->markersResetTimes[ $app ] ) )
|
||||
if( !isset( $this->markersResetTimes[ $row['item_app'] ] ) or !is_array( $this->markersResetTimes[ $row['item_app'] ] ) )
|
||||
{
|
||||
$this->markersResetTimes[ $app ] = array();
|
||||
$this->markersResetTimes[ $row['item_app'] ] = array();
|
||||
}
|
||||
|
||||
if ( $row['item_app_key_1'] )
|
||||
{
|
||||
if ( $row['item_app_key_2'] )
|
||||
{
|
||||
if( !isset( $this->markersResetTimes[ $app ][ $row['item_app_key_1'] ] ) OR !is_array( $this->markersResetTimes[ $app ][ $row['item_app_key_1'] ] ) )
|
||||
if( !isset( $this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ] ) OR !is_array( $this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ] ) )
|
||||
{
|
||||
$this->markersResetTimes[ $app ][ $row['item_app_key_1'] ] = array();
|
||||
$this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ] = array();
|
||||
}
|
||||
|
||||
if ( $row['item_app_key_3'] )
|
||||
{
|
||||
if( !isset( $this->markersResetTimes[ $app ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ] ) OR !is_array( $this->markersResetTimes[ $app ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ] ) )
|
||||
if( !isset( $this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ] ) OR !is_array( $this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ] ) )
|
||||
{
|
||||
$this->markersResetTimes[ $app ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ] = array();
|
||||
$this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ] = array();
|
||||
}
|
||||
|
||||
$this->markersResetTimes[ $app ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ][ $row['item_app_key_3'] ] = $row['item_global_reset'];
|
||||
$this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ][ $row['item_app_key_3'] ] = $row['item_global_reset'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->markersResetTimes[ $app ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ] = $row['item_global_reset'];
|
||||
$this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ][ $row['item_app_key_2'] ] = $row['item_global_reset'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->markersResetTimes[ $app ][ $row['item_app_key_1'] ] = $row['item_global_reset'];
|
||||
$this->markersResetTimes[ $row['item_app'] ][ $row['item_app_key_1'] ] = $row['item_global_reset'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->markersResetTimes[ $app ] = $row['item_global_reset'];
|
||||
$this->markersResetTimes[ $row['item_app'] ] = $row['item_global_reset'];
|
||||
}
|
||||
|
||||
$this->markers[ $app ][ $row['item_key'] ] = $row;
|
||||
$this->markers[ $row['item_app'] ][ $row['item_key'] ] = $row;
|
||||
}
|
||||
|
||||
if ( !$app )
|
||||
{
|
||||
$this->haveAllMarkers = TRUE;
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$this->markersResetTimes[ $app ] = NULL;
|
||||
if ( $app )
|
||||
{
|
||||
$this->markersResetTimes[ $app ] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->markersResetTimes = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->markersResetTimes[ $app ];
|
||||
|
||||
if ( $app )
|
||||
{
|
||||
return $this->markersResetTimes[ $app ];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->markersResetTimes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2158,7 +2291,19 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
/* If it's an array, combine the values */
|
||||
elseif ( is_array( $this->modPermissions[ $k ] ) AND is_array( $v ) )
|
||||
{
|
||||
$this->modPermissions[ $k ] = array_merge( $this->modPermissions[ $k ], $v );
|
||||
foreach( $v as $_k => $_v )
|
||||
{
|
||||
/* If this key isn't set yet, then use this value */
|
||||
if( !isset( $this->modPermissions[ $k ][ $_k ] ) )
|
||||
{
|
||||
$this->modPermissions[ $k ][ $_k ] = $_v;
|
||||
}
|
||||
/* Otherwise, we only set the value if it's better than what is already set */
|
||||
elseif ( $_v == -1 or ( $this->modPermissions[ $k ][ $_k ] != -1 and $_v > $this->modPermissions[ $k ][ $_k ] ) )
|
||||
{
|
||||
$this->modPermissions[ $k ][ $_k ] = $_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If it's a number, they get the higher one, or -1 is best */
|
||||
@@ -2172,7 +2317,7 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return */
|
||||
return $this->modPermissions;
|
||||
}
|
||||
@@ -2254,7 +2399,7 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( isset( $this->ignorePreferences[ $member->member_id ] ) )
|
||||
{
|
||||
return (bool) $this->ignorePreferences[ $member->member_id ][ 'ignore_' . $type ];
|
||||
@@ -2270,7 +2415,7 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function createMenu()
|
||||
{
|
||||
if ( $this->create_menu === NULL or \IPS\IN_DEV )
|
||||
if ( $this->create_menu === NULL or ( \IPS\IN_DEV and !\IPS\DEV_USE_MENU_CACHE ) )
|
||||
{
|
||||
$createMenu = array();
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'CreateMenu', $this ) as $ext )
|
||||
@@ -2355,9 +2500,9 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML for search results
|
||||
* Get HTML for search result display
|
||||
*
|
||||
* @return string
|
||||
* @return callable
|
||||
*/
|
||||
public function searchResultHtml()
|
||||
{
|
||||
@@ -2768,6 +2913,11 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Posts Per Day Storage
|
||||
*/
|
||||
protected $_ppdLimit = NULL;
|
||||
|
||||
/**
|
||||
* Check posts per day to see if this member can post.
|
||||
*
|
||||
@@ -2775,6 +2925,11 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function checkPostsPerDay()
|
||||
{
|
||||
/* Fetch our PPD limit - we should only need to do this once */
|
||||
if ( $this->_ppdLimit === NULL )
|
||||
{
|
||||
$this->_ppdLimit = $this->group['g_ppd_limit'];
|
||||
}
|
||||
/* We can't actually check guests as we can't store how often they have posted - simply counting content is not viable */
|
||||
if ( ! $this->member_id )
|
||||
{
|
||||
@@ -2782,7 +2937,7 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
|
||||
/* Is there any limit at all? */
|
||||
if ( ! $this->group['g_ppd_limit'] )
|
||||
if ( ! $this->_ppdLimit )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2806,7 +2961,7 @@ class _Member extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
|
||||
/* Still within 24 hours... have we hit the limit? */
|
||||
if ( $count > $this->group['g_ppd_limit'] )
|
||||
if ( $count >= $this->_ppdLimit )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user