Version 5.0.0 beta 1

This commit is contained in:
Neo committed 2025-12-19 16:27:35 -08:00
1 parent 25ddeb65d6
commit 15c7beabc5
6736 files changed
+627902 -497943

No files matched your search

+58 -41
View File
@@ -11,48 +11,65 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\Achievements\Badge;
use IPS\core\Achievements\Rank;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\CheckboxSet;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Translatable;
use IPS\Lang;
use IPS\Member;
use IPS\Member\Group;
use IPS\Settings;
use IPS\Widget\Customizable;
use IPS\Widget\StaticCache;
use OutOfRangeException;
use function count;
use function defined;
use function in_array;
use function is_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* achievements Widget
*/
class _achievements extends \IPS\Widget\StaticCache
class achievements extends StaticCache implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'achievements';
public string $key = 'achievements';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Translatable( 'widget_feed_title', isset( $this->configuration['language_key'] ) ? NULL : \IPS\Member::loggedIn()->language()->addToStack( 'achievements_widget_title' ), FALSE, array( 'app' => 'core', 'key' => ( isset( $this->configuration['language_key'] ) ? $this->configuration['language_key'] : NULL ) ) ) );
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'achievements_to_show', isset( $this->configuration['achievements_to_show'] ) ? explode( ',', $this->configuration['achievements_to_show'] ) : [ 'badges', 'ranks' ], TRUE, [ 'options' => [
$form->add( new Translatable( 'widget_feed_title', isset( $this->configuration['language_key'] ) ? NULL : Member::loggedIn()->language()->addToStack( 'achievements_widget_title' ), FALSE, array( 'app' => 'core', 'key' => ( $this->configuration['language_key'] ?? NULL ) ) ) );
$form->add( new CheckboxSet( 'achievements_to_show', isset( $this->configuration['achievements_to_show'] ) ? explode( ',', $this->configuration['achievements_to_show'] ) : [ 'badges', 'ranks' ], TRUE, [ 'options' => [
'badges' => 'block_achievements_badges',
'ranks' => 'block_achievements_rank',
] ] ) );
$form->add( new \IPS\Helpers\Form\Number( 'number_to_show', isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 5, TRUE, array( 'max' => 25 ) ) );
$form->add( new Number( 'number_to_show', $this->configuration['number_to_show'] ?? 5, TRUE, array( 'max' => 25 ) ) );
return $form;
}
@@ -62,14 +79,14 @@ class _achievements extends \IPS\Widget\StaticCache
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
if ( !isset( $this->configuration['language_key'] ) )
{
$this->configuration['language_key'] = 'widget_title_' . md5( mt_rand() );
}
$values['language_key'] = $this->configuration['language_key'];
\IPS\Lang::saveCustom( 'core', $this->configuration['language_key'], $values['widget_feed_title'] );
Lang::saveCustom( 'core', $this->configuration['language_key'], $values['widget_feed_title'] );
unset( $values['widget_feed_title'] );
$values['achievements_to_show'] = implode( ',', $values['achievements_to_show'] );
@@ -81,14 +98,14 @@ class _achievements extends \IPS\Widget\StaticCache
*
* @return string
*/
public function render()
public function render(): string
{
$result = [];
$toShow = explode( ',', ( $this->configuration['achievements_to_show'] ?? 'badges,ranks' ) );
$countToShow = $this->configuration['number_to_show'] ?? 5;
$exclude = json_decode( \IPS\Settings::i()->rules_exclude_groups, TRUE );
$exclude = json_decode( Settings::i()->rules_exclude_groups, TRUE );
foreach( \IPS\Member\Group::groups() as $group )
foreach( Group::groups() as $group )
{
if( ! $group->g_view_board )
{
@@ -96,74 +113,74 @@ class _achievements extends \IPS\Widget\StaticCache
}
}
if ( \is_array( $exclude ) and \count( $exclude ) )
if ( is_array( $exclude ) and count( $exclude ) )
{
$subWhere[] = [ \IPS\Db::i()->in( 'member_group_id', $exclude ) . ' OR ' . \IPS\Db::i()->findInSet( 'mgroup_others', $exclude ) ];
$subWhere[] = [ Db::i()->in( 'member_group_id', $exclude ) . ' OR ' . Db::i()->findInSet( 'mgroup_others', $exclude ) ];
}
$subWhere[] = [ 'temp_ban != 0 OR ' . \IPS\Db::i()->bitwiseWhere( \IPS\Member::$bitOptions['members_bitoptions'], 'bw_is_spammer' ) ];
$subQuery = \IPS\Db::i()->select( 'member_id', 'core_members', $subWhere );
$subWhere[] = [ 'temp_ban != 0 OR ' . Db::i()->bitwiseWhere( Member::$bitOptions['members_bitoptions'], 'bw_is_spammer' ) ];
$subQuery = Db::i()->select( 'member_id', 'core_members', $subWhere );
if ( \IPS\core\Achievements\Badge::show() and \in_array( 'badges', $toShow ) )
if ( Badge::show() and in_array( 'badges', $toShow ) )
{
foreach ( \IPS\Db::i()->select( '*', 'core_member_badges', ( $subQuery ? [ \IPS\Db::i()->in( 'core_member_badges.member', $subQuery, TRUE ) ] : NULL ), 'datetime DESC', $countToShow )->join( 'core_badges', 'core_member_badges.badge=core_badges.id' ) as $earnedBadge )
foreach ( Db::i()->select( '*', 'core_member_badges', ( $subQuery ? [ Db::i()->in( 'core_member_badges.member', $subQuery, TRUE ) ] : NULL ), 'datetime DESC', $countToShow )->join( 'core_badges', 'core_member_badges.badge=core_badges.id' ) as $earnedBadge )
{
try
{
$member = \IPS\Member::load( $earnedBadge['member'] );
$member = Member::load( $earnedBadge['member'] );
if ( !$member->member_id )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
$result[] = [
'type' => 'badge',
'badge' => \IPS\core\Achievements\Badge::constructFromData( $earnedBadge ),
'badge' => Badge::constructFromData( $earnedBadge ),
'member' => $member,
'date' => $earnedBadge['datetime']
];
}
catch ( \OutOfRangeException $e ) { }
catch ( OutOfRangeException $e ) { }
}
}
if ( \IPS\core\Achievements\Rank::show() and \in_array( 'ranks', $toShow ) )
if ( Rank::show() and in_array( 'ranks', $toShow ) )
{
$query = [ [ 'new_rank IS NOT NULL' ] ];
if ( $subQuery )
{
$query[] = [ \IPS\Db::i()->in( 'core_points_log.member', $subQuery, TRUE ) ];
$query[] = [ Db::i()->in( 'core_points_log.member', $subQuery, TRUE ) ];
}
foreach ( \IPS\Db::i()->select( '*', 'core_points_log', $query, 'datetime DESC', $countToShow ) as $earnedRank )
foreach ( Db::i()->select( '*', 'core_points_log', $query, 'datetime DESC', $countToShow ) as $earnedRank )
{
try
{
$member = \IPS\Member::load( $earnedRank['member'] );
$member = Member::load( $earnedRank['member'] );
if ( !$member->member_id )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
$result[] = [
'type' => 'rank',
'rank' => \IPS\core\Achievements\Rank::load( $earnedRank['new_rank'] ),
'rank' => Rank::load( $earnedRank['new_rank'] ),
'member' => $member,
'date' => $earnedRank['datetime']
];
}
catch ( \OutOfRangeException $e ) { }
catch ( OutOfRangeException $e ) { }
}
}
if ( ( \IPS\core\Achievements\Badge::show() and \in_array( 'badges', $toShow ) ) and ( \IPS\core\Achievements\Rank::show() and \in_array( 'ranks', $toShow ) ) )
if ( ( Badge::show() and in_array( 'badges', $toShow ) ) and ( Rank::show() and in_array( 'ranks', $toShow ) ) )
{
usort( $result, function( $a, $b ) { return $b['date'] <=> $a['date']; } );
$result = array_splice( $result, 0, $countToShow );
}
return $result ? $this->output( $result, isset( $this->configuration['language_key'] ) ? \IPS\Member::loggedIn()->language()->addToStack( $this->configuration['language_key'], FALSE, array( 'escape' => TRUE ) ) : \IPS\Member::loggedIn()->language()->addToStack( 'achievements_widget_title' ) ) : '';
return $result ? $this->output( $result, isset( $this->configuration['language_key'] ) ? Member::loggedIn()->language()->addToStack( $this->configuration['language_key'], FALSE, array( 'escape' => TRUE ) ) : Member::loggedIn()->language()->addToStack( 'achievements_widget_title' ) ) : '';
}
/**
@@ -171,8 +188,8 @@ class _achievements extends \IPS\Widget\StaticCache
*
* @return void
*/
public function delete()
public function delete() : void
{
\IPS\Lang::deleteCustom( 'core', $this->configuration['language_key'] );
Lang::deleteCustom( 'core', $this->configuration['language_key'] );
}
}
+49 -47
View File
@@ -11,59 +11,77 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application\Module;
use IPS\Dispatcher;
use IPS\Member;
use IPS\Member\Group;
use IPS\Output;
use IPS\Request;
use IPS\Session\Store;
use IPS\Settings;
use IPS\Theme;
use IPS\Widget\StaticCache;
use function array_slice;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* activeUsers Widget
*/
class _activeUsers extends \IPS\Widget\PermissionCache
class activeUsers extends StaticCache
{
/**
* @brief Widget Key
*/
public $key = 'activeUsers';
public string $key = 'activeUsers';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* @brief Cache Expiration
* @note We only let this cache be valid for up to 60 seconds
*/
public $cacheExpiration = 60;
public int $cacheExpiration = 60;
/**
* @var string
*/
protected string $url = '';
/**
* Constructor
*
* @param String $uniqueKey Unique key for this specific instance
* @param String $uniqueKey Unique key for this specific instance
* @param array $configuration Widget custom configuration
* @param null|string|array $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param null|string $orientation Orientation (top, bottom, right, left)
* @param array|string|null $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param string|null $orientation Orientation (top, bottom, right, left)
* @param string $layout
* @return void
*/
public function __construct( $uniqueKey, array $configuration, $access=null, $orientation=null )
public function __construct(string $uniqueKey, array $configuration, array|string $access=null, string $orientation=null, string $layout='table' )
{
parent::__construct( $uniqueKey, $configuration, $access, $orientation );
parent::__construct( $uniqueKey, $configuration, $access, $orientation, $layout );
$member = \IPS\Member::loggedIn() ?: new \IPS\Member;
$member = Member::loggedIn() ?: new Member;
/* We can't run the URL related logic if we have no dispatcher because this class could also be initialized by the CLI cron job */
if( \IPS\Dispatcher::hasInstance() )
if( Dispatcher::hasInstance() )
{
$parts = parse_url( (string) \IPS\Request::i()->url()->setPage() );
$parts = parse_url( (string) Request::i()->url()->setPage() );
if ( \IPS\Settings::i()->htaccess_mod_rewrite )
if ( Settings::i()->htaccess_mod_rewrite )
{
$this->url = $parts['scheme'] . "://" . $parts['host'] . ( isset( $parts['port'] ) ? ':' . $parts['port'] : '' ) . $parts['path'];
}
@@ -74,30 +92,14 @@ class _activeUsers extends \IPS\Widget\PermissionCache
if( $member->member_id AND !$member->isOnlineAnonymously() )
{
\IPS\Output::i()->jsVars['member_id'] = $member->member_id;
\IPS\Output::i()->jsVars['member_url'] = (string) $member->url();
\IPS\Output::i()->jsVars['member_hovercardUrl'] = (string) $member->url()->setQueryString( 'do', 'hovercard' );
\IPS\Output::i()->jsVars['member_formattedName'] = str_replace( '"', '\\"', \IPS\Member\Group::load( $member->member_group_id )->formatName( $member->name ) );
Output::i()->jsVars['member_id'] = $member->member_id;
Output::i()->jsVars['member_url'] = (string) $member->url();
Output::i()->jsVars['member_hovercardUrl'] = (string) $member->url()->setQueryString( 'do', 'hovercard' );
Output::i()->jsVars['member_formattedName'] = str_replace( '"', '\\"', Group::load( $member->member_group_id )->formatName( $member->name ) );
}
/* We want to use the user's permissions array which will validate social groups, clubs and groups. But, we need to remove the individual member entry */
$member = \IPS\Member::loggedIn() ?: new \IPS\Member;
$permissions = $member->permissionArray();
foreach( $permissions as $key => $entry )
{
if( mb_substr( $entry, 0, 1 ) === 'm' )
{
unset( $permissions[ $key ] );
break;
}
}
/* We sort to ensure the array is always in the same order */
sort( $permissions );
$theme = $member->skin ?: \IPS\Theme::defaultTheme();
$this->cacheKey = "widget_{$this->key}_" . $this->uniqueKey . '_' . md5( $this->url . '_' . json_encode( $configuration ) . "_" . $member->language()->id . "_" . $theme . "_" . json_encode( $permissions ) . $orientation . '-' . (int) \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members', 'front' ) ) );
$theme = $member->skin ?: Theme::defaultTheme();
$this->cacheKey = "widget_{$this->key}_" . $this->uniqueKey . '_' . md5( $this->url . '_' . json_encode( $configuration ) . "_" . $member->language()->id . "_" . $theme . "_" . $orientation . '-' . (int) Member::loggedIn()->canAccessModule( Module::get( 'core', 'members', 'front' ) ) );
}
}
@@ -106,22 +108,22 @@ class _activeUsers extends \IPS\Widget\PermissionCache
*
* @return string
*/
public function render()
public function render(): string
{
/* Do we have permission? */
if ( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'online', 'front' ) ) )
if ( !Member::loggedIn()->canAccessModule( Module::get( 'core', 'online', 'front' ) ) )
{
return "";
}
$members = \IPS\Session\Store::i()->getOnlineMembersByLocation( \IPS\Dispatcher::i()->application->directory, \IPS\Dispatcher::i()->module->key, \IPS\Dispatcher::i()->controller, \IPS\Request::i()->id, $this->url );
$members = Store::i()->getOnlineMembersByLocation( Dispatcher::i()->application->directory, Dispatcher::i()->module->key, Dispatcher::i()->controller, Request::i()->id, $this->url );
$memberCount = \count( $members );
$memberCount = count( $members );
/* If it's on the sidebar (rather than at the bottom), we want to limit it to 60 so we don't take too much space */
if ( $this->orientation === 'vertical' and \count( $members ) >= 60 )
if ( $this->orientation === 'vertical' and count( $members ) >= 60 )
{
$members = \array_slice( $members, 0, 60 );
$members = array_slice( $members, 0, 60 );
}
/* Display */
@@ -0,0 +1,130 @@
<?php
/**
* @brief advertisements Widget
* @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
{subpackage}
* @since 27 Nov 2023
*/
namespace IPS\core\widgets;
use IPS\Application;
use IPS\core\Advertisement;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Node;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Select;
use IPS\Node\Model;
use IPS\Widget;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* advertisements Widget
*/
class advertisements extends Widget
{
/**
* @brief Widget Key
*/
public string $key = 'advertisements';
/**
* @brief App
*/
public string $app = 'core';
/**
* Specify widget configuration
*
* @param null|Form $form Form object
* @return Form
*/
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$ads = [];
foreach( Db::i()->select( 'ad_id', 'core_advertisements', [ 'ad_type!=?', Advertisement::AD_EMAIL ] ) as $adId )
{
$ads[$adId] = 'core_advert_' . $adId;
}
if( !count( $ads ) )
{
return $form;
}
$form->add( new Select( 'widget_ads', $this->configuration['widget_ads'] ?? -1, false, [
'options' => $ads,
'multiple' => true,
'noDefault' => true,
'unlimited' => -1,
'unlimitedLang' => 'any'
] ) );
if( Application::appIsEnabled( 'nexus' ) )
{
/* Do we have any advertising packages configured? */
$count = (int) Db::i()->select( 'count(*)', 'nexus_packages', [ 'p_type=?', 'ad' ] )->first();
if( $count )
{
$form->add( new Node( 'widget_ad_package', $this->configuration['widget_ad_package'] ?? null, false, [
'class' => 'IPS\nexus\Package',
'multiple' => false,
'where' => [ 'p_type=?', 'ad' ]
] ) );
}
}
$form->add( new Number( 'widget_ad_limit', $this->configuration['widget_ad_limit'] ?? 1, false ) );
return $form;
}
/**
* Ran before saving widget configuration
*
* @param array $values Values from form
* @return array
*/
public function preConfig( array $values ): array
{
$values['widget_ad_package'] = ( isset( $values['widget_ad_package'] ) and $values['widget_ad_package'] instanceof Model ) ? $values['widget_ad_package']->_id : null;
return $values;
}
/**
* Render a widget
*
* @return string
*/
public function render(): string
{
$ids = ( isset( $this->configuration['widget_ads'] ) and $this->configuration['widget_ads'] != -1 ) ? $this->configuration['widget_ads'] : [];
/* Do we have a specific Commerce package selected? Get those ads */
if( isset( $this->configuration['widget_ad_package'] ) and Application::appIsEnabled( 'nexus' ) )
{
foreach( Db::i()->select( 'ps_extra', 'nexus_purchases', [ 'ps_app=? and ps_type=? and ps_item_id=? and ps_active=?', 'nexus', 'package', $this->configuration['widget_ad_package'], 1 ] ) as $data )
{
if( $extra = json_decode( $data, true ) )
{
$ids[] = $extra['ad'];
}
}
}
return $this->output( Advertisement::loadForWidget( array(), ( count( $ids ) ? $ids : null ), ( $this->configuration['widget_ad_limit'] ?? null ) ) );
}
}
+57 -52
View File
@@ -11,50 +11,64 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application\Module;
use IPS\Helpers\Form;
use IPS\Helpers\Form\CheckboxSet;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\Translatable;
use IPS\Lang;
use IPS\Member;
use IPS\Member\Club;
use IPS\Member\Club\CustomField;
use IPS\Settings;
use IPS\Widget;
use IPS\Widget\Customizable;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Clubs Widget
*/
class _clubs extends \IPS\Widget
class clubs extends Widget implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'clubs';
public string $key = 'clubs';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Translatable( 'widget_feed_title', isset( $this->configuration['language_key'] ) ? NULL : \IPS\Member::loggedIn()->language()->addToStack( 'my_clubs' ), FALSE, array( 'app' => 'core', 'key' => ( isset( $this->configuration['language_key'] ) ? $this->configuration['language_key'] : NULL ) ) ) );
$form->add( new Translatable( 'widget_feed_title', isset( $this->configuration['language_key'] ) ? NULL : Member::loggedIn()->language()->addToStack( 'my_clubs' ), FALSE, array( 'app' => 'core', 'key' => ( $this->configuration['language_key'] ?? NULL ) ) ) );
$form->add( new \IPS\Helpers\Form\Radio( 'club_filter_type', isset( $this->configuration['club_filter_type'] ) ? $this->configuration['club_filter_type'] : 'mine', TRUE, array( 'options' => array(
$form->add( new Radio( 'club_filter_type', $this->configuration['club_filter_type'] ?? 'mine', TRUE, array( 'options' => array(
'mine' => 'user_clubs',
'all' => 'all_clubs',
) ) ) );
$fields = \IPS\Member\Club\CustomField::roots();
$fields = CustomField::roots();
foreach ( $fields as $field )
{
if ( $field->filterable )
@@ -63,7 +77,7 @@ class _clubs extends \IPS\Widget
{
case 'Checkbox':
case 'YesNo':
$input = new \IPS\Helpers\Form\CheckboxSet( 'field_' . $field->id, isset( $this->configuration['filters'][ $field->id ] ) ? $this->configuration['filters'][ $field->id ] : array( 1, 0 ), FALSE, array( 'options' => array(
$input = new CheckboxSet( 'field_' . $field->id, isset( $this->configuration['filters'][ $field->id ] ) ? $this->configuration['filters'][ $field->id ] : array( 1, 0 ), FALSE, array( 'options' => array(
1 => 'yes',
0 => 'no',
) ) );
@@ -75,7 +89,7 @@ class _clubs extends \IPS\Widget
case 'Radio':
case 'Select':
$options = json_decode( $field->extra, TRUE );
$input = new \IPS\Helpers\Form\CheckboxSet( 'field_' . $field->id, isset( $this->configuration['filters'][ $field->id ] ) ? $this->configuration['filters'][ $field->id ] : array_keys( $options ), FALSE, array( 'options' => $options ) );
$input = new CheckboxSet( 'field_' . $field->id, isset( $this->configuration['filters'][ $field->id ] ) ? $this->configuration['filters'][ $field->id ] : array_keys( $options ), FALSE, array( 'options' => $options ) );
$input->label = $field->_title;
$form->add( $input );
break;
@@ -83,13 +97,13 @@ class _clubs extends \IPS\Widget
}
}
$form->add( new \IPS\Helpers\Form\Radio( 'sort_by', isset( $this->configuration['sort_by'] ) ? $this->configuration['sort_by'] : 'last_activity', TRUE, array( 'options' => array(
$form->add( new Radio( 'sort_by', $this->configuration['sort_by'] ?? 'last_activity', TRUE, array( 'options' => array(
'last_activity' => 'clubs_sort_last_activity',
'members' => 'clubs_sort_members',
'content' => 'clubs_sort_content',
'created' => 'clubs_sort_created',
) ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'number_to_show', isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 10, TRUE ) );
$form->add( new Number( 'number_to_show', $this->configuration['number_to_show'] ?? 10, TRUE ) );
return $form;
}
@@ -99,17 +113,17 @@ class _clubs extends \IPS\Widget
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
if ( !isset( $this->configuration['language_key'] ) )
{
$this->configuration['language_key'] = 'widget_title_' . md5( mt_rand() );
}
$values['language_key'] = $this->configuration['language_key'];
\IPS\Lang::saveCustom( 'core', $this->configuration['language_key'], $values['widget_feed_title'] );
Lang::saveCustom( 'core', $this->configuration['language_key'], $values['widget_feed_title'] );
unset( $values['widget_feed_title'] );
$fields = \IPS\Member\Club\CustomField::roots();
$fields = CustomField::roots();
foreach ( $fields as $field )
{
if ( $field->filterable )
@@ -118,7 +132,7 @@ class _clubs extends \IPS\Widget
{
case 'Checkbox':
case 'YesNo':
if ( \count( $values[ 'field_' . $field->id ] ) === 1 )
if ( count( $values[ 'field_' . $field->id ] ) === 1 )
{
$values['filters'][ $field->id ] = array_pop( $values[ 'field_' . $field->id ] );
}
@@ -129,12 +143,12 @@ class _clubs extends \IPS\Widget
case 'Radio':
case 'Select':
$options = json_decode( $field->extra, TRUE );
if ( \count( $values[ 'field_' . $field->id ] ) > 0 and \count( $values[ 'field_' . $field->id ] ) < \count( $options ) )
if ( count( $values[ 'field_' . $field->id ] ) > 0 and count( $values[ 'field_' . $field->id ] ) < count( $options ) )
{
$values['filters'][ $field->id ] = array();
foreach ( $values[ 'field_' . $field->id ] as $v )
{
$values['filters'][ $field->id ][] = $options[ $v ];
$values['filters'][ $field->id ][] = $v;
}
}
unset( $values[ 'field_' . $field->id ] );
@@ -151,47 +165,38 @@ class _clubs extends \IPS\Widget
*
* @return string
*/
public function render()
public function render(): string
{
if ( \IPS\Settings::i()->clubs and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'clubs', 'front' ) ) )
if( !Member::loggedIn()->member_id and $this->configuration['club_filter_type'] == 'mine' )
{
/* Strip any not existing custom field filters, e.g. when a field was deleted */
if ( isset( $this->configuration['filters'] ) and \is_array( $this->configuration['filters'] ) )
{
$fields = \IPS\Member\Club\CustomField::roots();
foreach ( $this->configuration['filters'] as $key => $value )
{
if( !isset( $fields[ $key ] ) )
{
unset( $this->configuration['filters'][ $key ] );
}
}
}
$clubsCount = \IPS\Member\Club::clubs(
\IPS\Member::loggedIn(),
isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 10,
isset( $this->configuration['sort_by'] ) ? $this->configuration['sort_by'] : 'last_activity',
return '';
}
if ( Settings::i()->clubs and Member::loggedIn()->canAccessModule( Module::get( 'core', 'clubs', 'front' ) ) )
{
$clubsCount = Club::clubs(
Member::loggedIn(),
$this->configuration['number_to_show'] ?? 10,
$this->configuration['sort_by'] ?? 'last_activity',
!isset( $this->configuration['club_filter_type'] ) or $this->configuration['club_filter_type'] == 'mine',
isset( $this->configuration['filters'] ) ? $this->configuration['filters'] : array(),
$this->configuration['filters'] ?? array(),
NULL,
TRUE
);
if ( $clubsCount )
{
$clubs = \IPS\Member\Club::clubs(
\IPS\Member::loggedIn(),
isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 10,
isset( $this->configuration['sort_by'] ) ? $this->configuration['sort_by'] : 'last_activity',
$clubs = Club::clubs(
Member::loggedIn(),
$this->configuration['number_to_show'] ?? 10,
$this->configuration['sort_by'] ?? 'last_activity',
!isset( $this->configuration['club_filter_type'] ) or $this->configuration['club_filter_type'] == 'mine',
isset( $this->configuration['filters'] ) ? $this->configuration['filters'] : array()
$this->configuration['filters'] ?? array()
);
return $this->output(
$clubs,
isset( $this->configuration['language_key'] ) ? \IPS\Member::loggedIn()->language()->addToStack( $this->configuration['language_key'], FALSE, array( 'escape' => TRUE ) ) : \IPS\Member::loggedIn()->language()->addToStack( 'my_clubs' ),
$this->orientation
isset( $this->configuration['language_key'] ) ? Member::loggedIn()->language()->addToStack( $this->configuration['language_key'], FALSE, array( 'escape' => TRUE ) ) : Member::loggedIn()->language()->addToStack( 'my_clubs' )
);
}
}
+53 -42
View File
@@ -11,70 +11,81 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Db;
use IPS\File;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Translatable;
use IPS\Http\Url;
use IPS\Lang;
use IPS\Login;
use IPS\Member;
use IPS\Widget;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* guestSignUp Widget
*/
class _guestSignUp extends \IPS\Widget
class guestSignUp extends Widget
{
/**
* @brief Widget Key
*/
public $key = 'guestSignUp';
public string $key = 'guestSignUp';
/**
* @brief Language String Key used to store the editor content
*/
public static $editorKey = 'block_guestsignup_message';
public static string $editorKey = 'block_guestsignup_message';
/**
* @brief Language Key used to save the content
*/
public static $editorLangKey = 'widget_guestsignup_text';
public static string $editorLangKey = 'widget_guestsignup_text';
/**
* @brief App
*/
public $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'core';
/**
* Constructor
*
* @param string $uniqueKey Unique key for this specific instance
* @param String $uniqueKey Unique key for this specific instance
* @param array $configuration Widget custom configuration
* @param null|string|array $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param null|string $orientation Orientation (top, bottom, right, left)
* @param array|string|null $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param string|null $orientation Orientation (top, bottom, right, left)
* @param string $layout
* @return void
*/
public function __construct( $uniqueKey, array $configuration, $access=null, $orientation=null )
public function __construct(string $uniqueKey, array $configuration, array|string $access=null, string $orientation=null, string $layout='table' )
{
parent::__construct($uniqueKey, $configuration, $access, $orientation);
parent::__construct($uniqueKey, $configuration, $access, $orientation, $layout);
$this->errorMessage = 'guest_signup_admin_message';
}
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Translatable( 'block_guestsignup_title', NULL, TRUE, array( 'app'=>'core', 'key' =>'widget_guestsignup_title' ) ) );
$form->add( new \IPS\Helpers\Form\Translatable( 'block_guestsignup_message', NULL, TRUE, array(
$form->add( new Translatable( 'block_guestsignup_title', NULL, TRUE, array( 'app'=>'core', 'key' =>'widget_guestsignup_title' ) ) );
$form->add( new Translatable( 'block_guestsignup_message', NULL, TRUE, array(
'app' => 'core',
'key' => static::$editorLangKey,
'editor' => array(
@@ -92,28 +103,28 @@ class _guestSignUp extends \IPS\Widget
*
* @return void
*/
public function delete()
public function delete() : void
{
\IPS\Lang::deleteCustom( 'core', 'widget_guestsignup_title' );
\IPS\Lang::deleteCustom( 'core', 'widget_guestsignup_text' );
Lang::deleteCustom( 'core', 'widget_guestsignup_title' );
Lang::deleteCustom( 'core', 'widget_guestsignup_text' );
foreach( \IPS\Db::i()->select( '*', 'core_attachments_map', array( array( 'location_key=?', 'core_GuestSignupWidget' ) ) ) as $map )
foreach( Db::i()->select( '*', 'core_attachments_map', array( array( 'location_key=?', 'core_GuestSignupWidget' ) ) ) as $map )
{
try
{
$attachment = \IPS\Db::i()->select( '*', 'core_attachments', array( 'attach_id=?', $map['attachment_id'] ) )->first();
$attachment = Db::i()->select( '*', 'core_attachments', array( 'attach_id=?', $map['attachment_id'] ) )->first();
\IPS\Db::i()->delete( 'core_attachments_map', array( array( 'attachment_id=?', $attachment['attach_id'] ) ) );
\IPS\Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
Db::i()->delete( 'core_attachments_map', array( array( 'attachment_id=?', $attachment['attach_id'] ) ) );
Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
\IPS\File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
if ( $attachment['attach_thumb_location'] )
{
\IPS\File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
}
}
catch ( \Exception $e ) { }
catch ( Exception $e ) { }
}
}
@@ -123,11 +134,11 @@ class _guestSignUp extends \IPS\Widget
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
\IPS\File::claimAttachments( 'widget-' . $this->uniqueKey, 0, 0, 'widget_guestsignup_text' );
\IPS\Lang::saveCustom( 'core', static::$editorLangKey, $values[ 'block_guestsignup_message' ] );
\IPS\Lang::saveCustom( 'core', 'widget_guestsignup_title', $values[ 'block_guestsignup_title' ] );
File::claimAttachments( 'widget-' . $this->uniqueKey, 0, 0, 'widget_guestsignup_text' );
Lang::saveCustom( 'core', static::$editorLangKey, $values[ 'block_guestsignup_message' ] );
Lang::saveCustom( 'core', 'widget_guestsignup_title', $values[ 'block_guestsignup_title' ] );
return $values;
}
@@ -136,23 +147,23 @@ class _guestSignUp extends \IPS\Widget
*
* @return string
*/
public function render()
public function render(): string
{
/* Show this only to guests */
if ( \IPS\Member::loggedIn()->member_id )
if ( Member::loggedIn()->member_id )
{
return '';
}
else
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'widget_guestsignup_title' );
$text = \IPS\Member::loggedIn()->language()->addToStack( 'widget_guestsignup_text' );
if ( !\IPS\Member::loggedIn()->language()->checkKeyExists( 'widget_guestsignup_title' ) )
$title = Member::loggedIn()->language()->addToStack( 'widget_guestsignup_title' );
$text = Member::loggedIn()->language()->addToStack( 'widget_guestsignup_text' );
if ( !Member::loggedIn()->language()->checkKeyExists( 'widget_guestsignup_title' ) )
{
return '';
}
$login = new \IPS\Login( \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) );
$login = new Login( Url::internal( 'app=core&module=system&controller=login', 'front', 'login' ) );
return $this->output( $login, $text, $title );
}
}
+22 -17
View File
@@ -11,41 +11,46 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Http\Url;
use IPS\Member;
use IPS\Settings;
use IPS\Theme;
use IPS\Widget;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* invite Widget
*/
class _invite extends \IPS\Widget
class invite extends Widget
{
/**
* @brief Widget Key
*/
public $key = 'invite';
public string $key = 'invite';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Initialise this widget
*
* @return void
*/
public function init()
public function init(): void
{
// Use this to perform any set up and to assign a template that is not in the following format:
$this->template( array( \IPS\Theme::i()->getTemplate( 'widgets', $this->app, 'front' ), $this->key ) );
$this->template( array( Theme::i()->getTemplate( 'widgets', $this->app, 'front' ), $this->key ) );
parent::init();
}
@@ -56,7 +61,7 @@ class _invite extends \IPS\Widget
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
return $values;
}
@@ -66,14 +71,14 @@ class _invite extends \IPS\Widget
*
* @return string
*/
public function render()
public function render(): string
{
$subject = \IPS\Member::loggedIn()->language()->addToStack('block_invite_subject', FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ), 'rawurlencode' => TRUE ) );
$url = \IPS\Http\Url::internal( "" );
$subject = Member::loggedIn()->language()->addToStack('block_invite_subject', FALSE, array( 'sprintf' => array( Settings::i()->board_name ), 'rawurlencode' => TRUE ) );
$url = Url::internal( "" );
if( \IPS\Settings::i()->ref_on and \IPS\Member::loggedIn()->member_id )
if( Settings::i()->ref_on and Member::loggedIn()->member_id )
{
$url = $url->setQueryString( array( '_rid' => \IPS\Member::loggedIn()->member_id ) );
$url = $url->setQueryString( array( '_rid' => Member::loggedIn()->member_id ) );
}
return $this->output( $subject, urlencode( $url ) );
+61 -44
View File
@@ -11,78 +11,95 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use DateInterval;
use IPS\Application;
use IPS\DateTime;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Checkbox;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\Select;
use IPS\Helpers\Form\Text;
use IPS\Helpers\Form\YesNo;
use IPS\Member;
use IPS\Member\Group;
use IPS\Patterns\ActiveRecordIterator;
use IPS\Widget\Customizable;
use IPS\Widget\StaticCache;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Members Widget
*/
class _members extends \IPS\Widget\StaticCache
class members extends StaticCache implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'members';
public string $key = 'members';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param \IPS\Helpers\Form|NULL $form Form helper
* @return null|\IPS\Helpers\Form
* @param Form|NULL $form Form helper
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
/* Block title */
$form->add( new \IPS\Helpers\Form\Text( 'widget_member_title', isset( $this->configuration['widget_member_title'] ) ? $this->configuration['widget_member_title'] : \IPS\Member::loggedIn()->language()->addToStack( 'widget_member_title_default' ) ) );
$form->add( new Text( 'widget_member_title', $this->configuration['widget_member_title'] ?? Member::loggedIn()->language()->addToStack( 'widget_member_title_default' ) ) );
$form->add( new \IPS\Helpers\Form\Select(
$form->add( new Select(
'widget_member_groups',
( isset( $this->configuration['widget_member_groups'] ) ) ? ( $this->configuration['widget_member_groups'] === '*' ? '*' : $this->configuration['widget_member_groups'] ) : '*',
FALSE,
array( 'options' => \IPS\Member\Group::groups(), 'multiple' => TRUE, 'parse' => 'normal', 'unlimited' => '*', 'unlimitedLang' => 'all' ),
array( 'options' => Group::groups(), 'multiple' => TRUE, 'parse' => 'normal', 'unlimited' => '*', 'unlimitedLang' => 'all' ),
NULL,
NULL,
NULL,
'widget_member_groups'
) );
$form->add( new \IPS\Helpers\Form\Checkbox( 'widget_member_secondary_groups', isset( $this->configuration['widget_member_secondary_groups'] ) ? $this->configuration['widget_member_secondary_groups'] : FALSE, FALSE ) );
$form->add( new Checkbox( 'widget_member_secondary_groups', $this->configuration['widget_member_secondary_groups'] ?? FALSE, FALSE ) );
$form->add( new \IPS\Helpers\Form\Number( 'widget_member_posts', isset( $this->configuration['widget_member_posts'] ) ? $this->configuration['widget_member_posts'] : 0, FALSE ) );
$form->add( new \IPS\Helpers\Form\Number( 'widget_member_rep' , isset( $this->configuration['widget_member_rep'] ) ? $this->configuration['widget_member_rep'] : 0, FALSE ) );
$form->add( new Number( 'widget_member_posts', $this->configuration['widget_member_posts'] ?? 0, FALSE ) );
$form->add( new Number( 'widget_member_rep' , $this->configuration['widget_member_rep'] ?? 0, FALSE ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'widget_member_online', isset( $this->configuration['widget_member_online'] ) ? $this->configuration['widget_member_online'] : TRUE, FALSE ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'widget_member_born_today', isset( $this->configuration['widget_member_born_today'] ) ? $this->configuration['widget_member_born_today'] : FALSE, FALSE ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'widget_member_born_month', isset( $this->configuration['widget_member_born_month'] ) ? $this->configuration['widget_member_born_month'] : FALSE, FALSE ) );
$form->add( new YesNo( 'widget_member_online', $this->configuration['widget_member_online'] ?? TRUE, FALSE ) );
$form->add( new YesNo( 'widget_member_born_today', $this->configuration['widget_member_born_today'] ?? FALSE, FALSE ) );
$form->add( new YesNo( 'widget_member_born_month', $this->configuration['widget_member_born_month'] ?? FALSE, FALSE ) );
if ( \IPS\Application::appIsEnabled('blog') )
if ( Application::appIsEnabled('blog') )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'widget_member_has_blog', isset( $this->configuration['widget_member_has_blog'] ) ? $this->configuration['widget_member_has_blog'] : FALSE, FALSE ) );
$form->add( new YesNo( 'widget_member_has_blog', $this->configuration['widget_member_has_blog'] ?? FALSE, FALSE ) );
}
if ( \IPS\Application::appIsEnabled('gallery') )
if ( Application::appIsEnabled('gallery') )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'widget_member_has_album', isset( $this->configuration['widget_member_has_album'] ) ? $this->configuration['widget_member_has_album'] : FALSE, FALSE ) );
$form->add( new YesNo( 'widget_member_has_album', $this->configuration['widget_member_has_album'] ?? FALSE, FALSE ) );
}
$form->add( new \IPS\Helpers\Form\Number( 'widget_member_show', ( isset( $this->configuration['widget_member_show'] ) and $this->configuration['widget_member_show'] != -1 ) ? $this->configuration['widget_member_show'] : 100, FALSE ) );
$form->add( new Number( 'widget_member_show', ( isset( $this->configuration['widget_member_show'] ) and $this->configuration['widget_member_show'] != -1 ) ? $this->configuration['widget_member_show'] : 100, FALSE ) );
$form->add( new \IPS\Helpers\Form\Select( 'widget_feed_sort_on', isset( $this->configuration['widget_feed_sort_on'] ) ? $this->configuration['widget_feed_sort_on'] : 'last_activity', FALSE, array( 'options' => array(
$form->add( new Select( 'widget_feed_sort_on', $this->configuration['widget_feed_sort_on'] ?? 'last_activity', FALSE, array( 'options' => array(
'name' => 'widget__sort_name',
'member_posts' => 'widget__sort_posts',
'joined' => 'widget__sort_joined',
@@ -92,16 +109,16 @@ class _members extends \IPS\Widget\StaticCache
'_age' => 'widget__sort_age',
'pp_reputation_points' => 'widget__sort_points',
'_random' => 'widget__sort_random'
) ) ), NULL, NULL, NULL, 'widget_feed_sort_on' );
) ), NULL, NULL, NULL, 'widget_feed_sort_on' ) );
$form->add( new \IPS\Helpers\Form\Select( 'widget_feed_sort_dir', isset( $this->configuration['widget_feed_sort_dir'] ) ? $this->configuration['widget_feed_sort_dir'] : 'desc', FALSE, array(
$form->add( new Select( 'widget_feed_sort_dir', $this->configuration['widget_feed_sort_dir'] ?? 'desc', FALSE, array(
'options' => array(
'desc' => 'descending',
'asc' => 'ascending'
)
) ) );
$form->add( new \IPS\Helpers\Form\Radio( 'widget_member_display', isset( $this->configuration['widget_member_display'] ) ? $this->configuration['widget_member_display'] : 'csv', FALSE, array(
$form->add( new Radio( 'widget_member_display', $this->configuration['widget_member_display'] ?? 'csv', FALSE, array(
'options' => array(
'csv' => 'widget__display_csv',
'list' => 'widget__display_list'
@@ -116,18 +133,18 @@ class _members extends \IPS\Widget\StaticCache
*
* @return string
*/
public function render()
public function render(): string
{
$where = array( array( 'completed=?', true ) );
$joins = array();
if ( ! empty( $this->configuration['widget_member_groups'] ) AND $this->configuration['widget_member_groups'] !== '*' )
{
$groupWhere = \IPS\Db::i()->in( 'member_group_id', $this->configuration['widget_member_groups'] );
$groupWhere = Db::i()->in( 'member_group_id', $this->configuration['widget_member_groups'] );
if ( ! empty( $this->configuration['widget_member_secondary_groups'] ) )
{
$groupWhere .= ' OR ' . \IPS\Db::i()->findInSet( 'mgroup_others', $this->configuration['widget_member_groups'] );
$groupWhere .= ' OR ' . Db::i()->findInSet( 'mgroup_others', $this->configuration['widget_member_groups'] );
}
$where[] = array( '(' . $groupWhere . ')' );
@@ -145,12 +162,12 @@ class _members extends \IPS\Widget\StaticCache
if ( ! empty( $this->configuration['widget_member_online'] ) OR !isset( $this->configuration['widget_member_online'] ) )
{
$where[] = array( 'last_activity > ?', \IPS\DateTime::create()->sub( new \DateInterval( 'PT30M' ) )->getTimeStamp() );
$where[] = array( 'last_activity > ?', DateTime::create()->sub( new DateInterval( 'PT30M' ) )->getTimeStamp() );
}
if ( ! empty( $this->configuration['widget_member_born_today'] ) )
{
$time = \IPS\DateTime::ts( time(), TRUE );
$time = DateTime::ts( time(), TRUE );
$mon = $time->format('n');
$mday = $time->format('j');
$year = $time->format('Y');
@@ -168,13 +185,13 @@ class _members extends \IPS\Widget\StaticCache
if ( ! empty( $this->configuration['widget_member_born_month'] ) )
{
$time = \IPS\DateTime::ts( time(), TRUE );
$time = DateTime::ts( time(), TRUE );
$mon = $time->format('n');
$where[] = array( 'bday_month=?', $mon );
}
if ( \IPS\Application::appIsEnabled('blog') and ! empty( $this->configuration['widget_member_has_blog'] ) )
if ( Application::appIsEnabled('blog') and ! empty( $this->configuration['widget_member_has_blog'] ) )
{
$joins['blog'] = array(
'select' => 'blog.blog_id',
@@ -183,7 +200,7 @@ class _members extends \IPS\Widget\StaticCache
);
}
if ( \IPS\Application::appIsEnabled('gallery') and ! empty( $this->configuration['widget_member_has_album'] ) )
if ( Application::appIsEnabled('gallery') and ! empty( $this->configuration['widget_member_has_album'] ) )
{
$joins['gallery'] = array(
'select' => 'gallery.album_id',
@@ -214,10 +231,10 @@ class _members extends \IPS\Widget\StaticCache
/* Exclude banned, validating and spammers */
$where[] = array( "core_members.temp_ban=0" );
$where[] = array( "core_members.email!=''" );
$where[] = array( '( ! ' . \IPS\Db::i()->bitwiseWhere( \IPS\Member::$bitOptions['members_bitoptions'], 'bw_is_spammer' ) . ' )' );
$where[] = array( '( ! ' . Db::i()->bitwiseWhere( Member::$bitOptions['members_bitoptions'], 'bw_is_spammer' ) . ' )' );
$where[] = array( "( core_validating.vid IS NULL ) " );
$select = \IPS\Db::i()->select(
$select = Db::i()->select(
'core_members.*',
'core_members',
$where,
@@ -227,20 +244,20 @@ class _members extends \IPS\Widget\StaticCache
$select->join( 'core_validating', 'core_validating.member_id=core_members.member_id AND core_validating.new_reg = 1' );
if ( \count( $joins ) )
if ( count( $joins ) )
{
foreach( $joins as $join )
{
$select->join( $join['from'], ( isset( $join['where'] ) ? $join['where'] : null ), 'STRAIGHT_JOIN' );
$select->join( $join['from'], ( $join['where'] ?? null ), 'STRAIGHT_JOIN' );
}
}
$members = new \IPS\Patterns\ActiveRecordIterator(
$members = new ActiveRecordIterator(
$select,
'\IPS\Member'
);
/* Display */
return $this->output( $members, isset( $this->configuration['widget_member_title'] ) ? $this->configuration['widget_member_title'] : \IPS\Member::loggedIn()->language()->addToStack( 'widget_member_title_default' ), isset( $this->configuration['widget_member_display'] ) ? $this->configuration['widget_member_display'] : 'csv' );
return $this->output( $members, $this->configuration['widget_member_title'] ?? Member::loggedIn()->language()->addToStack( 'widget_member_title_default' ), $this->configuration['widget_member_display'] ?? 'csv' );
}
}
+40 -39
View File
@@ -11,65 +11,66 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Select;
use IPS\Helpers\Form\Translatable;
use IPS\Lang;
use IPS\Member;
use IPS\Patterns\ActiveRecordIterator;
use IPS\Widget\Customizable;
use IPS\Widget\StaticCache;
use function count;
use function defined;
use function in_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* mostContributions Widget
*/
class _mostContributions extends \IPS\Widget\StaticCache
class mostContributions extends StaticCache implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'mostContributions';
public string $key = 'mostContributions';
/**
* @brief App
*/
public $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Initialise this widget
*
* @return void
*/
public function init()
{
parent::init();
}
public string $app = 'core';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
/* Block title */
$form->add( new \IPS\Helpers\Form\Translatable( 'widget_feed_title', isset( $this->configuration['language_key'] ) ? NULL : \IPS\Member::loggedIn()->language()->addToStack( 'block_mostContributions' ), FALSE, array( 'app' => 'core', 'key' => ( isset( $this->configuration['language_key'] ) ? $this->configuration['language_key'] : NULL ) ) ) );
$form->add( new Translatable( 'widget_feed_title', isset( $this->configuration['language_key'] ) ? NULL : Member::loggedIn()->language()->addToStack( 'block_mostContributions' ), FALSE, array( 'app' => 'core', 'key' => ( $this->configuration['language_key'] ?? NULL ) ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'number_to_show', isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 5, TRUE, array( 'max' => 25 ) ) );
$form->add( new Number( 'number_to_show', $this->configuration['number_to_show'] ?? 5, TRUE, array( 'max' => 25 ) ) );
/* What are we showing? */
$classes = array();
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter' ) as $contentRouter )
foreach ( Application::allExtensions( 'core', 'ContentRouter' ) as $contentRouter )
{
foreach ( $contentRouter->classes as $class )
{
$exploded = explode( '\\', $class );
if ( \in_array( 'IPS\Content\Item', class_parents( $class ) ) )
if ( in_array( 'IPS\Content\Item', class_parents( $class ) ) )
{
if ( $class::incrementPostCount() )
{
@@ -92,7 +93,7 @@ class _mostContributions extends \IPS\Widget\StaticCache
}
}
}
elseif ( \in_array( 'IPS\Content\Comment', class_parents( $class ) ) )
elseif ( in_array( 'IPS\Content\Comment', class_parents( $class ) ) )
{
if ( $class::incrementPostCount() )
{
@@ -120,7 +121,7 @@ class _mostContributions extends \IPS\Widget\StaticCache
}
}
$form->add( new \IPS\Helpers\Form\Select( 'most_contributions_area', isset( $this->configuration['most_contributions_area'] ) ? $this->configuration['most_contributions_area'] : "0", FALSE, array( 'options' => $options, 'multiple' => FALSE, 'unlimited' => '0', 'unlimitedLang' => "everything" ), NULL, NULL, NULL, 'most_contributions_area' ) );
$form->add( new Select( 'most_contributions_area', $this->configuration['most_contributions_area'] ?? "0", FALSE, array( 'options' => $options, 'multiple' => FALSE, 'unlimited' => '0', 'unlimitedLang' => "everything" ), NULL, NULL, NULL, 'most_contributions_area' ) );
return $form;
}
@@ -130,7 +131,7 @@ class _mostContributions extends \IPS\Widget\StaticCache
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
if ( !isset( $this->configuration['language_key'] ) )
{
@@ -138,7 +139,7 @@ class _mostContributions extends \IPS\Widget\StaticCache
}
$values['language_key'] = $this->configuration['language_key'];
\IPS\Lang::saveCustom( 'core', $this->configuration['language_key'], $values['widget_feed_title'] );
Lang::saveCustom( 'core', $this->configuration['language_key'], $values['widget_feed_title'] );
unset( $values['widget_feed_title'] );
return $values;
@@ -149,15 +150,15 @@ class _mostContributions extends \IPS\Widget\StaticCache
*
* @return string
*/
public function render()
public function render(): string
{
$members = array();
$area = isset( $this->configuration['most_contributions_area'] ) ? $this->configuration['most_contributions_area'] : NULL;
$area = $this->configuration['most_contributions_area'] ?? NULL;
/* If we're showing everything that's easy just show the content count */
if( !$area )
{
$contributions = array( 'members' => new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_members', array( "member_posts > ?", 0 ), "member_posts DESC", array( 0,5 ) ), 'IPS\Member' ) );
$contributions = array( 'members' => new ActiveRecordIterator( Db::i()->select( '*', 'core_members', array( "member_posts > ?", 0 ), "member_posts DESC", array( 0,5 ) ), 'IPS\Member' ) );
}
/* A specific content type? That's more work */
else
@@ -165,14 +166,14 @@ class _mostContributions extends \IPS\Widget\StaticCache
$contributions = $area::mostContributions( $this->configuration['number_to_show'] );
}
if( !\count( $contributions['members'] ) )
if( !count( $contributions['members'] ) )
{
return "";
}
if ( isset( $this->configuration['language_key'] ) )
{
$title = \IPS\Member::loggedIn()->language()->addToStack( $this->configuration['language_key'], FALSE, array( 'escape' => TRUE ) );
$title = Member::loggedIn()->language()->addToStack( $this->configuration['language_key'], FALSE, array( 'escape' => TRUE ) );
}
elseif ( isset( $this->configuration['widget_feed_title'] ) )
{
@@ -180,7 +181,7 @@ class _mostContributions extends \IPS\Widget\StaticCache
}
else
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'block_mostContributions' );
$title = Member::loggedIn()->language()->addToStack( 'block_mostContributions' );
}
return $this->output( $contributions, $area, $title );
@@ -191,8 +192,8 @@ class _mostContributions extends \IPS\Widget\StaticCache
*
* @return void
*/
public function delete()
public function delete() : void
{
\IPS\Lang::deleteCustom( 'core', $this->configuration['language_key'] );
Lang::deleteCustom( 'core', $this->configuration['language_key'] );
}
}
+29 -31
View File
@@ -11,53 +11,51 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use DateInterval;
use IPS\DateTime;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Member;
use IPS\Widget\Customizable;
use IPS\Widget\StaticCache;
use function array_slice;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* mostSolved Widget
*/
class _mostSolved extends \IPS\Widget\StaticCache
class mostSolved extends StaticCache implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'mostSolved';
public string $key = 'mostSolved';
/**
* @brief App
*/
public $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Initialise this widget
*
* @return void
*/
public function init()
{
parent::init();
}
public string $app = 'core';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Number( 'number_to_show', isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 5, TRUE, array( 'max' => 25 ) ) );
$form->add( new Number( 'number_to_show', $this->configuration['number_to_show'] ?? 5, TRUE, array( 'max' => 25 ) ) );
return $form;
}
@@ -66,14 +64,14 @@ class _mostSolved extends \IPS\Widget\StaticCache
*
* @return string
*/
public function render()
public function render(): string
{
/* How many? */
$limit = isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 5;
$limit = $this->configuration['number_to_show'] ?? 5;
/* Work out who has got the most reputation this week... */
$topSolvedThisWeek = array();
foreach ( \IPS\Db::i()->select( 'member_id', 'core_solved_index', array( 'member_id > 0 AND solved_date>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1W' ) )->getTimestamp() ) ) as $memberId )
foreach ( Db::i()->select( 'member_id', 'core_solved_index', array( 'member_id > 0 AND solved_date>? AND type=? AND hidden=0', DateTime::create()->sub( new DateInterval( 'P1W' ) )->getTimestamp(), 'solved' ) ) as $memberId )
{
if ( !isset( $topSolvedThisWeek[ $memberId ] ) )
{
@@ -85,14 +83,14 @@ class _mostSolved extends \IPS\Widget\StaticCache
}
}
arsort( $topSolvedThisWeek );
$topSolvedThisWeek = \array_slice( $topSolvedThisWeek, 0, $limit, TRUE );
$topSolvedThisWeek = array_slice( $topSolvedThisWeek, 0, $limit, TRUE );
/* Load their data */
if( \count( $topSolvedThisWeek ) )
if( count( $topSolvedThisWeek ) )
{
foreach ( \IPS\Db::i()->select( '*', 'core_members', \IPS\Db::i()->in( 'member_id', array_keys( $topSolvedThisWeek ) ) ) as $member )
foreach ( Db::i()->select( '*', 'core_members', Db::i()->in( 'member_id', array_keys( $topSolvedThisWeek ) ) ) as $member )
{
\IPS\Member::constructFromData( $member );
Member::constructFromData( $member );
}
}
+42 -32
View File
@@ -11,54 +11,64 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Db;
use IPS\File;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Translatable;
use IPS\Lang;
use IPS\Member;
use IPS\Request;
use IPS\Settings;
use IPS\Widget;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* newsletter Widget
*/
class _newsletter extends \IPS\Widget
class newsletter extends Widget
{
/**
* @brief Widget Key
*/
public $key = 'newsletter';
public string $key = 'newsletter';
/**
* @brief Language String Key used to store the editor content
*/
public static $editorKey = 'block_newsletter_signup';
public static string $editorKey = 'block_newsletter_signup';
/**
* @brief Language Key used to save the content
*/
public static $editorLangKey = 'block_newsletter_signup';
public static string $editorLangKey = 'block_newsletter_signup';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Translatable( 'block_newsletter_signup_text', NULL, TRUE, array(
$form->add( new Translatable( 'block_newsletter_signup_text', NULL, TRUE, array(
'app' => 'core',
'key' => static::$editorLangKey,
'editor' => array(
@@ -76,27 +86,27 @@ class _newsletter extends \IPS\Widget
*
* @return void
*/
public function delete()
public function delete() : void
{
\IPS\Lang::deleteCustom( 'core', static::$editorLangKey );
Lang::deleteCustom( 'core', static::$editorLangKey );
foreach( \IPS\Db::i()->select( '*', 'core_attachments_map', array( array( 'location_key=?', 'core_Newsletterwidget' ) ) ) as $map )
foreach( Db::i()->select( '*', 'core_attachments_map', array( array( 'location_key=?', 'core_Newsletterwidget' ) ) ) as $map )
{
try
{
$attachment = \IPS\Db::i()->select( '*', 'core_attachments', array( 'attach_id=?', $map['attachment_id'] ) )->first();
$attachment = Db::i()->select( '*', 'core_attachments', array( 'attach_id=?', $map['attachment_id'] ) )->first();
\IPS\Db::i()->delete( 'core_attachments_map', array( array( 'attachment_id=?', $attachment['attach_id'] ) ) );
\IPS\Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
Db::i()->delete( 'core_attachments_map', array( array( 'attachment_id=?', $attachment['attach_id'] ) ) );
Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
\IPS\File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
if ( $attachment['attach_thumb_location'] )
{
\IPS\File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
}
}
catch ( \Exception $e ) { }
catch ( Exception $e ) { }
}
}
@@ -106,10 +116,10 @@ class _newsletter extends \IPS\Widget
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
\IPS\File::claimAttachments( 'widget-' . $this->uniqueKey, 0, 0, 'block_newsletter_signup' );
\IPS\Lang::saveCustom( 'core', 'block_newsletter_signup', $values[ 'block_newsletter_signup_text' ] );
File::claimAttachments( 'widget-' . $this->uniqueKey, 0, 0, 'block_newsletter_signup' );
Lang::saveCustom( 'core', 'block_newsletter_signup', $values[ 'block_newsletter_signup_text' ] );
return $values;
}
@@ -118,21 +128,21 @@ class _newsletter extends \IPS\Widget
*
* @return string
*/
public function render()
public function render(): string
{
if( \IPS\Member::loggedIn()->allow_admin_mails )
if( Member::loggedIn()->allow_admin_mails )
{
return "";
}
// If we have just dropped the block, the ref will be the URL for that block drop, which will show a WSOD if we click the sign up button before reloading the page
if ( isset( \IPS\Request::i()->blockID ) )
if ( isset( Request::i()->blockID ) )
{
$url = \IPS\Settings::i()->base_url;
$url = Settings::i()->base_url;
}
else
{
$url = (string) \IPS\Request::i()->url();
$url = (string) Request::i()->url();
}
return $this->output( $url );
+28 -25
View File
@@ -11,45 +11,48 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\Feature;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Output;
use IPS\Theme;
use IPS\Widget\Customizable;
use IPS\Widget\PermissionCache;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Promoted Content Widget
*/
class _promoted extends \IPS\Widget\PermissionCache
class promoted extends PermissionCache implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'promoted';
public string $key = 'promoted';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Initialize widget
*
* @return null
* @return void
*/
public function init()
public function init(): void
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/promote.css', 'core' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/promote_responsive.css', 'core' ) );
}
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'styles/promote.css', 'core' ) );
parent::init();
}
@@ -57,14 +60,14 @@ class _promoted extends \IPS\Widget\PermissionCache
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return \IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Number( 'toshow', isset( $this->configuration['toshow'] ) ? $this->configuration['toshow'] : 5, TRUE ) );
$form->add( new Number( 'toshow', $this->configuration['toshow'] ?? 5, TRUE ) );
return $form;
}
@@ -74,12 +77,12 @@ class _promoted extends \IPS\Widget\PermissionCache
*
* @return string
*/
public function render()
public function render(): string
{
$limit = isset ( $this->configuration['toshow'] ) ? $this->configuration['toshow'] : 5;
$stream = \IPS\core\Promote::internalStream( $limit );
$limit = $this->configuration['toshow'] ?? 5;
$stream = Feature::internalStream( $limit );
if ( ! \count( $stream ) )
if ( ! count( $stream ) )
{
return '';
}
@@ -1,109 +0,0 @@
<?php
/**
* @brief recentStatusUpdates Widget
* @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 04 Jun 2014
*/
namespace IPS\core\widgets;
/* 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;
}
/**
* recentStatusUpdates Widget
*/
class _recentStatusUpdates extends \IPS\Widget
{
/**
* @brief Widget Key
*/
public $key = 'recentStatusUpdates';
/**
* @brief App
*/
public $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* @brief cacheKey
*/
public $cacheKey = "";
/**
* Constructor
*
* @param String $uniqueKey Unique key for this specific instance
* @param array $configuration Widget custom configuration
* @param null|string|array $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param null|string $orientation Orientation (top, bottom, right, left)
* @return void
*/
public function __construct( $uniqueKey, array $configuration, $access=null, $orientation=null )
{
parent::__construct( $uniqueKey, $configuration, $access, $orientation );
/* We need to adjust the key for profile posts setting */
$this->cacheKey = "widget_{$this->key}_" . $this->uniqueKey . '_' . md5( json_encode( $configuration ) . "_" . \IPS\Member::loggedIn()->language()->id . "_" . \IPS\Member::loggedIn()->skin . "_" . json_encode( \IPS\Member::loggedIn()->groups ) . "_" . $orientation . "_" . \IPS\core\Statuses\Status::canCreateFromCreateMenu() );
}
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return \IPS\Helpers\Form
*/
public function configuration( &$form=null )
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Number( 'number_to_show', isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 5, TRUE ) );
return $form;
}
/**
* Render a widget
*
* @return string
*/
public function render()
{
if ( !\IPS\Settings::i()->profile_comments )
{
return '';
}
if( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'status', 'front' ) ) )
{
return '';
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_core.js', 'core' ) );
$statuses = new \IPS\Patterns\ActiveRecordIterator(
\IPS\Db::i()->select(
'*',
'core_member_status_updates',
array( 'status_approved = 1' ),
'status_date DESC',
array( 0, isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 5 )
),
'\IPS\core\Statuses\Status'
);
return $this->output( $statuses );
}
}
+47 -34
View File
@@ -12,58 +12,71 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content\Controller;
use IPS\Dispatcher;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Translatable;
use IPS\Lang;
use IPS\Member;
use IPS\Request;
use IPS\Settings;
use IPS\Widget\Customizable;
use IPS\Widget\PermissionCache;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Related Content Widget
*/
class _relatedContent extends \IPS\Widget\PermissionCache
class relatedContent extends PermissionCache implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'relatedContent';
public string $key = 'relatedContent';
/**
* @brief App
*/
public $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'core';
/**
* Constructor
*
* @param String $uniqueKey Unique key for this specific instance
* @param String $uniqueKey Unique key for this specific instance
* @param array $configuration Widget custom configuration
* @param null|string|array $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param null|string $orientation Orientation (top, bottom, right, left)
* @param array|string|null $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param string|null $orientation Orientation (top, bottom, right, left)
* @param string $layout
* @return void
*/
public function __construct( $uniqueKey, array $configuration, $access=null, $orientation=null )
public function __construct(string $uniqueKey, array $configuration, array|string $access=null, string $orientation=null, string $layout='table' )
{
parent::__construct( $uniqueKey, $configuration, $access, $orientation );
parent::__construct( $uniqueKey, $configuration, $access, $orientation, $layout );
/* We can't run the URL related logic if we have no dispatcher because this class could also be initialized by the CLI cron job */
if( \IPS\Dispatcher::hasInstance() )
if( Dispatcher::hasInstance() )
{
/* Cache per item, not per block */
$parts = parse_url( (string) \IPS\Request::i()->url()->setPage() );
$parts = parse_url( (string) Request::i()->url()->setPage() );
if ( \IPS\Settings::i()->htaccess_mod_rewrite )
if ( Settings::i()->htaccess_mod_rewrite )
{
$url = $parts['scheme'] . "://" . $parts['host'] . ( isset( $parts['port'] ) ? ':' . $parts['port'] : '' ) . $parts['path'];
$url = $parts['scheme'] . "://" . $parts['host'] . ( isset( $parts['port'] ) ? ':' . $parts['port'] : '' ) . ( $parts['path'] ?? '' );
}
else
{
$url = $parts['scheme'] . "://" . $parts['host'] . ( isset( $parts['port'] ) ? ':' . $parts['port'] : '' ) . $parts['path'] . ( isset( $parts['query'] ) ? '?' . $parts['query'] : '' );
$url = $parts['scheme'] . "://" . $parts['host'] . ( isset( $parts['port'] ) ? ':' . $parts['port'] : '' ) . ( $parts['path'] ?? '' ) . ( isset( $parts['query'] ) ? '?' . $parts['query'] : '' );
}
$this->cacheKey .= '_' . md5( $url );
@@ -76,7 +89,7 @@ class _relatedContent extends \IPS\Widget\PermissionCache
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
if ( !isset( $this->configuration['language_key'] ) )
{
@@ -84,7 +97,7 @@ class _relatedContent extends \IPS\Widget\PermissionCache
}
$values['language_key'] = $this->configuration['language_key'];
\IPS\Lang::saveCustom( 'core', $this->configuration['language_key'], $values['widget_feed_title'] );
Lang::saveCustom( 'core', $this->configuration['language_key'], $values['widget_feed_title'] );
unset( $values['widget_feed_title'] );
return $values;
@@ -93,16 +106,16 @@ class _relatedContent extends \IPS\Widget\PermissionCache
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return \IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
/* Block title */
$form->add( new \IPS\Helpers\Form\Translatable( 'widget_feed_title', isset( $this->configuration['language_key'] ) ? NULL : \IPS\Member::loggedIn()->language()->addToStack( 'block_relatedContent' ), FALSE, array( 'app' => 'core', 'key' => ( isset( $this->configuration['language_key'] ) ? $this->configuration['language_key'] : NULL ) ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'toshow', isset( $this->configuration['toshow'] ) ? $this->configuration['toshow'] : 5, TRUE ) );
$form->add( new Translatable( 'widget_feed_title', isset( $this->configuration['language_key'] ) ? NULL : Member::loggedIn()->language()->addToStack( 'block_relatedContent' ), FALSE, array( 'app' => 'core', 'key' => ( $this->configuration['language_key'] ?? NULL ) ) ) );
$form->add( new Number( 'toshow', $this->configuration['toshow'] ?? 5, TRUE ) );
return $form;
}
@@ -112,29 +125,29 @@ class _relatedContent extends \IPS\Widget\PermissionCache
*
* @return string
*/
public function render()
public function render(): string
{
if( !( \IPS\Dispatcher::i()->dispatcherController instanceof \IPS\Content\Controller ) )
if( !( Dispatcher::i()->dispatcherController instanceof Controller ) )
{
return '';
}
$limit = isset ( $this->configuration['toshow'] ) ? $this->configuration['toshow'] : 5;
$limit = $this->configuration['toshow'] ?? 5;
$related = \IPS\Dispatcher::i()->dispatcherController->getSimilarContent( $limit );
$related = Dispatcher::i()->dispatcherController->getSimilarContent( $limit );
if( $related === NULL or !\count( $related ) )
if( $related === NULL or !count( $related ) )
{
return '';
}
if ( isset( $this->configuration['language_key'] ) )
{
$title = \IPS\Member::loggedIn()->language()->addToStack( $this->configuration['language_key'], FALSE, array( 'escape' => TRUE ) );
$title = Member::loggedIn()->language()->addToStack( $this->configuration['language_key'], FALSE, array( 'escape' => TRUE ) );
}
else
{
$title = \IPS\Member::loggedIn()->language()->addToStack( 'block_relatedContent' );
$title = Member::loggedIn()->language()->addToStack( 'block_relatedContent' );
}
return $this->output( $related, $title );
+37 -28
View File
@@ -11,44 +11,53 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Member;
use IPS\Session\Store;
use IPS\Settings;
use IPS\Widget;
use IPS\Widget\StaticCache;
use UnderflowException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Stats Widget
*/
class _stats extends \IPS\Widget\StaticCache
class stats extends StaticCache
{
/**
* @brief Widget Key
*/
public $key = 'stats';
public string $key = 'stats';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param \IPS\Helpers\Form|NULL $form Form helper
* @return null|\IPS\Helpers\Form
* @param Form|NULL $form Form helper
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$mostOnline = json_decode( \IPS\Settings::i()->most_online, TRUE );
$form->add( new \IPS\Helpers\Form\Number( 'stats_most_online', $mostOnline['count'], TRUE ) );
$mostOnline = json_decode( Settings::i()->most_online, TRUE );
$form->add( new Number( 'stats_most_online', $mostOnline['count'], TRUE ) );
return $form;
}
@@ -59,16 +68,16 @@ class _stats extends \IPS\Widget\StaticCache
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
if ( \IPS\Member::loggedIn()->isAdmin() and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_recount_content' ) )
if ( Member::loggedIn()->isAdmin() and Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_recount_content' ) )
{
$mostOnline = array( 'count' => $values['stats_most_online'], 'time' => time() );
\IPS\Settings::i()->changeValues( array( 'most_online' => json_encode( $mostOnline ) ) );
Settings::i()->changeValues( array( 'most_online' => json_encode( $mostOnline ) ) );
unset( $values['stats_most_online'] );
\IPS\Widget::deleteCaches( 'stats', 'core' );
Widget::deleteCaches( 'stats', 'core' );
}
return $values;
@@ -79,37 +88,37 @@ class _stats extends \IPS\Widget\StaticCache
*
* @return string
*/
public function render()
public function render(): string
{
$stats = array();
$mostOnline = json_decode( \IPS\Settings::i()->most_online, TRUE );
$mostOnline = json_decode( Settings::i()->most_online, TRUE );
/* fetch only successful registered members ; if this needs to be changed, please review the other areas where we have the name<>? AND email<>? condition */
$where = array( 'completed=?', true );
/* Member count */
$stats['member_count'] = \IPS\Db::i()->select( 'COUNT(*)', 'core_members', $where )->first();
$stats['member_count'] = Db::i()->select( 'COUNT(*)', 'core_members', $where )->first();
/* Most online */
$count = \IPS\Session\Store::i()->getOnlineUsers( \IPS\Session\Store::ONLINE_GUESTS | \IPS\Session\Store::ONLINE_MEMBERS | \IPS\Session\Store::ONLINE_COUNT_ONLY );
$count = Store::i()->getOnlineUsers( Store::ONLINE_GUESTS | Store::ONLINE_MEMBERS | Store::ONLINE_COUNT_ONLY );
if( $count > $mostOnline['count'] )
{
$mostOnline = array( 'count' => $count, 'time' => time() );
\IPS\Settings::i()->changeValues( array( 'most_online' => json_encode( $mostOnline ) ) );
Settings::i()->changeValues( array( 'most_online' => json_encode( $mostOnline ) ) );
}
$stats['most_online'] = $mostOnline;
/* Last Registered Member */
$where = array( array( "completed=1 AND temp_ban != -1" ) );
$where[] = array( '( ! ' . \IPS\Db::i()->bitwiseWhere( \IPS\Member::$bitOptions['members_bitoptions'], 'bw_is_spammer' ) . ' )' );
$where[] = array( 'member_id NOT IN(?)', \IPS\Db::i()->select( 'member_id', 'core_validating', array( 'new_reg=1' ) ) );
$where[] = array( 'NOT(members_bitoptions2 & ?)', \IPS\Member::$bitOptions['members_bitoptions']['members_bitoptions2']['is_support_account'] );
$where[] = array( '( ! ' . Db::i()->bitwiseWhere( Member::$bitOptions['members_bitoptions'], 'bw_is_spammer' ) . ' )' );
$where[] = array( 'member_id NOT IN(?)', Db::i()->select( 'member_id', 'core_validating', array( 'new_reg=1' ) ) );
$where[] = array( 'NOT(members_bitoptions2 & ?)', Member::$bitOptions['members_bitoptions']['members_bitoptions2']['is_support_account'] );
try
{
$stats['last_registered'] = \IPS\Member::constructFromData( \IPS\Db::i()->select( 'core_members.*', 'core_members', $where, 'core_members.member_id DESC', array( 0, 1 ) )->first() );
$stats['last_registered'] = Member::constructFromData( Db::i()->select( 'core_members.*', 'core_members', $where, 'core_members.member_id DESC', array( 0, 1 ) )->first() );
}
catch( \UnderflowException $ex )
catch( UnderflowException $ex )
{
$stats['last_registered'] = NULL;
}
+49 -42
View File
@@ -11,53 +11,63 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application;
use IPS\Content;
use IPS\core\Stream as StreamClass;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Select;
use IPS\Helpers\Form\Text;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use IPS\Theme;
use IPS\Widget\PermissionCache;
use function count;
use function defined;
use function in_array;
use function is_array;
use function strstr;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* stream Widget
*/
class _stream extends \IPS\Widget\PermissionCache
class stream extends PermissionCache
{
/**
* @brief Widget Key
*/
public $key = 'stream';
public string $key = 'stream';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Initialise this widget
*
* @return void
*/
public function init()
public function init(): void
{
parent::init(); //outputCss
/* Necessary CSS/JS */
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_streams.js', 'core' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_statuses.js', 'core' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/streams.css' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/streams_responsive.css', 'core', 'front' ) );
}
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_streams.js', 'core' ) );
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'styles/streams.css' ) );
$apps = array();
if( isset( $this->configuration['content'] ) and \strstr( $this->configuration['content'], ',' ) )
if( isset( $this->configuration['content'] ) and strstr( $this->configuration['content'], ',' ) )
{
foreach( explode( ',', $this->configuration['content'] ) as $content )
{
@@ -67,9 +77,9 @@ class _stream extends \IPS\Widget\PermissionCache
}
/* We will need specific CSS */
foreach( \IPS\Application::enabledApplications() as $appDir => $app )
foreach( Application::enabledApplications() as $appDir => $app )
{
if ( isset( $this->configuration['content'] ) and $this->configuration['content'] === 0 or \in_array( $appDir, $apps ) )
if ( isset( $this->configuration['content'] ) and $this->configuration['content'] === 0 or in_array( $appDir, $apps ) )
{
if ( method_exists( $app, 'outputCss' ) )
{
@@ -82,28 +92,25 @@ class _stream extends \IPS\Widget\PermissionCache
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$options = array();
foreach( \IPS\Content::routedClasses( FALSE, FALSE, TRUE ) AS $class )
foreach( Content\Search\SearchContent::searchableClasses() as $class )
{
if ( \in_array( 'IPS\Content\Searchable', \class_implements( $class ) ) )
{
$options[ $class ] = \IPS\Member::loggedIn()->language()->addToStack( $class::$title . '_pl' );
}
$options[ $class ] = Member::loggedIn()->language()->addToStack( $class::$title . '_pl' );
}
$form->add( new \IPS\Helpers\Form\Text( 'title', $this->configuration['title'] ?? NULL, TRUE ) );
$form->add( new \IPS\Helpers\Form\Select( 'content', ( isset( $this->configuration['content'] ) AND $this->configuration['content'] !== 0 ) ? explode( ',', $this->configuration['content'] ) : 0, FALSE, array(
$form->add( new Text( 'title', $this->configuration['title'] ?? NULL, TRUE ) );
$form->add( new Select( 'content', ( isset( $this->configuration['content'] ) AND $this->configuration['content'] !== 0 ) ? explode( ',', $this->configuration['content'] ) : 0, FALSE, array(
'options' => $options,
'multiple' => TRUE,
'unlimited' => 0,
) ) );
$dateField = new \IPS\Helpers\Form\Select( 'date', ( isset( $this->configuration['date'] ) ) ? $this->configuration['date'] : 'year', FALSE, array(
$dateField = new Select( 'date', ( isset( $this->configuration['date'] ) ) ? $this->configuration['date'] : 'year', FALSE, array(
'options' => array(
'today' => 'search_day',
'week' => 'search_week',
@@ -111,10 +118,10 @@ class _stream extends \IPS\Widget\PermissionCache
'year' => 'search_year'
)
) );
$dateField->label = \IPS\Member::loggedIn()->language()->addToStack( 'stream_date_relative_days' );
$dateField->label = Member::loggedIn()->language()->addToStack( 'stream_date_relative_days' );
$form->add( $dateField );
$form->add( new \IPS\Helpers\Form\Number( 'max_results', $this->configuration['max_results'] ?? 5, TRUE, array( 'max' => 20 ) ) );
$form->add( new Number( 'max_results', $this->configuration['max_results'] ?? 5, TRUE, array( 'max' => 20 ) ) );
return $form;
}
@@ -124,9 +131,9 @@ class _stream extends \IPS\Widget\PermissionCache
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
if ( \is_array( $values['content'] ) )
if ( is_array( $values['content'] ) )
{
$save = [];
foreach( $values['content'] AS $class )
@@ -144,7 +151,7 @@ class _stream extends \IPS\Widget\PermissionCache
*
* @return string
*/
public function render()
public function render(): string
{
if ( !isset( $this->configuration['content'] ) )
{
@@ -154,11 +161,11 @@ class _stream extends \IPS\Widget\PermissionCache
/* Set our content */
if ( $this->configuration['content'] === 0 )
{
$stream = \IPS\core\Stream::allActivityStream();
$stream = StreamClass::allActivityStream();
}
else
{
$stream = new \IPS\core\Stream;
$stream = new StreamClass;
$stream->classes = $this->configuration['content'];
}
@@ -191,17 +198,17 @@ class _stream extends \IPS\Widget\PermissionCache
/* Set some defaults */
$stream->id = 0;
$stream->include_comments = TRUE;
$stream->baseUrl = \IPS\Http\Url::internal( "app=core&module=discover&controller=streams", 'front', 'discover_all' );
$stream->baseUrl = Url::internal( "app=core&module=discover&controller=streams", 'front', 'discover_all' );
/* Query */
$query = $stream->query()->setLimit( $this->configuration['max_results'] ?? 5 );
$results = $query->search();
if ( !\count( $results ) )
if ( !count( $results ) )
{
return '';
}
return $this->output( $stream, $results, $this->configuration['title'] ?? \IPS\Member::loggedIn()->language()->addToStack( 'block_stream' ), $this->orientation );
return $this->output( $stream, $results, $this->configuration['title'] ?? Member::loggedIn()->language()->addToStack( 'block_stream' ), $this->orientation );
}
}
@@ -0,0 +1,263 @@
<?php
/**
* @brief tableofcontents Widget
* @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 22 Jan 2024
*/
namespace IPS\core\widgets;
use IPS\Application;
use IPS\cms\modules\front\pages\page;
use IPS\Content\Controller;
use IPS\Db;
use IPS\Dispatcher;
use IPS\Helpers\Form;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use OutOfBoundsException;
use OutOfRangeException;
use Throwable;
use UnderflowException;
use IPS\Widget\StaticCache;
use IPS\Widget;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* tableofcontents Widget
*/
class tableofcontents extends StaticCache
{
/**
* @brief Widget Key
*/
public string $key = 'tableofcontents';
/**
* @brief App
*/
public string $app = 'core';
/**
* This key is used to select the correct items; set it using static::setKey()
* @var string|int|null
*/
protected static string|int|null $_tocKey;
/**
* Set a key for the current table of contents so they are unique per id/page
*
* @param string|int|null $key
* @return void
*/
public static function setKey( string|int|null $key=null ) :void
{
static::$_tocKey = $key;
}
/**
* @return bool
*/
public function canEdit() : bool
{
$controller = Dispatcher::i()->dispatcherController;
if ( $controller instanceof Controller )
{
try
{
$item = $controller::loadItem();
if ( $item?->author()?->member_id === Member::loggedIn()->member_id and Member::loggedIn()->member_id )
{
return true;
}
}
catch ( Throwable ) {}
}
return Dispatcher::i()->application instanceof Application AND Dispatcher::i()->application->canManageWidgets();
}
/**
* Constructor
*
* @param String $uniqueKey Unique key for this specific instance
* @param array $configuration Widget custom configuration
* @param array|string|null $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param string|null $orientation Orientation (top, bottom, right, left)
* @param string $layout
* @return void
*/
public function __construct(string $uniqueKey, array $configuration, array|string $access=null, string $orientation=null, string $layout='table' )
{
parent::__construct( $uniqueKey, $configuration, $access, $orientation, $layout );
$data = Dispatcher::i()->getLocationData();
if ( @$data['app'] === 'cms' and @$data['module'] === 'pages' and @$data['controller'] === 'page' and $page = page::getPage() )
{
@$data['id'] = $page->id;
}
$location = static::getLocationHash( @$data['app'], @$data['module'], @$data['controller'], @$data['id'] );
$this->cacheKey = "widget_{$this->key}_" . $this->uniqueKey . '_' . md5( Member::loggedIn()->language()->id . "_" . $orientation) . ( $this->canEdit() ? '_canEdit_' : '_cannotEdit_' ) . '_' . $location;
}
/**
* Initialise this widget
*
* @return void
*/
public function init() : void
{
// Use this to perform any set up and to assign a template that is not in the following format:
// $this->template( array( \IPS\Theme::i()->getTemplate( 'widgets', $this->app, 'front' ), $this->key ) );
// If you are creating a plugin, uncomment this line:
// $this->template( array( \IPS\Theme::i()->getTemplate( 'plugins', 'core', 'global' ), $this->key ) );
// And then create your template at located at plugins/<your plugin>/dev/html/tableofcontents.phtml
parent::init();
}
/**
* Specify widget configuration
*
* @param null|Form $form Form object
* @return Form
*/
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->addMessage( "block_tableofcontents__info" );
return $form;
}
/**
* Ran before saving widget configuration
*
* @param array $values Values from form
* @return array
*/
public function preConfig( array $values ): array
{
return $values;
}
/**
* Get a hash for a location; This method is used to keep the results consistent
*
* @param string|null $app
* @param string|null $module
* @param string|null $controller
* @param string|null $else
* @return string
*/
public static function getLocationHash( ?string $app=null, ?string $module=null, ?string $controller=null, ?string $else=null ) : string
{
return md5( json_encode( [ $app, $module, $controller, $else ] ) );
}
/**
* Get the items inside the table of contents widget. If the widget was never configured, it will return null.
*
* @param array $data
*
* @return array|null
* @static
*/
public static function getItems( array $data ) : array|null
{
try
{
$where = [ [ '`app`=? AND `module`=? AND `controller`=?', $data['app'], $data['module'], $data['controller'] ] ];
if ( isset( $data['key'] ) )
{
$where[] = [ '`key`=?', $data['key'] ];
}
$row = Db::i()->select( '*', 'core_table_of_contents', $where )->first();
$items = json_decode( $row['contents'], true );
/* Fail fast here. This should always json_decode to an array */
if ( !is_array( $items ) )
{
throw new OutOfBoundsException;
}
return $items;
}
catch ( UnderflowException ) {}
return null;
}
/**
* Get the location data from the current request
*
* @return array
*/
public static function getLocationData() : array
{
if ( Widget\Request::i() instanceof Widget\Request )
{
$data['app'] = Request::i()->pageApp;
$data['module'] = Request::i()->pageModule;
$data['controller'] = Request::i()->pageController;
$data['id'] = Widget\Request::i()->id ?? null;
if ( isset( $data['app'] ) and isset( $data['module'] ) and isset( $data['controller'] ) )
{
try
{
if ( Request::i()->pageID and $page = \IPS\cms\Pages\Page::load( Request::i()->pageID ) )
{
$data['key'] = $page->id;
}
}
catch ( UnderflowException|OutOfRangeException ) {}
return $data;
}
}
$data = Dispatcher::i()->getLocationData();
if ( $data['app'] === 'cms' and $data['module'] === 'pages' and $data['controller'] === 'page' and $page = page::getPage() )
{
$data['key'] = (string) $page->id;
}
else if ( isset( static::$_tocKey ) )
{
$data['key'] = (string) static::$_tocKey;
}
else if ( isset( $data['id'] ) )
{
$data['key'] = (string) $data['id'];
}
return $data;
}
/**
* Render a widget
*
* @return string
*/
public function render(): string
{
$data = static::getLocationData();
Output::i()->addCssFiles( '/framework/table-of-contents.css', 'core', 'global' );
return $this->output( static::getItems( $data ), $this->canEdit() );
// Use $this->output( $foo, $bar ); to return a string generated by the template set in init() or manually added via $widget->template( $callback );
// Note you MUST route output through $this->output() rather than calling \IPS\Theme::i()->getTemplate() because of the way widgets are cached
}
}
+155
View File
@@ -0,0 +1,155 @@
<?php
/**
* @brief tags Widget
* @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
{subpackage}
* @since 05 Aug 2024
*/
namespace IPS\core\widgets;
use IPS\Content\Tag;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Select;
use IPS\Helpers\Form\Text;
use IPS\Member;
use IPS\Settings;
use IPS\Widget\Customizable;
use IPS\Widget\PermissionCache;
use OutOfRangeException;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* tags Widget
*/
class tags extends PermissionCache implements Customizable
{
/**
* @brief Widget Key
*/
public string $key = 'tags';
/**
* @brief App
*/
public string $app = 'core';
/**
* Specify widget configuration
*
* @param null|Form $form Form object
* @return Form
*/
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new Text( 'tag_block_title', $this->configuration['tag_block_title'] ?? Member::loggedIn()->language()->get( 'block_tags' ), true ) );
$tags = iterator_to_array(
Db::i()->select( 'tag_id, tag_text', 'core_tags_data', null, 'tag_text' )
->setKeyField( 'tag_id' )
->setValueField( 'tag_text' )
);
$form->add( new Select( 'tag_block_tags', $this->configuration['tag_block_tags'] ?? null, true, [
'options' => $tags,
'multiple' => true,
'noDefault' => true
] ) );
$form->add( new Number( 'tag_block_limit', $this->configuration['tag_block_limit'] ?? 5, true ) );
return $form;
}
/**
* @return string[]
*/
public function getSupportedLayouts() : array
{
$layouts = parent::getSupportedLayouts();
/* Remove support for carousels; if we have tabs, there is way too much going on here */
$return = [];
foreach( $layouts as $k => $v )
{
if( !str_ends_with( $v, '-carousel' ) )
{
$return[] = $v;
}
}
return $return;
}
/**
* Render a widget
*
* @return string
*/
public function render(): string
{
$data = [];
$limit = $this->configuration['tag_block_limit'] ?? 5;
$contentTypes = Tag::getTaggableContentTypes();
foreach( ( $this->configuration['tag_block_tags'] ?? [] ) as $tag )
{
try
{
$tag = Tag::load( $tag );
}
catch( OutOfRangeException )
{
continue;
}
$items = [];
foreach( Db::i()->select( '*', [ 'core_tags', 't' ], [
[ 't.tag_text=?', $tag->text ],
[ 'p.tag_perm_visible=?', 1 ],
[ '(p.tag_perm_text=? or ' . Db::i()->findInSet( 'p.tag_perm_text', Member::loggedIn()->groups ) . ')', '*' ]
], 't.tag_added desc', $limit )
->join( [ 'core_tags_perms', 'p' ], 't.tag_aai_lookup=p.tag_perm_aai_lookup and t.tag_aap_lookup=p.tag_perm_aap_lookup' ) as $row )
{
foreach( $contentTypes as $k => $itemClass )
{
if( $itemClass::$application == $row['tag_meta_app'] and $itemClass::$module == $row['tag_meta_area'] )
{
try
{
$items[] = $itemClass::load( $row['tag_meta_id'] );
}
catch( OutOfRangeException ){}
break;
}
}
}
if( count( $items ) )
{
$data[ $tag->text ] = $items;
}
}
if( !count( $data ) )
{
return "";
}
$title = $this->configuration['tag_block_title'] ?? Member::loggedIn()->language()->get( 'block_tags' );
return $this->output( $title, $data );
}
}
+30 -20
View File
@@ -11,43 +11,53 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use DateInterval;
use IPS\DateTime;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Member;
use IPS\Widget\Customizable;
use IPS\Widget\PermissionCache;
use function array_slice;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* topContributors Widget
*/
class _topContributors extends \IPS\Widget\PermissionCache
class topContributors extends PermissionCache implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'topContributors';
public string $key = 'topContributors';
/**
* @brief App
*/
public $app = 'core';
public string $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return \IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Number( 'number_to_show', isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 5, TRUE, array( 'max' => 25 ) ) );
$form->add( new Number( 'number_to_show', $this->configuration['number_to_show'] ?? 5, TRUE, array( 'max' => 25 ) ) );
return $form;
}
@@ -56,14 +66,14 @@ class _topContributors extends \IPS\Widget\PermissionCache
*
* @return string
*/
public function render()
public function render(): string
{
/* How many? */
$limit = isset( $this->configuration['number_to_show'] ) ? $this->configuration['number_to_show'] : 5;
$limit = $this->configuration['number_to_show'] ?? 5;
/* Work out who has got the most reputation this week... */
$topContributorsThisWeek = array();
foreach ( \IPS\Db::i()->select( array( 'member_received', 'rep_rating' ), 'core_reputation_index', array( 'member_received>0 AND rep_date>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1W' ) )->getTimestamp() ) ) as $rep )
foreach ( Db::i()->select( array( 'member_received', 'rep_rating' ), 'core_reputation_index', array( 'member_received>0 AND rep_date>?', DateTime::create()->sub( new DateInterval( 'P1W' ) )->getTimestamp() ) ) as $rep )
{
if ( !isset( $topContributorsThisWeek[ $rep['member_received'] ] ) )
{
@@ -75,14 +85,14 @@ class _topContributors extends \IPS\Widget\PermissionCache
}
}
arsort( $topContributorsThisWeek );
$topContributorsThisWeek = \array_slice( $topContributorsThisWeek, 0, $limit, TRUE );
$topContributorsThisWeek = array_slice( $topContributorsThisWeek, 0, $limit, TRUE );
/* Load their data */
if( \count( $topContributorsThisWeek ) )
if( count( $topContributorsThisWeek ) )
{
foreach ( \IPS\Db::i()->select( '*', 'core_members', \IPS\Db::i()->in( 'member_id', array_keys( $topContributorsThisWeek ) ) ) as $member )
foreach ( Db::i()->select( '*', 'core_members', Db::i()->in( 'member_id', array_keys( $topContributorsThisWeek ) ) ) as $member )
{
\IPS\Member::constructFromData( $member );
Member::constructFromData( $member );
}
}
-86
View File
@@ -1,86 +0,0 @@
<?php
/**
* @brief twitter Widget
* @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 30 Sep 2019
*/
namespace IPS\core\widgets;
/* 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;
}
/**
* twitter Widget
*/
class _twitter extends \IPS\Widget\StaticCache
{
/**
* @brief Widget Key
*/
public $key = 'twitter';
/**
* @brief App
*/
public $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
*/
public function configuration( &$form=null )
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Text( 'twitter_name', ( isset( $this->configuration['twitter_name'] ) ) ? $this->configuration['twitter_name'] : NULL, TRUE ) );
$form->add( new \IPS\Helpers\Form\Radio( 'twitter_style', ( isset( $this->configuration['twitter_style'] ) ) ? $this->configuration['twitter_style'] : 'light', FALSE, array( 'options' => array(
'light' => 'twitter_light',
'dark' => 'twitter_dark'
) ) ) );
$form->add( new \IPS\Helpers\Form\Color( 'twitter_color', ( isset( $this->configuration['twitter_color'] ) ) ? $this->configuration['twitter_color'] : NULL ), FALSE );
return $form;
}
/**
* Ran before saving widget configuration
*
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
{
return $values;
}
/**
* Render a widget
*
* @return string
*/
public function render()
{
if ( isset( $this->configuration['twitter_name'] ) )
{
$locale = explode( \IPS\Member::loggedIn()->language()->bcp47(), '-' );
return $this->output( $this->configuration['twitter_name'], $locale[0], $this->configuration['twitter_style'] ?? 'light', $this->configuration['twitter_color'] ?? NULL );
}
return '';
}
}
+44 -33
View File
@@ -11,57 +11,68 @@
namespace IPS\core\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application\Module;
use IPS\Member;
use IPS\Member\Group;
use IPS\Output;
use IPS\Session\Front;
use IPS\Session\Store;
use IPS\Theme;
use IPS\Widget\PermissionCache;
use function array_slice;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* whosOnline Widget
*/
class _whosOnline extends \IPS\Widget\PermissionCache
class whosOnline extends PermissionCache
{
/**
* @brief Widget Key
*/
public $key = 'whosOnline';
public string $key = 'whosOnline';
/**
* @brief App
*/
public $app = 'core';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'core';
/**
* Constructor
*
* @param String $uniqueKey Unique key for this specific instance
* @param String $uniqueKey Unique key for this specific instance
* @param array $configuration Widget custom configuration
* @param null|string|array $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param null|string $orientation Orientation (top, bottom, right, left)
* @param array|string|null $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param string|null $orientation Orientation (top, bottom, right, left)
* @param string $layout
* @return void
*/
public function __construct( $uniqueKey, array $configuration, $access=null, $orientation=null )
public function __construct(string $uniqueKey, array $configuration, array|string $access=null, string $orientation=null, string $layout='table' )
{
parent::__construct( $uniqueKey, $configuration, $access, $orientation );
parent::__construct( $uniqueKey, $configuration, $access, $orientation, $layout );
$member = \IPS\Member::loggedIn() ?: new \IPS\Member;
$member = Member::loggedIn() ?: new Member;
if( $member->member_id AND !$member->isOnlineAnonymously() )
{
\IPS\Output::i()->jsVars['member_id'] = $member->member_id;
\IPS\Output::i()->jsVars['member_url'] = (string) $member->url();
\IPS\Output::i()->jsVars['member_hovercardUrl'] = (string) $member->url()->setQueryString( 'do', 'hovercard' );
\IPS\Output::i()->jsVars['member_formattedName'] = str_replace( '"', '\\"', \IPS\Member\Group::load( $member->member_group_id )->formatName( $member->name ) );
Output::i()->jsVars['member_id'] = $member->member_id;
Output::i()->jsVars['member_url'] = (string) $member->url();
Output::i()->jsVars['member_hovercardUrl'] = (string) $member->url()->setQueryString( 'do', 'hovercard' );
Output::i()->jsVars['member_formattedName'] = str_replace( '"', '\\"', Group::load( $member->member_group_id )->formatName( $member->name ) );
}
/* We want to use the user's permissions array which will validate social groups, clubs and groups. But, we need to remove the individual member entry */
$member = \IPS\Member::loggedIn() ?: new \IPS\Member;
$member = Member::loggedIn() ?: new Member;
$permissions = $member->permissionArray();
foreach( $permissions as $key => $entry )
@@ -76,8 +87,8 @@ class _whosOnline extends \IPS\Widget\PermissionCache
/* We sort to ensure the array is always in the same order */
sort( $permissions );
$theme = $member->skin ?: \IPS\Theme::defaultTheme();
$this->cacheKey = "widget_{$this->key}_" . $this->uniqueKey . '_' . md5( json_encode( $configuration ) . "_" . $member->language()->id . "_" . $theme . "_" . json_encode( $permissions ) . $orientation . '-' . (int) \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'online', 'front' ) ) );
$theme = $member->skin ?: Theme::defaultTheme();
$this->cacheKey = "widget_{$this->key}_" . $this->uniqueKey . '_' . md5( json_encode( $configuration ) . "_" . $member->language()->id . "_" . $theme . "_" . json_encode( $permissions ) . $orientation . '-' . (int) Member::loggedIn()->canAccessModule( Module::get( 'core', 'online', 'front' ) ) );
}
/**
@@ -85,10 +96,10 @@ class _whosOnline extends \IPS\Widget\PermissionCache
*
* @return string
*/
public function render()
public function render(): string
{
/* Do we have permission? */
if ( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'online', 'front' ) ) )
if ( !Member::loggedIn()->canAccessModule( Module::get( 'core', 'online', 'front' ) ) )
{
return "";
}
@@ -97,13 +108,13 @@ class _whosOnline extends \IPS\Widget\PermissionCache
$members = array();
$anonymous = 0;
$users = \IPS\Session\Store::i()->getOnlineUsers( \IPS\Session\Store::ONLINE_MEMBERS, 'desc', NULL, NULL, TRUE );
$users = Store::i()->getOnlineUsers( Store::ONLINE_MEMBERS, 'desc', NULL, NULL, TRUE );
foreach( $users as $row )
{
switch ( $row['login_type'] )
{
/* Not-anonymous Member */
case \IPS\Session\Front::LOGIN_TYPE_MEMBER:
case Front::LOGIN_TYPE_MEMBER:
if ( $row['member_name'] )
{
$members[ $row['member_id'] ] = $row;
@@ -111,20 +122,20 @@ class _whosOnline extends \IPS\Widget\PermissionCache
break;
/* Anonymous member */
case \IPS\Session\Front::LOGIN_TYPE_ANONYMOUS:
case Front::LOGIN_TYPE_ANONYMOUS:
$anonymous += 1;
break;
}
}
$memberCount = \count( $members );
$memberCount = count( $members );
/* Get an accurate guest count */
$guests = \IPS\Session\Store::i()->getOnlineUsers( \IPS\Session\Store::ONLINE_GUESTS | \IPS\Session\Store::ONLINE_COUNT_ONLY, 'desc', NULL, NULL, TRUE );
$guests = Store::i()->getOnlineUsers( Store::ONLINE_GUESTS | Store::ONLINE_COUNT_ONLY, 'desc', NULL, NULL, TRUE );
/* If it's on the sidebar (rather than at the bottom), we want to limit it to 60 so we don't take too much space */
if ( $this->orientation === 'vertical' and \count( $members ) >= 60 )
if ( $this->orientation === 'vertical' and count( $members ) >= 60 )
{
$members = \array_slice( $members, 0, 60 );
$members = array_slice( $members, 0, 60 );
}
/* Display */