Version 4.7.0
This commit is contained in:
1 parent
517a5e1f70
commit
8ba7d43898
1933 files changed
+65613
-11332
No files matched your search
@@ -68,6 +68,7 @@ class _Badge extends \IPS\Node\Model
|
||||
'app' => 'core',
|
||||
'module' => 'achievements',
|
||||
'prefix' => 'badges_',
|
||||
'all' => 'badges_manage',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -135,8 +136,11 @@ class _Badge extends \IPS\Node\Model
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
/* Allow SVGs without the obscure hash removing the file extension */
|
||||
\IPS\File::$safeFileExtensions[] = 'svg';
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'badge_name', NULL, TRUE, array( 'app' => 'core', 'key' => ( $this->id ? "core_badges_{$this->id}" : NULL ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'badge_image', $this->image ? \IPS\File::get( 'core_Badges', $this->image ) : NULL, TRUE, array( 'obscure' => FALSE, 'checkImage' => TRUE, 'allowedFileTypes' => array_merge( \IPS\Image::$imageExtensions, ['svg'] ), 'storageExtension' => 'core_Badges', 'allowStockPhotos' => FALSE ), function( $val ) {
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'badge_image', $this->image ? \IPS\File::get( 'core_Badges', $this->image ) : NULL, TRUE, array( 'obscure' => TRUE, 'checkImage' => TRUE, 'allowedFileTypes' => array_merge( \IPS\Image::supportedExtensions(), ['svg'] ), 'storageExtension' => 'core_Badges', 'allowStockPhotos' => FALSE ), function( $val ) {
|
||||
if( !$val )
|
||||
{
|
||||
throw new \DomainException('achievements_bad_image');
|
||||
@@ -228,12 +232,47 @@ class _Badge extends \IPS\Node\Model
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$stats = $this->getBadgeStats();
|
||||
|
||||
return ( 100 / $stats['memberCount'] * $stats['badgeCount'][ $this->id ] ) < \IPS\Settings::i()->rare_badge_percent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of people who have this badge
|
||||
*
|
||||
* @param bool|null $roundUp Round number to nearest 100 to be less specific
|
||||
* @return int
|
||||
*/
|
||||
public function ownedByCount( bool $roundUp=FALSE )
|
||||
{
|
||||
if ( $stats = $this->getBadgeStats() and isset( $stats['badgeCount'][ $this->id ] ) )
|
||||
{
|
||||
if ( $roundUp )
|
||||
{
|
||||
return ceil( $stats['badgeCount'][$this->id] / 100 ) * 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $stats['badgeCount'][ $this->id ];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statistics for this badge
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getBadgeStats(): ?array
|
||||
{
|
||||
/* Fetch the counts we need from the datastore. If they are old or non-existent, refresh and store in datastore for next time. */
|
||||
$stats = NULL;
|
||||
|
||||
if( isset( \IPS\Data\Store::i()->badgeRarityStats ) )
|
||||
if( isset( \IPS\Data\Store::i()->badgeStats ) )
|
||||
{
|
||||
$stats = json_decode( \IPS\Data\Store::i()->badgeRarityStats, true );
|
||||
$stats = json_decode( \IPS\Data\Store::i()->badgeStats, true );
|
||||
|
||||
if( !isset( $stats['expiration'] ) OR time() > $stats['expiration'] OR !isset( $stats['badgeCount'][ $this->id ] ) )
|
||||
{
|
||||
@@ -243,21 +282,38 @@ class _Badge extends \IPS\Node\Model
|
||||
|
||||
if( $stats === NULL )
|
||||
{
|
||||
$exclude = json_decode( \IPS\Settings::i()->rules_exclude_groups, TRUE );
|
||||
$where = [ [ 'completed=?', true ] ];
|
||||
$subQuery = NULL;
|
||||
|
||||
if ( \is_array( $exclude ) and \count( $exclude ) )
|
||||
{
|
||||
$subQuery = \IPS\Db::i()->select( 'member_id', 'core_members', [ \IPS\Db::i()->in( 'member_group_id', $exclude ) ] );
|
||||
$where[] = [ \IPS\Db::i()->in( 'member_group_id', $exclude, TRUE ) ];
|
||||
}
|
||||
|
||||
$stats = array(
|
||||
'expiration' => time() + 3600, // Cache for 60 minutes
|
||||
'memberCount' => \IPS\Db::i()->select( 'COUNT(*)', 'core_members', [ 'completed=?', true ] )->first(),
|
||||
'expiration' => time() + ( 3600 * 6 ), // Cache for 6 hours
|
||||
'memberCount' => \IPS\Db::i()->select( 'COUNT(*)', 'core_members', $where )->first(),
|
||||
'badgeCount' => array(),
|
||||
);
|
||||
|
||||
foreach( \IPS\Db::i()->select( 'id', 'core_badges' ) as $badgeId )
|
||||
{
|
||||
$stats['badgeCount'][ $badgeId ] = \IPS\Db::i()->select( 'COUNT(*)', 'core_member_badges', [ 'badge=?', $badgeId ] )->first();
|
||||
$where = [ [ 'badge=?', $badgeId ] ];
|
||||
|
||||
if ( \is_array( $exclude ) and \count( $exclude ) )
|
||||
{
|
||||
$where[] = [ \IPS\Db::i()->in( 'core_member_badges.member', $subQuery, TRUE ) ];
|
||||
}
|
||||
|
||||
$stats['badgeCount'][ $badgeId ] = \IPS\Db::i()->select( 'COUNT(*)', 'core_member_badges', $where )->first();
|
||||
}
|
||||
|
||||
\IPS\Data\Store::i()->badgeRarityStats = json_encode( $stats );
|
||||
\IPS\Data\Store::i()->badgeStats = json_encode( $stats );
|
||||
}
|
||||
|
||||
return ( 100 / $stats['memberCount'] * $stats['badgeCount'][ $this->id ] ) < \IPS\Settings::i()->rare_badge_percent;
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,4 +500,24 @@ class _Badge extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output for API
|
||||
*
|
||||
* @param \IPS\Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @return array
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string name Name
|
||||
* @apiresponse array statistcs Badge Statistics
|
||||
*/
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
{
|
||||
$return = array(
|
||||
'id' => $this->id,
|
||||
'name' => $this->_title,
|
||||
'statistics' => $this->getBadgeStats(),
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user