Version 4.3.6

This commit is contained in:
Neo committed 2025-12-19 05:49:12 -08:00
1 parent fe1acf984a
commit 1a0c7fd3c2
609 files changed
+14707 -5726

No files matched your search

@@ -0,0 +1,35 @@
<?php
/**
* @brief Google Analytics Community Enhancements
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @since 22 Aug 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\extensions\core\CommunityEnhancements;
/* 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;
}
/**
* Google Analytics Community Enhancement
*/
class _GoogleAnalytics
{
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -0,0 +1,35 @@
<?php
/**
* @brief Community Enhancements: Mandrill integration
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @since 20 June 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\core\extensions\core\CommunityEnhancements;
/* 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;
}
/**
* Community Enhancements: Mandrill integration
*/
class _Mandrill
{
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -80,7 +80,7 @@ class _SpamMonitoring
// \IPS\Output::i()->error( $e->getMessage(), '2C116/2', 403, '' );
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=membersettings&controller=spam&tab=service' ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=moderation&controller=spam&tab=service' ) );
}
/**
@@ -1,3 +1,37 @@
<?php
/**
* @brief Sparkpost Community Enhancement extension
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 18 Sep 2014
* @version SVN_VERSION_NUMBER
* @deprecated 4.3
*/
namespace IPS\core\extensions\core\CommunityEnhancements;
// this file intentionally left blank
/* 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;
}
/**
* IP Address Lookup extension
*/
class _Sparkpost
{
/**
* @deprecated
*
*@return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -6,13 +6,13 @@ namespace IPS\core\extensions\core\Dashboard;
class _IpsconnectMaster
{
public function canView()
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return FALSE;
}
public function getBlock()
{
return '';
return TRUE;
}
}
@@ -39,7 +39,7 @@ class _LatestNews
*/
public function getBlock()
{
//
}
/**
@@ -59,14 +59,15 @@ class _Admin
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return TRUE;
}
@@ -49,14 +49,15 @@ class _Announcement
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return TRUE;
}
@@ -54,9 +54,10 @@ class _Clubs
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
try
{
@@ -196,7 +197,7 @@ class _Clubs
if( count( $toUpdate ) )
{
\IPS\Db::i()->update( 'core_clubs_fieldvalues', $toUpdate, array( 'club_id=?', $clubFieldValues['member_id'] ) );
\IPS\Db::i()->update( 'core_clubs_fieldvalues', $toUpdate, array( 'club_id=?', $clubFieldValues['club_id'] ) );
}
}
@@ -53,14 +53,15 @@ class _CustomField
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return TRUE;
}
@@ -48,14 +48,15 @@ class _Members
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
try
{
@@ -48,14 +48,15 @@ class _Messaging
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
try
{
@@ -54,9 +54,10 @@ class _Meta
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
$data = \IPS\Db::i()->select( '*', 'core_content_meta', array( "meta_id=? AND meta_type=?", $id1, $id3 ) )->first();
@@ -64,10 +65,12 @@ class _Meta
if ( $item->container() )
{
if ( $item->container()->can( 'attachments', $member ) )
if ( !$item->canView( $member ) )
{
return $item->canView( $member );
return FALSE;
}
return $viewOnly or $item->container()->can( 'attachments', $member );
}
else
{
@@ -48,14 +48,15 @@ class _Modcp
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
if ( $member->modPermission( 'mod_see_warn' ) )
{
@@ -54,9 +54,10 @@ class _ProfileSteps
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return FALSE;
}
@@ -48,14 +48,15 @@ class _Reports
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return $member->modPermission( 'can_view_reports' );
}
@@ -53,9 +53,10 @@ class _ReviewResponses
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
try
{
@@ -48,14 +48,15 @@ class _ShareLinks
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return FALSE;
}
@@ -48,14 +48,15 @@ class _Signatures
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return TRUE;
}
@@ -48,14 +48,15 @@ class _Staffdirectory
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return TRUE;
}
@@ -61,9 +61,10 @@ class _Widget
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @param array $attachment The attachment data
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
{
return TRUE;
}
@@ -45,14 +45,14 @@ class _Promote
{
$data = \IPS\Db::i()->select( '*', 'core_social_promote', array( "promote_media != '[]' and promote_id >?", $offset ), 'promote_id', array( 0, 1 ) )->first();
$update = array();
foreach( json_decode( $data['promote_media'], TRUE ) as $location )
{
if ( $location )
{
try
{
\IPS\File::get( $oldConfiguration ?: 'core_Promote', $location )->move( $storageConfiguration );
$update[] = (string) \IPS\File::get( $oldConfiguration ?: 'core_Promote', $location )->move( $storageConfiguration );
}
catch( \Exception $e )
{
@@ -60,10 +60,14 @@ class _Promote
}
}
}
if ( $update )
{
\IPS\Db::i()->update( 'core_social_promote', array( 'promote_media' => json_encode( $update ), array( 'promote_id=?', $data['promote_id'] ) ) );
}
return $data['promote_id'];
}
/**
* Fix all URLs
*
@@ -72,14 +76,14 @@ class _Promote
*/
public function fixUrls( $offset )
{
$data = \IPS\Db::i()->select( '*', 'core_social_promote', array( "promote_media!=?", '[]' ), 'promote_id', array( 0, 1 ) )->first();
$data = \IPS\Db::i()->select( '*', 'core_social_promote', array( "promote_media!=?", '[]' ), 'promote_id', array( $offset, 1 ) )->first();
$fixed = array();
foreach( json_decode( $data['promote_media'], TRUE ) as $location )
{
if ( $new = \IPS\File::repairUrl( $location ) )
{
$fixed[] = $location;
$fixed[] = $new;
}
}
@@ -45,7 +45,13 @@ class _Reaction
{
$reaction = \IPS\Db::i()->select( '*', 'core_reactions', array(), 'reaction_id', array( $offset, 1 ) )->first();
\IPS\File::get( $oldConfiguration ?: 'core_Reaction', $reaction['reaction_icon'] )->move( $storageConfiguration );
$url = (string) \IPS\File::get( $oldConfiguration ?: 'core_Reaction', $reaction['reaction_icon'] )->move( $storageConfiguration );
if ( $url != $reaction['reaction_icon'] )
{
\IPS\Db::i()->update( 'core_reactions', array( 'reaction_icon' => $url ), array( 'reaction_id=?', $reaction['reaction_id'] ) );
unset( \IPS\Data\Store::i()->reactions );
}
}
/**
@@ -62,7 +68,7 @@ class _Reaction
return TRUE;
}
catch( \UunderflowException $e )
catch( \UnderflowException $e )
{
return FALSE;
}
@@ -48,7 +48,7 @@ class _Theme
*/
public function count()
{
return 5; // While this isn't the number of files, it's the number of steps this will take to move them, which is all it's used for
return 6; // While this isn't the number of files, it's the number of steps this will take to move them, which is all it's used for
}
/**
@@ -203,6 +203,27 @@ class _Theme
/* Trash new CSS and images */
\IPS\Theme::clearFiles( \IPS\Theme::TEMPLATES + \IPS\Theme::CSS + \IPS\Theme::IMAGES );
return TRUE;
case 5:
$settings = array();
foreach( \IPS\Application::applications() AS $app )
{
$settings = array_merge( $settings, $app->uploadSettings() );
}
foreach( $settings AS $key )
{
if ( \IPS\Settings::i()->$key )
{
try
{
\IPS\File::get( $oldConfiguration ?: 'core_Theme', \IPS\Settings::i()->$key )->move( $storageConfiguration );
}
catch( \Exception $e ) {}
}
}
throw new \UnderflowException;
default:
@@ -318,6 +339,28 @@ class _Theme
\IPS\Output::clearJsFiles();
/* All done */
return TRUE;
case 5:
$settings = array();
foreach( \IPS\Application::applications() AS $app )
{
$settings = array_merge( $settings, $app->uploadSettings() );
}
$update = array();
foreach( $settings AS $key )
{
if ( \IPS\Settings::i()->$key AND $new = \IPS\File::repairUrl( \IPS\Settings::i()->$key ) )
{
$update[ $key ] = $new;
}
}
if ( count( $update ) )
{
\IPS\Settings::i()->changeValues( $update );
}
throw new \UnderflowException;
}
}
@@ -403,6 +446,21 @@ class _Theme
}
}
}
/* Setting? */
$settings = array();
foreach( \IPS\Application::applications() AS $app )
{
$settings = array_merge( $settings, $app->uploadSettings() );
}
foreach( $settings AS $key )
{
if ( \IPS\Settings::i()->$key AND \IPS\Settings::i()->$key == (string) $file )
{
return TRUE;
}
}
/* Not found? Then must not be valid */
return FALSE;
@@ -53,7 +53,7 @@ class _Content
{
$form->add( new \IPS\Helpers\Form\Number( 'g_attach_max', $group->g_id ? $group->g_attach_max : 500000, FALSE, array( 'unlimited' => -1 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack( 'filesize_raw_k' ), 'g_attach_max' ) );
}
$form->add( new \IPS\Helpers\Form\Number( 'g_attach_per_post', $group->g_id ? $group->g_attach_per_post : 50000, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack( 'filesize_raw_k' ), 'g_attach_per_post' ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_attach_per_post', $group->g_id ? $group->g_attach_per_post : 50000, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack( 'g_attach_per_post_suffix' ), 'g_attach_per_post' ) );
if( $group->g_id != \IPS\Settings::i()->guest_group )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'gbw_delete_attachments', $group->g_bitoptions['gbw_delete_attachments'], FALSE, array(), NULL, NULL, NULL, 'gbw_delete_attachments' ) );
@@ -174,11 +174,10 @@ class _GroupSettings
/* Privacy */
$form->addHeader( 'group_privacy' );
if ( \IPS\Application\Module::get( 'core', 'online', 'front' )->visible )
if( $group->g_id != \IPS\Settings::i()->guest_group )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'g_hide_online_list', !$group->g_hide_online_list, FALSE, array(), NULL, NULL, NULL, 'g_hide_online_list' ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'g_hide_online_list', $group->g_hide_online_list, FALSE, array(), NULL, NULL, NULL, 'g_hide_online_list' ) );
}
$form->add( new \IPS\Helpers\Form\YesNo( 'gbw_hide_group', !$group->g_bitoptions['gbw_hide_group'], FALSE, array(), NULL, NULL, NULL, 'gbw_hide_group' ) );
if ( \IPS\Settings::i()->ignore_system_on )
@@ -286,10 +285,6 @@ class _GroupSettings
{
$group->g_search_flood = $values['g_search_flood'];
}
if ( isset( $values['g_hide_online_list'] ) )
{
$group->g_hide_online_list = !$values['g_hide_online_list'];
}
if ( isset( $values['gbw_hide_group'] ) )
{
@@ -301,6 +296,32 @@ class _GroupSettings
{
$group->g_bitoptions['gbw_cannot_be_ignored'] = !$values['can_be_ignored'];
}
/* Update existing sessions if this setting is changed */
if( isset( $values['g_hide_online_list'] ) AND $group->g_hide_online_list != (int) $values['g_hide_online_list'] )
{
/* We have to send a limit even though we want all records because otherwise the Database store does not return all columns */
foreach( \IPS\Session\Store::i()->getOnlineUsers( 0, 'desc', array( 0, 5000 ), $group->g_id, TRUE ) as $sessionData )
{
/* Set public sessions to Anonymous */
if( $values['g_hide_online_list'] == \IPS\Session\Front::LOGIN_TYPE_ANONYMOUS AND $sessionData['login_type'] != \IPS\Session\Front::LOGIN_TYPE_INCOMPLETE )
{
$sessionData['login_type'] = \IPS\Session\Front::LOGIN_TYPE_ANONYMOUS;
}
/* Set anonymous sessions to public */
elseif( $sessionData['login_type'] == \IPS\Session\Front::LOGIN_TYPE_ANONYMOUS )
{
$sessionData['login_type'] = \IPS\Session\Front::LOGIN_TYPE_MEMBER;
}
\IPS\Session\Store::i()->updateSession( $sessionData );
}
}
if ( isset( $values['g_hide_online_list'] ) )
{
$group->g_hide_online_list = $values['g_hide_online_list'];
}
}
/**
@@ -340,7 +361,7 @@ class _GroupSettings
}
catch ( \Exception $e )
{
$newGroup->icon = NULL;
$newGroup->g_icon = NULL;
}
$newGroup->save();
@@ -36,8 +36,10 @@ class _GroupLimits
'exclude' => array( 'g_id', 'g_icon', 'prefix', 'suffix', 'g_promotion', 'g_bitoptions' ),
'lessIsMore' => array( 'g_search_flood', 'g_pm_flood_mins' ),
'neg1IsBest' => array( 'g_attach_max', 'g_max_bgimg_upload', 'g_max_messages', 'g_pm_perday', 'g_pm_flood_mins', 'g_max_mass_pm', 'g_rep_max_positive' ),
'zeroIsBest' => array( 'g_edit_cutoff', 'g_displayname_unit', 'g_sig_unit', 'g_mod_preview', 'g_ppd_limit', 'g_ppd_unit', 'gbw_no_status_update', 'g_max_bgimg_upload', 'gbw_disable_prefixes', 'gbw_disable_tagging', 'g_attach_per_post' ),
'zeroIsBest' => array( 'g_displayname_unit', 'g_sig_unit', 'g_mod_preview', 'g_ppd_limit', 'g_ppd_unit', 'gbw_no_status_update', 'g_max_bgimg_upload', 'gbw_disable_prefixes', 'gbw_disable_tagging' ),
'callback' => array(
'g_edit_cutoff' => array( $this, '_editCutoff' ),
'g_attach_per_post' => array( $this, '_attachMaxPerPost' ),
'g_signature_limits' => array( $this, '_signatureLimits' ),
'g_photo_max_vars' => array( $this, '_photoVars' ),
'g_dname_date' => array( $this, '_displayNameDate' ),
@@ -50,10 +52,91 @@ class _GroupLimits
'g_lock_unlock_own' => array( $this, '_perAppSettings' ),
'g_can_report' => array( $this, '_perAppSettings' ),
'g_club_allowed_nodes' => array( $this, '_clubNodes' ),
'g_create_clubs' => array( $this, '_createClub' ),
)
);
}
/**
* Cutoff for editing - only use a group's value if the group is able to edit
*
* @param array $a Group A's values
* @param array $b Group B's values
* @param string $k The key we want to get the combined value for
* @param array $member Member data
* @return mixed
*/
public function _editCutoff( $a, $b, $k, $member )
{
$cutoff = array();
if( $a['g_edit_posts'] )
{
if( $a[ $k ] == 0 )
{
return 0;
}
else
{
$cutoff[] = $a[ $k ];
}
}
if( $b['g_edit_posts'] )
{
if( $b[ $k ] == 0 )
{
return 0;
}
else
{
$cutoff[] = $b[ $k ];
}
}
return \count( $cutoff ) ? max( $cutoff ) : 0;
}
/**
* Max per-content-item attachment storage space
*
* @param array $a Group A's values
* @param array $b Group B's values
* @param string $k The key we want to get the combined value for
* @param array $member Member data
* @return mixed
*/
public function _attachMaxPerPost( $a, $b, $k, $member )
{
$maxAttachments = array();
if( $a['g_attach_max'] !== 0 )
{
if( $a[ $k ] == 0 )
{
return 0;
}
else
{
$maxAttachments[] = $a[ $k ];
}
}
if( $b['g_attach_max'] !== 0 )
{
if( $b[ $k ] == 0 )
{
return 0;
}
else
{
$maxAttachments[] = $b[ $k ];
}
}
return \count( $maxAttachments ) ? max( $maxAttachments ) : 0;
}
/**
* Per-App Settings
*
@@ -241,7 +324,8 @@ class _GroupLimits
public function _displayNameChanges( $a, $b, $k, $member )
{
$changes = $b[ $k ];
$timeFrame = $a['g_dname_date'];
/* Get the most generous date allowance */
$timeFrame = max( array( $a['g_dname_date'], $b['g_dname_date'] ) );
if( $changes == -1 OR $a[ $k ] == -1 )
{
@@ -283,9 +367,15 @@ class _GroupLimits
/* Time frame restriction */
else if( $changes )
{
{
$_compare = round( $timeFrame / $changes );
/* If there are no permitted changes allowed for group A, but there is a date set (is is default, then clear the date for the logic below */
if ( ! $a[ $k ] and $a['g_dname_date'] )
{
$a['g_dname_date'] = 0;
}
/* Existing has no time frame restriction */
if( !$a['g_dname_date'] AND $a[ $k ] )
{
@@ -382,4 +472,26 @@ class _GroupLimits
return implode( ",", $nodeTypes );
}
/**
* Available club types
*
* @param array $a Group A's values
* @param array $b Group B's values
* @param string $k The key we want to get the combined value for
* @param array $member Member data
* @return mixed
*/
public function _createClub( $a, $b, $k, $member )
{
if ( $a[$k] == '*' or $b[$k] == '*' )
{
return '*';
}
/* Merge together all available club types */
$types = array_unique( array_merge( explode( ",", $a[$k] ), explode( ",", $b[$k] ) ) );
return implode( ",", $types );
}
}
@@ -66,6 +66,8 @@ class _ErrorLogs
$table->include = array( 'log_member', 'log_error_code', 'log_error', 'log_date', 'log_ip_address' );
$table->mainColumn = 'log_date';
$table->langPrefix = 'errorlogs_';
$table->widths = array( 'log_error_code' => 10, 'log_ip_address' => 10, 'log_request_uri' => 30, 'log_date' => 10, 'log_member' => 10 );
$table->rowClasses = array( 'log_error' => array( 'ipsTable_wrap' ), 'log_request_uri' => array( 'ipsTable_wrap' ) );
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'tables', 'core', 'admin' ), 'table' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'tables', 'core', 'admin' ), 'rows' );
@@ -90,7 +90,7 @@ class _Reports
try
{
$report = \IPS\core\Reports\Report::load( $row['rid'] );
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $report->url(), TRUE, $reort->mapped('title') );
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $report->url(), TRUE, $report->mapped('title') );
}
catch( \OutOfRangeException $e )
{
@@ -30,7 +30,7 @@ class _Members
public function hasAccess()
{
/* Check Permissions */
return \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_edit' );
return \IPS\Member::loggedIn()->hasAcpRestriction( "core","members" );
}
/**
@@ -32,21 +32,37 @@ class _BasicInformation extends \IPS\core\MemberACPProfile\Block
$hasPassword = FALSE;
$canChangePassword = \IPS\Login\Handler::findMethod( 'IPS\Login\Handler\Standard' );
$activeIntegrations = array();
foreach ( \IPS\Login::methods() as $method )
if ( \IPS\Member::loggedIn()->hasAcpRestriction('core', 'members', 'member_edit') )
{
if ( $method->canProcess( $this->member ) )
/* Is this an admin? */
if ( $this->member->isAdmin() AND !\IPS\Member::loggedIn()->hasAcpRestriction('core', 'members', 'member_edit_admin' ) )
{
if ( !( $method instanceof \IPS\Login\Handler\Standard ) )
$canChangePassword = FALSE;
}
if ( $canChangePassword !== FALSE )
{
foreach ( \IPS\Login::methods() as $method )
{
$activeIntegrations[] = $method->_title;
}
if ( $method->canChangePassword( $this->member ) )
{
$hasPassword = TRUE;
$canChangePassword = TRUE;
if ( $method->canProcess( $this->member ) )
{
if ( !( $method instanceof \IPS\Login\Handler\Standard ) )
{
$activeIntegrations[] = $method->_title;
}
if ( $method->canChangePassword( $this->member ) )
{
$hasPassword = TRUE;
$canChangePassword = TRUE;
}
}
}
}
}
else
{
$canChangePassword = FALSE;
}
$accountActions = array();
if ( \IPS\Member::loggedIn()->member_id != $this->member->member_id AND \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_login' ) AND !$this->member->isBanned() )
@@ -78,6 +94,16 @@ class _BasicInformation extends \IPS\core\MemberACPProfile\Block
);
}
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_export_pi' ) )
{
$accountActions[] = array(
'title' => 'member_export_pi_title',
'icon' => 'download',
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=exportPersonalInfo&id={$this->member->member_id}" ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('member_export_pi_title') )
);
}
$activeSubscription = FALSE;
if ( \IPS\Application::appIsEnabled('nexus') and \IPS\Settings::i()->nexus_subs_enabled ) // I know... this should really be a hook... I won't tell if you won't
{
@@ -138,7 +138,7 @@ class _Header extends \IPS\core\MemberACPProfile\Block
}
elseif ( \IPS\Settings::i()->reputation_enabled and \IPS\Request::i()->type == 'reputation' )
{
$form->add( new \IPS\Helpers\Form\Number( 'member_reputation', $this->member->pp_reputation_points, FALSE ) );
$form->add( new \IPS\Helpers\Form\Number( 'member_reputation', $this->member->pp_reputation_points, FALSE, array( 'min' => NULL ) ) );
}
else
{
@@ -30,7 +30,7 @@ class _Locations extends \IPS\core\MemberACPProfile\LazyLoadingBlock
public function lazyOutput()
{
$mapMarkers = array();
if ( \IPS\Settings::i()->ipsgeoip and \IPS\Settings::i()->googlemaps and \IPS\Settings::i()->google_maps_api_key )
if ( \IPS\Settings::i()->ipsgeoip and \IPS\GeoLocation::enabled() )
{
foreach ( \IPS\Db::i()->select( 'DISTINCT ip_address', 'core_members_known_ip_addresses', array( 'member_id=?', $this->member->member_id ) ) as $ipAddress )
{
@@ -50,7 +50,7 @@ class _LoginMethods extends \IPS\core\MemberACPProfile\LazyLoadingBlock
{
continue;
}
if ( $option == 'status' and ( !$this->member->canAccessModule( \IPS\Application\Module::get( 'core', 'status' ) ) or !\IPS\core\Statuses\Status::canCreateFromCreateMenu( $this->member ) or !\IPS\Settings::i()->profile_comments or $this->member->group['gbw_no_status_update'] ) )
if ( $option == 'status' and ( !$this->member->canAccessModule( \IPS\Application\Module::get( 'core', 'status', 'front' ) ) or !\IPS\core\Statuses\Status::canCreateFromCreateMenu( $this->member ) or !\IPS\Settings::i()->profile_comments or $this->member->group['gbw_no_status_update'] ) )
{
continue;
}
@@ -29,13 +29,23 @@ class _Main extends \IPS\core\MemberACPProfile\MainTab
*/
public function leftColumnBlocks()
{
return array(
'IPS\core\extensions\core\MemberACPProfileBlocks\BasicInformation',
'IPS\core\extensions\core\MemberACPProfileBlocks\Groups',
'IPS\core\extensions\core\MemberACPProfileBlocks\DevicesAndIPAddresses',
'IPS\core\extensions\core\MemberACPProfileBlocks\MFA',
'IPS\core\extensions\core\MemberACPProfileBlocks\OAuth'
);
$return = array();
$return[] = 'IPS\core\extensions\core\MemberACPProfileBlocks\BasicInformation';
$return[] = 'IPS\core\extensions\core\MemberACPProfileBlocks\Groups';
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'membertools_ip' ) )
{
$return[] = 'IPS\core\extensions\core\MemberACPProfileBlocks\DevicesAndIPAddresses';
}
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_mfa' ) )
{
$return[] = 'IPS\core\extensions\core\MemberACPProfileBlocks\MFA';
}
$return[] = 'IPS\core\extensions\core\MemberACPProfileBlocks\OAuth';
return $return;
}
/**
@@ -0,0 +1,115 @@
<?php
/**
* @brief ACP Export Personal Information
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 15 May 2018
*/
namespace IPS\core\extensions\core\MemberExportPersonalInformation;
/* 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;
}
/**
* @brief ACP Export Personal Information
*/
class _Main
{
/**
* Return data
* @param \IPS\Member $member The member
*
* @return array
*/
public function getData( \IPS\Member $member )
{
$return = array();
/* Basic Data */
$columns = array(
'name',
'email',
'joined',
'ip_address',
'timezone',
'last_visit',
'last_post',
'birthday',
'allow_admin_mails',
'member_title'
);
foreach( $columns as $col )
{
$val = NULL;
switch( $col )
{
case 'last_visit':
case 'last_post':
$val = ( ! empty( $member->$col ) ) ? \IPS\DateTime::ts( $member->$col )->rfc3339() : NULL;
break;
case 'joined':
$val = $member->joined->rfc3339();
break;
default:
$val = (string) $member->$col;
break;
}
$return['core'][ $col ] = $val;
}
/* Known IP addresses stored */
$return['known_ip_addresses'] = array_keys( $member->ipAddresses() );
/* Devices used */
$devices = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_members_known_devices', array( 'member_id=? AND last_seen>?', $member->member_id, ( new \DateTime )->sub( new \DateInterval( \IPS\Member\Device::LOGIN_KEY_VALIDITY ) )->getTimestamp() ), 'last_seen DESC' ), 'IPS\Member\Device' );
foreach ( $devices as $device )
{
try
{
$log = \IPS\Db::i()->select( '*', 'core_members_known_ip_addresses', array( 'member_id=? AND device_key=?', \IPS\Member::loggedIn()->member_id, $device->device_key ), 'last_seen DESC' )->first();
}
catch ( \UnderflowException $e )
{
continue;
}
$return['known_browsers'][] = array(
'useragent' => $device->userAgent()->browser . ' ' . $device->userAgent()->browserVersion,
'last_seen' => \IPS\DateTime::ts( $log['last_seen'] )->rfc3339()
);
}
/* Accepted T&S */
foreach( \IPS\Db::i()->select( '*', 'core_member_history', array( 'log_app=? and log_member=? and log_type=?', 'core', $member->member_id, 'terms_acceptance' ) ) as $row )
{
$data = json_decode( $row['log_data'], TRUE );
if ( ! empty( $data['type'] ) )
{
$return['terms_accepted'][ $data['type'] ][] = \IPS\DateTime::ts( $row['log_date'] )->rfc3339();
}
}
/* Accepted Bulk Email */
foreach( \IPS\Db::i()->select( '*', 'core_member_history', array( 'log_app=? and log_member=? and log_type=?', 'core', $member->member_id, 'admin_mails' ) ) as $row )
{
$data = json_decode( $row['log_data'], TRUE );
$return['bulk_mail_optins'][] = array(
'enabled' => (boolean) $data['enabled'],
'date' => \IPS\DateTime::ts( $row['log_date'] )->rfc3339()
);
}
return $return;
}
}
@@ -0,0 +1,86 @@
<?php
/**
* @brief Member filter extension: Bulk mail filter
* @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 31 July 2018
*/
namespace IPS\core\extensions\core\MemberFilter;
/* 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;
}
/**
* @brief Member filter: Bulk mail filter
*/
class _Bulkmail
{
/**
* Determine if the filter is available in a given area
*
* @param string $area Area to check
* @return bool
*/
public function availableIn( $area )
{
return \in_array( $area, array( 'group_promotions' ) );
}
/**
* Get Setting Field
*
* @param mixed $criteria Value returned from the save() method
* @return array Array of form elements
*/
public function getSettingField( $criteria )
{
$options = array( 'any' => 'any', 'on' => 'member_filter_bulk_mail_on', 'off' => 'member_filter_bulk_mail_off' );
return array(
new \IPS\Helpers\Form\Radio( 'member_filter_bulk_mail', isset( $criteria['bulk_mail'] ) ? $criteria['bulk_mail'] : 'any', FALSE, array( 'options' => $options ) ),
);
}
/**
* Save the filter data
*
* @param array $post Form values
* @return mixed False, or an array of data to use later when filtering the members
* @throws \LogicException
*/
public function save( $post )
{
return ( isset( $post['member_filter_bulk_mail'] ) and \in_array( $post['member_filter_bulk_mail'], array( 'on', 'off' ) ) ) ? array( 'bulk_mail' => $post['member_filter_bulk_mail'] ) : FALSE;
}
/**
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
if ( isset( $data['bulk_mail'] ) )
{
switch ( $data['bulk_mail'] )
{
case 'on':
return array( "allow_admin_mails=1" );
break;
case 'off':
return array( "allow_admin_mails=0" );
break;
}
}
return NULL;
}
}
@@ -83,7 +83,7 @@ class _Content
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return string|array|NULL Where clause
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
@@ -92,13 +92,13 @@ class _Content
switch ( $data['content_count_operator'] )
{
case 'gt':
return array( array( "member_posts>?", (int) $data['content_count_score'] ) );
return array( "member_posts>?", (int) $data['content_count_score'] );
break;
case 'lt':
return array( array( "member_posts<?", (int) $data['content_count_score'] ) );
return array( "member_posts<?", (int) $data['content_count_score'] );
break;
case 'eq':
return array( array( "member_posts=?", (int) $data['content_count_score'] ) );
return array( "member_posts=?", (int) $data['content_count_score'] );
break;
}
}
@@ -121,7 +121,7 @@ class _Group
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return string|array|NULL Where clause
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
@@ -137,7 +137,7 @@ class _Group
if( count($_set) )
{
return "( member_group_id IN(" . $data['groups'] . ") OR " . implode( ' OR ', $_set ) . ' )';
return array( "( member_group_id IN(" . $data['groups'] . ") OR " . implode( ' OR ', $_set ) . ' )' );
}
}
@@ -72,11 +72,15 @@ class _Joined
{
return $post['bmf_members_joined'][3] ? array( 'days_lt' => intval( $post['bmf_members_joined'][3] ) ) : FALSE;
}
elseif( $post['bmf_members_joined'][2] == 'range' )
{
return ( empty( $post['bmf_members_joined'][0] ) OR empty( $post['bmf_members_joined'][0]['start'] ) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['bmf_members_joined'][0] ), TRUE ) );
}
}
else
{
/* Normalize objects to their array form. Bulk mailer stores options as a json array where as member export does not, so $data['range']['start'] is a DateTime object */
return ( empty($post['bmf_members_joined'][0]) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['bmf_members_joined'][0] ), TRUE ) );
return ( empty( $post['bmf_members_joined'][0] ) OR empty( $post['bmf_members_joined'][0]['start'] ) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['bmf_members_joined'][0] ), TRUE ) );
}
}
@@ -84,31 +88,56 @@ class _Joined
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return string|array|NULL Where clause
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
if( !empty($data['range']) AND !empty($data['range']['end']) )
{
$start = ( $data['range']['start'] ) ? new \IPS\DateTime( $data['range']['start'] ) : NULL;
$end = ( $data['range']['end'] ) ? new \IPS\DateTime( $data['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $data['range']['start'] )
{
try
{
/* Try just what is stored */
$start = new \IPS\DateTime( $data['range']['start'] );
}
catch( \Exception $e )
{
/* If there was an error, try dashes so DateTime will assume European dates. @see <a href='http://php.net/manual/en/function.strtotime.php#refsect1-function.strtotime-notes'>PHP Documentation</a> */
$start = new \IPS\DateTime( str_replace( '/', '-', $data['range']['start'] ) );
}
}
if ( $data['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $data['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $data['range']['end'] ) );
}
}
if( $start and $end )
{
return "core_members.joined BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}";
return array( "core_members.joined BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}" );
}
}
elseif( !empty( $data['days'] ) AND (int) $data['days'] )
{
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days'] . 'D' ) );
return "core_members.joined < {$date->getTimestamp()}";
return array( "core_members.joined < {$date->getTimestamp()}" );
}
elseif( !empty( $data['days_lt'] ) AND (int) $data['days_lt'] )
{
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days_lt'] . 'D' ) );
return "core_members.joined > {$date->getTimestamp()}";
return array( "core_members.joined > {$date->getTimestamp()}" );
}
return NULL;
@@ -136,8 +165,32 @@ class _Joined
if( !empty( $filters['range'] ) AND !empty( $filters['range']['end'] ) )
{
$start = ( $filters['range']['start'] ) ? new \IPS\DateTime( $filters['range']['start'] ) : NULL;
$end = ( $filters['range']['end'] ) ? new \IPS\DateTime( $filters['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $filters['range']['start'] )
{
try
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
catch( \Exception $e )
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
}
if ( $filters['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $filters['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $filters['range']['end'] ) );
}
}
if( $start and $end )
{
@@ -160,8 +213,32 @@ class _Joined
{
if( !empty( $filters['range'] ) AND !empty( $filters['range']['end'] ) )
{
$start = ( $filters['range']['start'] ) ? new \IPS\DateTime( $filters['range']['start'] ) : NULL;
$end = ( $filters['range']['end'] ) ? new \IPS\DateTime( $filters['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $filters['range']['start'] )
{
try
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
catch( \Exception $e )
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
}
if ( $filters['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $filters['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $filters['range']['end'] ) );
}
}
if ( $start and $end )
{
@@ -72,11 +72,15 @@ class _Lastpost
{
return $post['mf_members_last_post'][3] ? array( 'days_lt' => intval( $post['mf_members_last_post'][3] ) ) : FALSE;
}
elseif( $post['mf_members_last_post'][2] == 'range' )
{
return ( empty( $post['mf_members_last_post'][0] ) OR empty( $post['mf_members_last_post'][0]['start'] ) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['mf_members_last_post'][0] ), TRUE ) );
}
}
else
{
/* Normalize objects to their array form. Bulk mailer stores options as a json array where as member export does not, so $data['range']['start'] is a DateTime object */
return ( empty($post['mf_members_last_post'][0]) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['mf_members_last_post'][0] ), TRUE ) );
return ( empty( $post['mf_members_last_post'][0] ) OR empty( $post['mf_members_last_post'][0]['start'] ) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['mf_members_last_post'][0] ), TRUE ) );
}
}
@@ -84,31 +88,56 @@ class _Lastpost
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return string|array|NULL Where clause
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
if( !empty($data['range']) AND !empty($data['range']['end']) )
{
$start = ( $data['range']['start'] ) ? new \IPS\DateTime( $data['range']['start'] ) : NULL;
$end = ( $data['range']['end'] ) ? new \IPS\DateTime( $data['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $data['range']['start'] )
{
try
{
/* Try just what is stored */
$start = new \IPS\DateTime( $data['range']['start'] );
}
catch( \Exception $e )
{
/* If there was an error, try dashes so DateTime will assume European dates. @see <a href='http://php.net/manual/en/function.strtotime.php#refsect1-function.strtotime-notes'>PHP Documentation</a> */
$start = new \IPS\DateTime( str_replace( '/', '-', $data['range']['start'] ) );
}
}
if ( $data['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $data['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $data['range']['end'] ) );
}
}
if( $start and $end )
{
return "core_members.member_last_post BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}";
return array( "core_members.member_last_post BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}" );
}
}
elseif( !empty( $data['days'] ) AND (int) $data['days'] )
{
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days'] . 'D' ) );
return "( core_members.member_last_post < {$date->getTimestamp()} OR core_members.member_last_post IS NULL )";
return array( "( core_members.member_last_post < {$date->getTimestamp()} OR core_members.member_last_post IS NULL )" );
}
elseif( !empty( $data['days_lt'] ) AND (int) $data['days_lt'] )
{
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days_lt'] . 'D' ) );
return "( core_members.member_last_post > {$date->getTimestamp()} )";
return array( "( core_members.member_last_post > {$date->getTimestamp()} )" );
}
@@ -150,8 +179,32 @@ class _Lastpost
if( !empty( $filters['range'] ) AND !empty( $filters['range']['end'] ) )
{
$start = ( $filters['range']['start'] ) ? new \IPS\DateTime( $filters['range']['start'] ) : NULL;
$end = ( $filters['range']['end'] ) ? new \IPS\DateTime( $filters['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $filters['range']['start'] )
{
try
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
catch( \Exception $e )
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
}
if ( $filters['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $filters['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $filters['range']['end'] ) );
}
}
if( $start and $end )
{
@@ -174,8 +227,32 @@ class _Lastpost
{
if( !empty( $filters['range'] ) AND !empty( $filters['range']['end'] ) )
{
$start = ( $filters['range']['start'] ) ? new \IPS\DateTime( $filters['range']['start'] ) : NULL;
$end = ( $filters['range']['end'] ) ? new \IPS\DateTime( $filters['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $filters['range']['start'] )
{
try
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
catch( \Exception $e )
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
}
if ( $filters['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $filters['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $filters['range']['end'] ) );
}
}
if ( $start and $end )
{
@@ -72,11 +72,15 @@ class _Lastvisit
{
return $post['bmf_members_last_visit'][3] ? array( 'days_lt' => intval( $post['bmf_members_last_visit'][3] ) ) : FALSE;
}
elseif( $post['bmf_members_last_visit'][2] == 'range' )
{
return ( empty( $post['bmf_members_last_visit'][0] ) OR empty( $post['bmf_members_last_visit'][0]['start'] ) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['bmf_members_last_visit'][0] ), TRUE ) );
}
}
else
{
/* Normalize objects to their array form. Bulk mailer stores options as a json array where as member export does not, so $data['range']['start'] is a DateTime object */
return ( empty($post['bmf_members_last_visit'][0]) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['bmf_members_last_visit'][0] ), TRUE ) );
return ( empty( $post['bmf_members_last_visit'][0] ) OR empty( $post['bmf_members_last_visit'][0]['start'] ) ) ? FALSE : array( 'range' => json_decode( json_encode( $post['bmf_members_last_visit'][0] ), TRUE ) );
}
}
@@ -84,31 +88,56 @@ class _Lastvisit
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return string|array|NULL Where clause
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
if( !empty($data['range']) AND !empty($data['range']['end']) )
{
$start = ( $data['range']['start'] ) ? new \IPS\DateTime( $data['range']['start'] ) : NULL;
$end = ( $data['range']['end'] ) ? new \IPS\DateTime( $data['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $data['range']['start'] )
{
try
{
/* Try just what is stored */
$start = new \IPS\DateTime( $data['range']['start'] );
}
catch( \Exception $e )
{
/* If there was an error, try dashes so DateTime will assume European dates. @see <a href='http://php.net/manual/en/function.strtotime.php#refsect1-function.strtotime-notes'>PHP Documentation</a> */
$start = new \IPS\DateTime( str_replace( '/', '-', $data['range']['start'] ) );
}
}
if ( $data['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $data['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $data['range']['end'] ) );
}
}
if( $start and $end )
{
return "core_members.last_visit BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}";
return array( "core_members.last_activity BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}" );
}
}
elseif( !empty( $data['days'] ) AND (int) $data['days'] )
{
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days'] . 'D' ) );
return "core_members.last_visit < {$date->getTimestamp()}";
return array( "core_members.last_activity < {$date->getTimestamp()}" );
}
elseif( !empty( $data['days_lt'] ) AND (int) $data['days_lt'] )
{
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days_lt'] . 'D' ) );
return "core_members.last_visit > {$date->getTimestamp()}";
return array( "core_members.last_activity > {$date->getTimestamp()}" );
}
return NULL;
@@ -135,8 +164,32 @@ class _Lastvisit
if( !empty( $filters['range'] ) AND !empty( $filters['range']['end'] ) )
{
$start = ( $filters['range']['start'] ) ? new \IPS\DateTime( $filters['range']['start'] ) : NULL;
$end = ( $filters['range']['end'] ) ? new \IPS\DateTime( $filters['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $filters['range']['start'] )
{
try
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
catch( \Exception $e )
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
}
if ( $filters['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $filters['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $filters['range']['end'] ) );
}
}
if( $start and $end )
{
@@ -159,8 +212,32 @@ class _Lastvisit
{
if( !empty( $filters['range'] ) AND !empty( $filters['range']['end'] ) )
{
$start = ( $filters['range']['start'] ) ? new \IPS\DateTime( $filters['range']['start'] ) : NULL;
$end = ( $filters['range']['end'] ) ? new \IPS\DateTime( $filters['range']['end'] ) : NULL;
$start = NULL;
$end = NULL;
if ( $filters['range']['start'] )
{
try
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
catch( \Exception $e )
{
$start = new \IPS\DateTime( $filters['range']['start'] );
}
}
if ( $filters['range']['end'] )
{
try
{
$end = new \IPS\DateTime( $filters['range']['end'] );
}
catch( \Exception $e )
{
$end = new \IPS\DateTime( str_replace( '/', '-', $filters['range']['end'] ) );
}
}
if ( $start and $end )
{
@@ -64,14 +64,14 @@ class _Leaderboard
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return string|array|NULL Where clause
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
if( isset( $data['leaderboard'] ) )
{
$leaderBoardSelect = \IPS\Db::i()->select( 'leader_member_id', 'core_reputation_leaderboard_history', 'leader_position=1', NULL, NULL, NULL, NULL, \IPS\Db::SELECT_DISTINCT );
return ( $data['leaderboard'] == 'active' ) ? array( array( 'core_members.member_id IN(' . $leaderBoardSelect . ')' ) ) : array( array( 'core_members.member_id NOT IN(' . $leaderBoardSelect . ')' ) );
return ( $data['leaderboard'] == 'active' ) ? array( 'core_members.member_id IN(' . $leaderBoardSelect . ')' ) : array( 'core_members.member_id NOT IN(' . $leaderBoardSelect . ')' );
}
return NULL;
@@ -1,4 +1,31 @@
<?php
/**
* @brief Member filter extension
* @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 5 Apr 2017
*/
// Removed
namespace IPS\core\extensions\core\MemberFilter;
/* 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;
}
class _Linkedaccounts
{
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -0,0 +1,86 @@
<?php
/**
* @brief Member filter extension: Name
* @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 14 May 2018
*/
namespace IPS\core\extensions\core\MemberFilter;
/* 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;
}
/**
* @brief Member filter: Name
*/
class _Name
{
/**
* Determine if the filter is available in a given area
*
* @param string $area Area to check
* @return bool
*/
public function availableIn( $area )
{
return in_array( $area, array( 'bulkmail' ) );
}
/**
* Get Setting Field
*
* @param mixed $criteria Value returned from the save() method
* @return array Array of form elements
*/
public function getSettingField( $criteria )
{
$options = array( 'any' => 'mf_name_whatever', 'yes' => 'mf_name_yes', 'no' => 'mf_name_no' );
return array(
new \IPS\Helpers\Form\Radio( 'mf_name', isset( $criteria['mf_name'] ) ? $criteria['mf_name'] : 'yes', FALSE, array( 'options' => $options ) ),
);
}
/**
* Save the filter data
*
* @param array $post Form values
* @return mixed False, or an array of data to use later when filtering the members
* @throws \LogicException
*/
public function save( $post )
{
return ( isset( $post['mf_name'] ) and in_array( $post['mf_name'], array( 'yes', 'no' ) ) ) ? array( 'mf_name' => $post['mf_name'] ) : FALSE;
}
/**
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
if ( isset( $data['mf_name'] ) )
{
switch ( $data['mf_name'] )
{
case 'yes':
return array( "core_members.name <> ''" );
break;
case 'no':
return array( "core_members.name = ''" );
break;
}
}
return NULL;
}
}
@@ -83,7 +83,7 @@ class _Reputation
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return string|array|NULL Where clause
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
@@ -92,13 +92,13 @@ class _Reputation
switch ( $data['reputation_operator'] )
{
case 'gt':
return array( array( "pp_reputation_points>?", (int) $data['reputation_score'] ) );
return array( "pp_reputation_points>?", (int) $data['reputation_score'] );
break;
case 'lt':
return array( array( "pp_reputation_points<?", (int) $data['reputation_score'] ) );
return array( "pp_reputation_points<?", (int) $data['reputation_score'] );
break;
case 'eq':
return array( array( "pp_reputation_points=?", (int) $data['reputation_score'] ) );
return array( "pp_reputation_points=?", (int) $data['reputation_score'] );
break;
}
}
@@ -64,7 +64,7 @@ class _Twofactor
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @return string|array|NULL Where clause
* @return array|NULL Where clause - must be a single array( "clause", ...binds )
*/
public function getQueryWhereClause( $data )
{
@@ -73,10 +73,10 @@ class _Twofactor
switch ( $data['two_factor'] )
{
case 'active':
return array( array( "mfa_details IS NOT NULL AND mfa_details !=?", "[]" ) );
return array( "mfa_details IS NOT NULL AND mfa_details !=?", "[]" );
break;
case 'inactive':
return array( array( "( mfa_details IS NULL OR mfa_details =? )", "[]" ) );
return array( "( mfa_details IS NULL OR mfa_details =? )", "[]" );
break;
}
}
@@ -8,4 +8,24 @@
* @since 08 Apr 2013
*/
// Removed
namespace IPS\core\extensions\core\MemberForm;
/* 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;
}
class _BasicInformation
{
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -8,4 +8,24 @@
* @since 08 Apr 2013
*/
// Removed
namespace IPS\core\extensions\core\MemberForm;
/* 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;
}
class _Profile
{
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -1,3 +1,31 @@
<?php
/**
* @brief Admin CP Member Form
* @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 08 Apr 2013
*/
// Removed
namespace IPS\core\extensions\core\MemberForm;
/* 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;
}
class _Restrictions
{
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -1,11 +1,31 @@
<?php
/**
* @brief Admin CP Member Form: MFA
* @brief Admin CP Member Form
* @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 28 Sep 2016
* @since 08 Apr 2013
*/
// Removed
namespace IPS\core\extensions\core\MemberForm;
/* 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;
}
class _SecurityAnswers
{
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -260,7 +260,7 @@ class _Core
}
catch ( \Exception $e )
{
$device = $jsonValue['device'];
$device = htmlspecialchars( $jsonValue['device'], ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE );
}
if ( $jsonValue['type'] == 'new_device' )
{
@@ -382,7 +382,7 @@ class _Core
$account = NULL;
$link = NULL;
if ( $handler and isset( $jsonValue['account_id'] ) or isset( $jsonValue['account_name'] ) )
if ( $handler and ( isset( $jsonValue['account_id'] ) or isset( $jsonValue['account_name'] ) ) )
{
$account = $jsonValue['account_name'];
if ( $link = $handler->userLink( $jsonValue['account_id'], $jsonValue['account_name'] ) )
@@ -419,7 +419,7 @@ class _Core
case 'account':
$spamDefenseScore = NULL;
if ( isset( $jsonValue['spamCode'] ) )
if ( isset( $jsonValue['spamCode'] ) AND isset( $jsonValue['spamAction'] ) )
{
$spamDefenseScore = \IPS\Member::loggedIn()->language()->addToStack( 'history_spam_defense_' . $jsonValue['spamAction'], FALSE, array( 'sprintf' => array( $jsonValue['spamCode'] ) ) );
}
@@ -101,7 +101,8 @@ class _Content extends \IPS\core\MemberACPProfile\Restriction
$c = \IPS\Member::loggedIn()->language()->addToStack( 'moderation_' . $k );
if ( $changes[ $v ]['new'] != -1 )
{
$c = \IPS\Member::loggedIn()->language()->addToStack( 'history_received_warning_penalty_time', FALSE, array( 'sprintf' => array( $c, \IPS\DateTime::formatInterval( new \DateInterval( $changes[ $v ]['new'] ), 2 ) ) ) );
$interval = \IPS\DateTime::formatInterval( ( is_numeric( $changes[ $v ]['new'] ) ) ? \IPS\DateTime::create()->diff( \IPS\DateTime::ts( $changes[ $v ]['new'] ) ) : new \DateInterval( $changes[ $v ]['new'] ), 2 );
$c = \IPS\Member::loggedIn()->language()->addToStack( 'history_received_warning_penalty_time', FALSE, array( 'sprintf' => array( $c, $interval ) ) );
}
}
else
@@ -6,5 +6,13 @@ namespace IPS\core\extensions\core\MemberSync;
class _History
{
public function __construct() { }
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -6,5 +6,13 @@ namespace IPS\core\extensions\core\MemberSync;
class _ipsconnect
{
public function __construct() { }
/**
* @deprecated
*
* @return bool
*/
final public function deprecated()
{
return TRUE;
}
}
@@ -81,8 +81,8 @@ class _Reports extends \IPS\Content\Controller
/* fetch only reports for content of enabled applications */
$where .= " AND " . \IPS\Db::i()->in( 'class', array_merge( array( 'IPS\core\Messenger\Conversation', 'IPS\core\Messenger\Message' ), array_values( \IPS\Content::routedClasses( FALSE, TRUE ) ) ) );
$table = new \IPS\Helpers\Table\Content( '\IPS\core\Reports\Report', \IPS\Http\Url::internal( 'app=core&module=modcp&controller=modcp&tab=reports', NULL, 'modcp_reports' ), array( array( $where, \IPS\Db::i()->select( 'perm_id', 'core_permission_index', \IPS\Db::i()->findInSet( 'perm_view', array_merge( array( \IPS\Member::loggedIn()->member_group_id ), array_filter( explode( ',', \IPS\Member::loggedIn()->mgroup_others ) ) ) ) . " OR perm_view='*'" ) ) ) );
$table = new \IPS\Helpers\Table\Content( '\IPS\core\Reports\Report', \IPS\Http\Url::internal( 'app=core&module=modcp&controller=modcp&tab=reports', NULL, 'modcp_reports' ), array( array( $where, \IPS\Db::i()->select( 'perm_id', 'core_permission_index', \IPS\Db::i()->findInSet( 'perm_view', \IPS\Member::loggedIn()->permissionArray() ) . " OR perm_view='*'" ) ) ) );
$table->sortBy = $table->sortBy ?: 'first_report_date';
$table->sortDirection = 'desc';
@@ -29,7 +29,7 @@ class _Warnings
*/
public function getTab()
{
if ( ! \IPS\Member::loggedIn()->modPermission('mod_see_warn') )
if ( ! \IPS\Member::loggedIn()->modPermission('mod_see_warn') OR ! \IPS\Settings::i()->warn_on )
{
return null;
}
@@ -101,9 +101,17 @@ class _Content
throw new \OutOfRangeException;
}
/* If the content item is queued for deletion, add the query string parameter so we can see it */
$url = $notification->item->url();
if( $notification->item->hidden() == -2 )
{
$url = $url->setQueryString( 'showDeleted', 1 );
}
return array(
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'notification__new_content', FALSE, array( 'sprintf' => array( $item->author()->name, mb_strtolower( $item->indefiniteArticle() ), $item->searchIndexContainerClass()->_title, $item->mapped('title') ) ) ),
'url' => $notification->item->url(),
'url' => $url,
'content' => $notification->item->content(),
'author' => $notification->item->author(),
'unread' => (bool) ( $item->unread() )
@@ -263,6 +271,14 @@ class _Content
}
$comment = $commentClass::loadAndCheckPerms( $notification->item_sub_id );
/* If the comment is in the deletion queue, add the showDeleted=1 parameter otherwise it just won't show up */
$url = $comment->url('find');
if( $comment->hidden() == -2 )
{
$url = $url->setQueryString( 'showDeleted', 1 );
}
/* Unread? */
$unread = false;
@@ -273,7 +289,7 @@ class _Content
return array(
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'notification__new_comment', FALSE, array( 'pluralize' => array( count( $commenters ) ), 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $names ), $item->mapped('title') ) ) ),
'url' => $comment->url('find'),
'url' => $url,
'content' => $comment->content(),
'author' => $comment->author(),
'unread' => $unread,
@@ -173,6 +173,17 @@ class _Core
$src = $image->getAttribute('src');
\IPS\Output::i()->parseFileObjectUrls( $src );
$imageProperties = @getimagesize( $src );
/* getimagesize failed so let's try to use getimagesizefromstring */
if( !$imageProperties )
{
try
{
$image = \IPS\Http\Url::external( $src )->request()->get();
$imageProperties = getimagesizefromstring( $image->content );
}
catch ( \IPS\Http\Request\Exception $e ) {}
}
}
if( is_array( $imageProperties ) AND count( $imageProperties ) )
@@ -300,11 +311,11 @@ class _Core
if ( $newPhoto->file )
{
$member->logHistory( 'core', 'photo', array( 'coverphoto' => 'new' ) );
$member->logHistory( 'core', 'coverphoto', array( 'action' => 'new' ) );
}
else
{
$member->logHistory( 'core', 'photo', array( 'coverphoto' => 'remove' ) );
$member->logHistory( 'core', 'coverphoto', array( 'action' => 'remove' ) );
}
}
@@ -341,7 +352,7 @@ class _Core
{
return \IPS\Login\Handler::load( $item )->canProcess( static::$_member );
}
catch ( \OutOfRangeExcetpion $e )
catch ( \OutOfRangeException $e )
{
return TRUE;
}
@@ -683,7 +694,24 @@ class _Core
}
}, NULL, NULL, 'member_photo_upload' ) );
$form->add( new \IPS\Helpers\Form\Url( 'member_photo_url', NULL, FALSE, array( 'file' => 'core_Profile', 'allowedMimes' => 'image/*', 'maxFileSize' => $photoVars[0] ? $photoVars[0] / 1024 : NULL, 'maxDimensions' => array( 'width' => $photoVars[1], 'height' => $photoVars[2] ) ), NULL, NULL, NULL, 'member_photo_url' ) );
$form->add( new \IPS\Helpers\Form\Url( 'member_photo_url', NULL, FALSE, array( 'file' => 'core_Profile', 'allowedMimes' => 'image/*', 'maxFileSize' => $photoVars[0] ? $photoVars[0] / 1024 : NULL, 'maxDimensions' => array( 'width' => $photoVars[1], 'height' => $photoVars[2] ) ), function( $val ) use ( $member ){
if ( $val instanceof \IPS\Http\Url )
{
try
{
$image = \IPS\Image::create( (string) $val->request()->get() );
}
catch ( \InvalidArgumentException $e )
{
throw new \DomainException('member_photo_bad_url');
}
if( $image->isAnimatedGif and !$member->group['g_upload_animated_photos'] )
{
throw new \DomainException('member_photo_upload_no_animated');
}
}
}, NULL, NULL, 'member_photo_url' ) );
}
foreach ( $extra as $element )
@@ -88,9 +88,18 @@ class _Bulkmail
$content = str_replace( $k, '*|' . str_replace( array( '{', '}' ), '', $k ) . '|*', $content );
}
}
/* Format content */
$content = \IPS\Email::staticParseTextForEmail( $content, \IPS\Lang::load( \IPS\Lang::defaultLanguage() ) );
foreach( array_keys( \IPS\core\BulkMail\Bulkmailer::getTags() ) as $k )
{
$content = str_replace( '%7B' . mb_substr( $k, 1, -1 ) . '%7D', '*|' . mb_substr( $k, 1, -1 ) . '|*', $content );
$content = str_replace( '*%7' . mb_substr( $k, 1, -1 ) . '%7C*', '*|' . mb_substr( $k, 1, -1 ) . '|*', $content );
}
/* Send it */
$email = \IPS\Email::buildFromContent( $mail->subject, \IPS\Email::staticParseTextForEmail( $content, \IPS\Lang::load( \IPS\Lang::defaultLanguage() ) ), NULL, \IPS\Email::TYPE_BULK )
$email = \IPS\Email::buildFromContent( $mail->subject, $content, NULL, \IPS\Email::TYPE_BULK )
->setUnsubscribe( 'core', 'unsubscribeBulk' );
$sent = 0;
foreach ( $recipients as $languageId => $_recipients )
@@ -116,11 +116,14 @@ class _DeleteOrMoveContent
if ( isset( $data['moveTo'] ) )
{
$moveTo = $classname::load( $data['moveTo'] );
$text = \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_move_content', FALSE, array( 'htmlsprintf' => array( "<a href='{$node->url()}' target='_blank'>{$node->_title}</a>", "<a href='{$moveTo->url()}' target='_blank'>" . strip_tags( $moveTo->_title ) . "</a>" ) ) );
$link1 = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $node->url(), TRUE, $node->_title, FALSE );
$link2 = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $moveTo->url(), TRUE, $moveTo->_title, FALSE );
$text = \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_move_content', FALSE, array( 'htmlsprintf' => array( $link1, $link2 ) ) );
}
else
{
$text = \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_deleting', FALSE, array( 'htmlsprintf' => array( "<a href='{$node->url()}' target='_blank'>{$node->_title}</a>" ) ) );
$link = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $node->url(), TRUE, $node->_title, FALSE );
$text = \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_deleting', FALSE, array( 'htmlsprintf' => array( $link ) ) );
}
return array( 'text' => $text, 'complete' => $data['originalCount'] ? ( round( 100 / $data['originalCount'] * $offset, 2 ) ) : 100 );
@@ -89,7 +89,7 @@ class _Follow
$complete = 100;
}
$title = strip_tags( ( $item instanceof \IPS\Content\Comment ) ? $item->item()->mapped('title') : $item->mapped('title') );
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( "<a href='{$item->url()}' target='_blank'>{$title}</a>" ) ) ), 'complete' => $complete );
$title = ( $item instanceof \IPS\Content\Comment ) ? $item->item()->mapped('title') : $item->mapped('title');
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $item->url(), TRUE, $title, FALSE ) ) ) ), 'complete' => $complete );
}
}
@@ -0,0 +1,141 @@
<?php
/**
* @brief Background Task
* @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 21 Aug 2018
*/
namespace IPS\core\extensions\core\Queue;
/* 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;
}
/**
* Background Task
*/
class _IndexSingleItem
{
/**
* Parse data before queuing
*
* @param array $data
* @return array
*/
public function preQueueData( $data )
{
$classname = $data['class'];
\IPS\Log::debug( "Getting preQueueData for {$classname}", 'index_single_item' );
if ( \in_array( 'IPS\Content\Comment', class_parents( $classname ) ) )
{
$where = array( $classname::$databasePrefix . $classname::$databaseColumnMap['item'] . '=?', $data['id'] );
}
else
{
/* Just in case an item slips in here */
$where = array( $classname::$databasePrefix . $classname::$databaseColumnId . '=?', $data['id'] );
}
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', $classname::$databaseTable, $where )->first();
$data['indexed'] = 0;
return $data;
}
/**
* Run Background Task
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( $data, $offset )
{
$classname = $data['class'];
if ( !is_subclass_of( $classname, 'IPS\Content\Searchable' ) )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
if ( \in_array( 'IPS\Content\Comment', class_parents( $classname ) ) )
{
$where = array( $classname::$databasePrefix . $classname::$databaseColumnMap['item'] . '=?', $data['id'] );
}
else
{
$where = array( $classname::$databasePrefix . $classname::$databaseColumnId . '=?', $data['id'] );
}
$done = 0;
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', $classname::$databaseTable, $where, $classname::$databasePrefix . $classname::$databaseColumnId . ' ASC', array( $offset, 50 ) ), $classname ) AS $object )
{
try
{
if ( !$object->isFutureDate() )
{
\IPS\Content\Search\Index::i()->index( $object );
}
}
catch( \Exception $e )
{
\IPS\Log::log( $e, 'index_single_item' );
}
catch( \Throwable $e )
{
\IPS\Log::log( $e, 'index_single_item' );
}
$done++;
}
if ( !$done )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
return $offset + $done;
}
/**
* Get Progress
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
{
$class = $data['class'];
$exploded = explode( '\\', $class );
if ( !class_exists( $class ) or !\IPS\Application::appIsEnabled( $exploded[1] ) )
{
throw new \OutOfRangeException;
}
if ( \in_array( 'IPS\Content\Review', class_parents( $class ) ) )
{
$lang = \IPS\Member::loggedIn()->language()->addToStack('reindexing_single_item_reviews', FALSE, array( 'sprintf' => array( $data['url'], $data['title'] ) ) );
}
elseif ( \in_array( 'IPS\Content\Comment', class_parents( $class ) ) )
{
$lang = \IPS\Member::loggedIn()->language()->addToStack('reindexing_single_item_comments', FALSE, array( 'sprintf' => array( $data['url'], $data['title'] ) ) );
}
else
{
$lang = \IPS\Member::loggedIn()->language()->addToStack('reindexing_single_item', FALSE, array( 'sprintf' => array( $data['url'], $data['title'] ) ) );
}
return array( 'text' => $lang, 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['indexed'], 2 ) ) : 100 );
}
}
@@ -30,6 +30,14 @@ class _InstallLanguage
*/
public function preQueueData( $data )
{
/* Get count...this is an estimate but is good enough for the progress bar */
$data['originalCount'] = \IPS\Db::i()->select( 'COUNT(DISTINCT(word_key))', 'core_sys_lang_words', array( 'word_app=?', $data['application'] ) )->first();
if ( !$data['originalCount'] )
{
return NULL;
}
return $data;
}
@@ -43,50 +51,20 @@ class _InstallLanguage
*/
public function run( $data, $offset )
{
$offset = intval( $offset );
if( \IPS\Application::appIsEnabled( $data['application'] ) AND file_exists( \IPS\ROOT_PATH . "/applications/{$data['application']}/data/lang.xml" ) )
{
/* Open XML file */
$xml = new \IPS\Xml\XMLReader;
$xml->open( \IPS\ROOT_PATH . "/applications/{$data['application']}/data/lang.xml" );
$xml->read();
$rowsInserted = \IPS\Application::load( $data['application'] )->installLanguages( $offset, 500 );
/* Get the version */
$xml->read();
$xml->read();
$version = $xml->getAttribute('version');
$inserts = array();
/* Start looping through each word */
while ( $xml->read() )
/* If we didn't insert any, then we're done */
if( $rowsInserted )
{
if( $xml->name != 'word' OR $xml->nodeType != \XMLReader::ELEMENT )
{
continue;
}
$key = $xml->getAttribute('key');
$value = $xml->readString();
$inserts[] = array(
'word_app' => $data['application'],
'word_key' => $key,
'lang_id' => $data['language_id'],
'word_default' => $value,
'word_default_version' => $version,
'word_js' => (int) $xml->getAttribute('js'),
'word_export' => 1,
);
$xml->next();
return $rowsInserted + $offset;
}
}
\IPS\Db::i()->insert( 'core_sys_lang_words', $inserts, TRUE );
throw new \IPS\Task\Queue\OutOfRangeException;
}
else
{
/* Application doesn't exist anymore */
throw new \IPS\Task\Queue\OutOfRangeException;
}
throw new \IPS\Task\Queue\OutOfRangeException;
}
/**
@@ -99,7 +77,7 @@ class _InstallLanguage
*/
public function getProgress( $data, $offset )
{
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack( 'backgroundQueue_importing_english', FALSE, array( 'sprintf' => \IPS\Application::load( $data['application'] )->_title ) ), 'complete' => NULL );
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack( 'backgroundQueue_importing_english', FALSE, array( 'sprintf' => \IPS\Application::load( $data['application'] )->_title ) ), 'complete' => $data['originalCount'] ? ( round( 100 / $data['originalCount'] * $offset, 2 ) ) : 100 );
}
/**
@@ -110,8 +88,10 @@ class _InstallLanguage
*/
public function postComplete( $data )
{
$data = json_decode($data['data'], TRUE);
\IPS\Db::i()->insert( 'core_sys_lang_words', \IPS\Db::i()->select( "NULL AS word_id, {$data['language_id']} AS lang_id, word_app, word_plugin, word_theme, word_key, word_custom, word_default, word_default_version, word_custom_version, word_js, word_export", 'core_sys_lang_words', array( "word_export=? AND word_app=? AND lang_id=?", 0, $data['application'], \IPS\Lang::defaultLanguage() ) ) );
$data = json_decode( $data['data'], TRUE );
\IPS\Db::i()->query( "REPLACE INTO " . \IPS\Db::i()->prefix . "core_sys_lang_words (lang_id, word_app, word_plugin, word_theme, word_key, word_custom, word_default, word_default_version, word_custom_version, word_js, word_export ) SELECT {$data['language_id']} AS lang_id, word_app, word_plugin, word_theme, word_key, word_custom, word_default, word_default_version, word_custom_version, word_js, 0 FROM " . \IPS\Db::i()->prefix . "core_sys_lang_words WHERE word_export=0 AND word_app='{$data['application']}' AND lang_id=" . \IPS\Lang::defaultLanguage() );
unset( \IPS\Data\Store::i()->languages );
}
}
@@ -76,66 +76,76 @@ class _MemberContent
}
$select = \IPS\Db::i()->select( '*', $classname::$databaseTable, static::_getWhere( $data ), $classname::$databasePrefix.$classname::$databaseColumnId, array( 0, 100 ) );
if ( count( $select ) )
{
foreach ( new \IPS\Patterns\ActiveRecordIterator( $select, $classname ) as $item )
{
/* If this is the first comment on an item where a first comment is required (e.g. posts) do nothing, as when we get to the item, that will handle it */
if ( $item instanceof \IPS\Content\Comment )
{
$itemClass = $item::$itemClass;
if ( $itemClass::$firstCommentRequired and $item->isFirst() )
{
continue;
}
}
/* Do the action... */
try
{
switch ( $data['action'] )
{
case 'hide':
$item->hide( isset( $data['initiated_by_member_id'] ) ? \IPS\Member::load( $data['initiated_by_member_id'] ) : NULL );
break;
case 'delete':
$item->delete( isset( $data['initiated_by_member_id'] ) ? \IPS\Member::load( $data['initiated_by_member_id'] ) : NULL );
break;
case 'merge':
$member = \IPS\Member::load( $data['merge_with_id'] );
if ( ! $data['merge_with_id'] and $data['merge_with_name'] )
{
$member->name = $data['merge_with_name'];
}
$item->changeAuthor( $member );
break;
}
}
catch( \OutOfRangeException $e )
{
}
catch( \ErrorException $e )
{
}
}
if( $offset + 100 >= $data['originalCount'] )
foreach ( new \IPS\Patterns\ActiveRecordIterator( $select, $classname ) as $item )
{
/* If this is the first comment on an item where a first comment is required (e.g. posts) do nothing, as when we get to the item, that will handle it */
if ( $item instanceof \IPS\Content\Comment )
{
throw new \IPS\Task\Queue\OutOfRangeException;
$itemClass = $item::$itemClass;
if ( $itemClass::$firstCommentRequired and $item->isFirst() )
{
/* ... but we want to update the IP address of this post */
if ( $data['action'] === 'merge' and empty( $data['merge_with_id'] ) )
{
try
{
$item->changeIpAddress( '' );
$item->changeAuthor( new \IPS\Member );
}
catch( \OutOfRangeException $e ) {}
}
continue;
}
}
return ( $offset + 100 );
/* Do the action... */
try
{
switch ( $data['action'] )
{
case 'hide':
$item->hide( isset( $data['initiated_by_member_id'] ) ? \IPS\Member::load( $data['initiated_by_member_id'] ) : NULL );
break;
case 'delete':
$item->delete( isset( $data['initiated_by_member_id'] ) ? \IPS\Member::load( $data['initiated_by_member_id'] ) : NULL );
break;
case 'merge':
$member = \IPS\Member::load( $data['merge_with_id'] );
if ( ! $data['merge_with_id'] and $data['merge_with_name'] )
{
$member->name = $data['merge_with_name'];
}
$item->changeAuthor( $member );
if ( ! $data['merge_with_id'] )
{
$item->changeIpAddress( '' );
}
break;
}
}
catch( \OutOfRangeException $e )
{
}
catch( \ErrorException $e )
{
}
}
else
if( $offset + 100 >= $data['originalCount'] )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
return ( $offset + 100 );
}
/**
@@ -158,14 +168,15 @@ class _MemberContent
$member = \IPS\Member::load( $data['member_id'] );
if ( $member->member_id )
{
$member = $member->link();
/* htmlsprintf is safe here because $member->link() uses a template */
$sprintf = array( 'htmlsprintf' => array( $member->link(), \IPS\Member::loggedIn()->language()->addToStack( $classname::$title . '_pl_lc' ) ) );
}
else
{
$member = $data['name'];
$sprintf = array( 'sprintf' => array( $data['name'], \IPS\Member::loggedIn()->language()->addToStack( $classname::$title . '_pl_lc' ) ) );
}
$text = \IPS\Member::loggedIn()->language()->addToStack( 'backgroundQueue_membercontent_' . $data['action'], FALSE, array( 'htmlsprintf' => array( $member, \IPS\Member::loggedIn()->language()->addToStack( $classname::$title . '_pl_lc' ) ) ) );
$text = \IPS\Member::loggedIn()->language()->addToStack( 'backgroundQueue_membercontent_' . $data['action'], FALSE, $sprintf );
return array( 'text' => $text, 'complete' => $data['originalCount'] ? ( round( 100 / $data['originalCount'] * $offset, 2 ) ) : 100 );
}
@@ -44,6 +44,12 @@ class _MoveMembers
return null;
}
/* Skip this task if we're trying to move them to the same group */
if( isset( $data['oldGroup'] ) AND $data['oldGroup'] AND $data['oldGroup'] === $data['group'] )
{
return NULL;
}
return $data;
}
@@ -61,7 +61,10 @@ class _RebuildSearchIndex
if( \IPS\Settings::i()->search_method == 'mysql' and \IPS\Settings::i()->search_index_timeframe )
{
$where[] = array( $classname::$databasePrefix . $classname::$databaseColumnMap['date'] . '> ?', \IPS\DateTime::ts( time() - ( 86400 * \IPS\Settings::i()->search_index_timeframe ) )->getTimestamp() );
if( isset( $classname::$databaseColumnMap['date'] ) )
{
$where[] = array( $classname::$databasePrefix . $classname::$databaseColumnMap['date'] . '> ?', \IPS\DateTime::ts( time() - ( 86400 * \IPS\Settings::i()->search_index_timeframe ) )->getTimestamp() );
}
}
return array( 'where' => $where, 'joins' => $joins );
@@ -120,6 +120,10 @@ class _RecountStarRatings
{
$class = $data['class'];
$exploded = explode( '\\', $class );
if ( !class_exists( $class ) or !\IPS\Application::appIsEnabled( $exploded[1] ) )
{
throw new \OutOfRangeException;
}
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('rebuilding_starratings', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $class::$title, FALSE, array( 'strtolower' => TRUE ) ) ) ) ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $offset, 2 ) ) : 100 );
}
@@ -0,0 +1,106 @@
<?php
/**
* @brief Background Task: Unsub members
* @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 13 June 2018
*/
namespace IPS\core\extensions\core\Queue;
/* 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;
}
/**
* Background Task: Unsub members
*/
class _UnsubMembers
{
/**
* Parse data before queuing
*
* @param array $data
* @return array
*/
public function preQueueData( $data )
{
$select = \IPS\Db::i()->select( 'core_members.*', 'core_members', $data['where'], 'member_id ASC', array(), NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS )
->join( 'core_pfields_content', 'core_members.member_id=core_pfields_content.member_id' )
->join( array( 'core_validating', 'v' ), 'v.member_id=core_members.member_id')
->join( array( 'core_admin_permission_rows', 'm' ), "m.row_id=core_members.member_id AND m.row_id_type='member'" )
->join( array( 'core_admin_permission_rows', 'g' ), array( 'g.row_id', \IPS\Db::i()->select( 'row_id', array( 'core_admin_permission_rows', 'sub' ), array( "((sub.row_id=core_members.member_group_id OR FIND_IN_SET( sub.row_id, core_members.mgroup_others ) ) AND sub.row_id_type='group') AND g.row_id_type='group'" ), NULL, array( 0, 1 ) ) ) );
$data['originalCount'] = $select->count( TRUE );
if( $data['originalCount'] == 0 )
{
return null;
}
return $data;
}
/**
* Run Background Task
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( $data, $offset )
{
$perCycle = 1000;
$select = \IPS\Db::i()->select( 'core_members.*', 'core_members', $data['where'], 'member_id ASC', array( 0, $perCycle ), NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS )
->join( 'core_pfields_content', 'core_members.member_id=core_pfields_content.member_id' )
->join( array( 'core_validating', 'v' ), 'v.member_id=core_members.member_id')
->join( array( 'core_admin_permission_rows', 'm' ), "m.row_id=core_members.member_id AND m.row_id_type='member'" )
->join( array( 'core_admin_permission_rows', 'g' ), array( 'g.row_id', \IPS\Db::i()->select( 'row_id', array( 'core_admin_permission_rows', 'sub' ), array( "((sub.row_id=core_members.member_group_id OR FIND_IN_SET( sub.row_id, core_members.mgroup_others ) ) AND sub.row_id_type='group') AND g.row_id_type='group'" ), NULL, array( 0, 1 ) ) ) );
$total = $select->count( TRUE );
if ( !$select->count() or $offset > $data['originalCount'] )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
foreach( $select AS $row )
{
try
{
$member = \IPS\Member::constructFromData( $row );
$member->allow_admin_mails = 0;
$member->save();
}
catch( \Exception $e ) {}
$offset++;
}
return $offset;
}
/**
* Get Progress
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
{
$text = \IPS\Member::loggedIn()->language()->addToStack('unsubscribing_members', FALSE, array() );
return array( 'text' => $text, 'complete' => $data['originalCount'] ? ( round( 100 / $data['originalCount'] * $offset, 2 ) ) : 100 );
}
}
@@ -75,6 +75,6 @@ class _WarnNotifications
$numberofFollowers = intval( $warning->notificationsCount( $warning->getModerators() ) );
$complete = $numberofFollowers ? ( round( 100 / $numberofFollowers * $offset, 2 ) ) : 100;
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( "<a href='{$warning->url()}' target='_blank'>" . strip_tags( $warning->mapped('title') ) . "</a>" ) ) ), 'complete' => $complete );
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $warning->url(), TRUE, $warning->mapped('title'), FALSE ) ) ) ), 'complete' => $complete );
}
}
@@ -221,10 +221,15 @@ class _Content extends \IPS\Content\ExtensionGenerator
{
$exploded = explode( '_', $filename );
$block = (int) array_pop( $exploded );
$totalLimit = isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ? $settings["sitemap_{$class::$title}_count"] : self::RECOMMENDED_ITEM_LIMIT;
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : self::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * \IPS\Sitemap::MAX_PER_FILE;
$limit = \IPS\Sitemap::MAX_PER_FILE;
if ( ! $totalLimit )
{
return NULL;
}
if ( $totalLimit > -1 and ( $offset + $limit ) > $totalLimit )
{
$limit = $totalLimit - $offset;
@@ -253,6 +258,8 @@ class _Content extends \IPS\Content\ExtensionGenerator
{
if( !$item->canView( new \IPS\Member ) )
{
/* Update the last ID, so if we get 500 results that cannot be viewed, the last ID updates for the next batch */
$lastId = $item->$idColumn;
continue;
}
@@ -45,6 +45,24 @@ class _Profiles
);
}
/**
* Save settings for ACP configuration
*
* @param array $values Values
* @return void
*/
public function saveSettings( $values )
{
if ( $values['sitemap_configuration_info'] )
{
\IPS\Settings::i()->changeValues( array( 'sitemap_profiles_count' => $this->recommendedSettings['sitemap_profiles_count'], 'sitemap_profiles_content' => $this->recommendedSettings['sitemap_profiles_content'], 'sitemap_profiles_priority' => $this->recommendedSettings['sitemap_profiles_priority'] ) );
}
else
{
\IPS\Settings::i()->changeValues( array( 'sitemap_profiles_count' => $values['sitemap_profiles_count'], 'sitemap_profiles_content' => $values['sitemap_profiles_content'], 'sitemap_profiles_priority' => $values['sitemap_profiles_priority'] ) );
}
}
/**
* Get the sitemap filename(s)
*
@@ -133,7 +133,7 @@ class _ClubMembership extends \IPS\nexus\Invoice\Item\Purchase
/**
* URL
*
* @return |IPS\Http\Url|NULL
* @return \IPS\Http\Url|NULL
*/
public function url()
{
@@ -150,7 +150,7 @@ class _ClubMembership extends \IPS\nexus\Invoice\Item\Purchase
/**
* ACP URL
*
* @return |IPS\Http\Url|NULL
* @return \IPS\Http\Url|NULL
*/
public function acpUrl()
{
@@ -291,7 +291,7 @@ class _ClubMembership extends \IPS\nexus\Invoice\Item\Purchase
/**
* Warning to display to admin when cancelling a purchase
*
* @param \IPS\nexus\Invoice $invoice The invoice
* @param \IPS\nexus\Purchase $purchase The Purchase
* @return string
*/
public static function onCancelWarning( \IPS\nexus\Purchase $purchase )
@@ -420,7 +420,7 @@ class _ClubMembership extends \IPS\nexus\Invoice\Item\Purchase
*
* @param array $values Values from form
* @param \IPS\nexus\Invoice $invoice The invoice
* @return \IPS\nexus\extensions\nexus\Item\MiscellaneousCharge
* @return \IPS\nexus\extensions\nexus\Item\ClubMembership
*/
public static function createFromForm( array $values, \IPS\nexus\Invoice $invoice )
{
@@ -442,9 +442,9 @@ class _ClubMembership extends \IPS\nexus\Invoice\Item\Purchase
$item->renewalTerm = $club->renewalTerm( $fee->currency );
$item->payTo = $club->owner;
$item->commission = \IPS\Settings::i()->clubs_paid_commission;
if ( $fees = json_decode( \IPS\Settings::i()->clubs_paid_transfee, TRUE ) and isset( $fees[ $price->currency ] ) )
if ( $fees = \IPS\Settings::i()->clubs_paid_transfee and isset( $fees[ $fee->currency ] ) )
{
$item->fee = new \IPS\nexus\Money( $fees[ $price->currency ]['amount'], $fee->currency );
$item->fee = new \IPS\nexus\Money( $fees[ $fee->currency ]['amount'], $fee->currency );
}
return $item;