Version 4.3.0
This commit is contained in:
1 parent
96997ddd8e
commit
fe1acf984a
1349 files changed
+116159
-67711
No files matched your search
@@ -22,6 +22,16 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _Application extends \IPS\Application
|
||||
{
|
||||
/**
|
||||
* @brief Cached advertisement count
|
||||
*/
|
||||
protected $advertisements = NULL;
|
||||
|
||||
/**
|
||||
* @brief Cached clubs pending approval count
|
||||
*/
|
||||
protected $clubs = NULL;
|
||||
|
||||
/**
|
||||
* ACP Menu Numbers
|
||||
*
|
||||
@@ -34,9 +44,21 @@ class _Application extends \IPS\Application
|
||||
switch ( $queryString['controller'] )
|
||||
{
|
||||
case 'advertisements':
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'core_advertisements', array( 'ad_active=-1' ) )->first();
|
||||
break;
|
||||
if( $this->advertisements === NULL )
|
||||
{
|
||||
$this->advertisements = \IPS\Db::i()->select( 'COUNT(*)', 'core_advertisements', array( 'ad_active=-1' ) )->first();
|
||||
}
|
||||
return $this->advertisements;
|
||||
|
||||
case 'clubs':
|
||||
if( $this->clubs === NULL )
|
||||
{
|
||||
$this->clubs = \IPS\Db::i()->select( 'COUNT(*)', 'core_clubs', array( 'approved=0' ) )->first();
|
||||
}
|
||||
return $this->clubs;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,6 +89,18 @@ class _Application extends \IPS\Application
|
||||
{
|
||||
return 'cogs';
|
||||
}
|
||||
|
||||
/**
|
||||
* Install Other
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function installOther()
|
||||
{
|
||||
/* Save installed domain to spam defense whitelist */
|
||||
$domain = rtrim( str_replace( 'www.', '', parse_url( \IPS\Settings::i()->base_url, PHP_URL_HOST ) ), '/' );
|
||||
\IPS\Db::i()->insert( 'core_spam_whitelist', array( 'whitelist_type' => 'domain', 'whitelist_content' => $domain, 'whitelist_date' => time(), 'whitelist_reason' => 'Invision Community Domain' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can view page even when user is a guest when guests cannot access the site
|
||||
@@ -81,7 +115,7 @@ class _Application extends \IPS\Application
|
||||
return (
|
||||
$module->key == 'system'
|
||||
and
|
||||
in_array( $controller, array( 'login', 'register', 'lostpass', 'terms', 'ajax', 'privacy', 'editor', 'language', 'theme' ) )
|
||||
in_array( $controller, array( 'login', 'register', 'lostpass', 'terms', 'ajax', 'privacy', 'editor', 'language', 'theme', 'redirect', 'guidelines' ) )
|
||||
)
|
||||
or
|
||||
(
|
||||
@@ -111,7 +145,9 @@ class _Application extends \IPS\Application
|
||||
) )
|
||||
or
|
||||
(
|
||||
$controller === 'ajax' and $do === 'states' // Makes sure address input still works within the ACP otherwise the form to turn site back online is broken
|
||||
$controller === 'ajax' and
|
||||
( $do === 'states' OR // Makes sure address input still works within the ACP otherwise the form to turn site back online is broken
|
||||
$do === 'passwordStrength' ) // Makes sure the password strength meter still works because it is used in the AdminCP and registration
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -224,7 +260,7 @@ class _Application extends \IPS\Application
|
||||
/* redirect old messenger link */
|
||||
if( isset( \IPS\Request::i()->module ) AND \IPS\Request::i()->module == 'global' AND isset( \IPS\Request::i()->controller ) AND (\IPS\Request::i()->controller == 'register' ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register', 'front', 'register', NULL, \IPS\Settings::i()->logins_over_https ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register', 'front', 'register' ) );
|
||||
}
|
||||
|
||||
/* redirect old reports */
|
||||
@@ -235,4 +271,25 @@ class _Application extends \IPS\Application
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=modcp&controller=modcp&tab=reports&action=view&id=' . \IPS\Request::i()->rid , 'front', 'modcp_report' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports an IN_DEV email template into the database
|
||||
*
|
||||
* @param string $path Path to file
|
||||
* @param object $file DirectoryIterator File Object
|
||||
* @param string|null $namePrefix Name prefix
|
||||
* @return array
|
||||
*/
|
||||
protected function _buildEmailTemplateFromInDev( $path, $file, $namePrefix='' )
|
||||
{
|
||||
$return = parent::_buildEmailTemplateFromInDev( $path, $file, $namePrefix );
|
||||
|
||||
/* Make sure that the email wrapper is pinned to the top of the list */
|
||||
if( $file->getFilename() == 'emailWrapper.phtml' )
|
||||
{
|
||||
$return['template_pinned'] = 1;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,8 @@ class _groups extends \IPS\Api\Controller
|
||||
* GET /core/groups
|
||||
* Get list of groups
|
||||
*
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
* @return \IPS\Api\PaginatedResponse<IPS\Member\Group>
|
||||
*/
|
||||
public function GETindex()
|
||||
@@ -37,10 +38,12 @@ class _groups extends \IPS\Api\Controller
|
||||
/* Return */
|
||||
return new \IPS\Api\PaginatedResponse(
|
||||
200,
|
||||
\IPS\Db::i()->select( '*', 'core_groups', $where, "g_id asc", NULL, NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS ),
|
||||
\IPS\Db::i()->select( '*', 'core_groups', $where, "g_id asc" ),
|
||||
isset( \IPS\Request::i()->page ) ? \IPS\Request::i()->page : 1,
|
||||
'IPS\Member\Group',
|
||||
\IPS\Db::i()->select( 'COUNT(*)', 'core_groups', $where )->first()
|
||||
\IPS\Db::i()->select( 'COUNT(*)', 'core_groups', $where )->first(),
|
||||
$this->member,
|
||||
isset( \IPS\Request::i()->perPage ) ? \IPS\Request::i()->perPage : NULL
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,7 +65,7 @@ class _groups extends \IPS\Api\Controller
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
return new \IPS\Api\Response( 200, $group->apiOutput() );
|
||||
return new \IPS\Api\Response( 200, $group->apiOutput( $this->member ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -74,6 +77,7 @@ class _groups extends \IPS\Api\Controller
|
||||
* DELETE /core/groups/{id}
|
||||
* Deletes a group
|
||||
*
|
||||
* @apiclientonly
|
||||
* @param int $id ID Number
|
||||
* @throws 1C358/2 INVALID_ID The group ID does not exist
|
||||
* @return void
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Me API
|
||||
* @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 3 Dec 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\core\api;
|
||||
|
||||
/* 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 Me API
|
||||
*/
|
||||
class _me extends \IPS\Api\Controller
|
||||
{
|
||||
/**
|
||||
* GET /core/me
|
||||
* Get basic information about the authorized user
|
||||
*
|
||||
* @apimemberonly
|
||||
* @return \IPS\Member
|
||||
*/
|
||||
public function GETindex()
|
||||
{
|
||||
$output = $this->member->apiOutput( $this->member );
|
||||
|
||||
if ( $this->canAccess( 'core', 'me', 'GETitem' ) )
|
||||
{
|
||||
$output['email'] = $this->member->email;
|
||||
}
|
||||
|
||||
return new \IPS\Api\Response( 200, $output );
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /core/me/email
|
||||
* Get authorized user's email address
|
||||
*
|
||||
* @apimemberonly
|
||||
* @return array
|
||||
* @apiresponse string email Email address
|
||||
*/
|
||||
public function GETitem( $path )
|
||||
{
|
||||
return new \IPS\Api\Response( 200, array( 'email' => $this->member->email ) );
|
||||
}
|
||||
}
|
||||
@@ -26,15 +26,43 @@ class _members extends \IPS\Api\Controller
|
||||
* GET /core/members
|
||||
* Get list of members
|
||||
*
|
||||
* @apiparam string sortBy What to sort by. Can be 'joined', 'name' or leave unspecified for ID
|
||||
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
|
||||
* @apiparam int page Page number
|
||||
* @apiparam string sortBy What to sort by. Can be 'joined', 'name' or leave unspecified for ID
|
||||
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
|
||||
* @apiparam string name (Partial) user name to search for
|
||||
* @apiparam string email (Partial) Email address to search for
|
||||
* @apiparam int|array group Group ID or IDs to search for
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
* @return \IPS\Api\PaginatedResponse<IPS\Member>
|
||||
*/
|
||||
public function GETindex()
|
||||
{
|
||||
/* Where clause */
|
||||
$where = array();
|
||||
$where = array( array( 'core_members.name<>?', '' ) );
|
||||
|
||||
/* Are we searching? */
|
||||
if( isset( \IPS\Request::i()->name ) )
|
||||
{
|
||||
$where[] = array( "name LIKE CONCAT( '%', ?, '%' )", \IPS\Request::i()->name );
|
||||
}
|
||||
|
||||
if( isset( \IPS\Request::i()->email ) )
|
||||
{
|
||||
$where[] = array( "email LIKE CONCAT( '%', ?, '%' )", \IPS\Request::i()->email );
|
||||
}
|
||||
|
||||
if( isset( \IPS\Request::i()->group ) )
|
||||
{
|
||||
if( is_array( \IPS\Request::i()->group ) )
|
||||
{
|
||||
$groups = array_map( function( $value ){ return intval( $value ); }, \IPS\Request::i()->group );
|
||||
$where[] = array( "(member_group_id IN(" . implode( ',', $groups ) . ") OR " . \IPS\Db::i()->findInSet( 'mgroup_others', $groups ) . ")" );
|
||||
}
|
||||
elseif( \IPS\Request::i()->group )
|
||||
{
|
||||
$where[] = array( "(member_group_id=" . intval( \IPS\Request::i()->group ) . ") OR (" . \IPS\Db::i()->findInSet( 'mgroup_others', array( intval( \IPS\Request::i()->group ) ) ) . ")" );
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort */
|
||||
$sortBy = ( isset( \IPS\Request::i()->sortBy ) and in_array( \IPS\Request::i()->sortBy, array( 'name', 'joined' ) ) ) ? \IPS\Request::i()->sortBy : 'member_id';
|
||||
@@ -43,10 +71,12 @@ class _members extends \IPS\Api\Controller
|
||||
/* Return */
|
||||
return new \IPS\Api\PaginatedResponse(
|
||||
200,
|
||||
\IPS\Db::i()->select( '*', 'core_members', $where, "{$sortBy} {$sortDir}", NULL, NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS ),
|
||||
\IPS\Db::i()->select( '*', 'core_members', $where, "{$sortBy} {$sortDir}" ),
|
||||
isset( \IPS\Request::i()->page ) ? \IPS\Request::i()->page : 1,
|
||||
'IPS\Member',
|
||||
\IPS\Db::i()->select( 'COUNT(*)', 'core_members', $where )->first()
|
||||
\IPS\Db::i()->select( 'COUNT(*)', 'core_members', $where )->first(),
|
||||
$this->member,
|
||||
isset( \IPS\Request::i()->perPage ) ? \IPS\Request::i()->perPage : NULL
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,6 +85,7 @@ class _members extends \IPS\Api\Controller
|
||||
* Get information about a specific member
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @apiparam array otherFields An array of additional non-standard fields to return via the REST API
|
||||
* @throws 1C292/2 INVALID_ID The member ID does not exist
|
||||
* @return \IPS\Member
|
||||
*/
|
||||
@@ -68,7 +99,7 @@ class _members extends \IPS\Api\Controller
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
return new \IPS\Api\Response( 200, $member->apiOutput() );
|
||||
return new \IPS\Api\Response( 200, $member->apiOutput( $this->member, ( isset( \IPS\Request::i()->otherFields ) ) ? \IPS\Request::i()->otherFields : NULL ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -79,8 +110,7 @@ class _members extends \IPS\Api\Controller
|
||||
/**
|
||||
* Create or update member
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @apiparam int group Group ID number
|
||||
* @param \IPS\Member $member The member
|
||||
* @throws 1C292/4 USERNAME_EXISTS The username provided is already in use
|
||||
* @throws 1C292/5 EMAIL_EXISTS The email address provided is already in use
|
||||
* @throws 1C292/6 INVALID_GROUP The group ID provided is not valid
|
||||
@@ -92,7 +122,8 @@ class _members extends \IPS\Api\Controller
|
||||
{
|
||||
$existingUsername = \IPS\Member::load( \IPS\Request::i()->name, 'name' );
|
||||
if ( !$existingUsername->member_id )
|
||||
{
|
||||
{
|
||||
$member->logHistory( 'core', 'display_name', array( 'old' => $member->name, 'new' => \IPS\Request::i()->name, 'by' => 'api' ) );
|
||||
$member->name = \IPS\Request::i()->name;
|
||||
}
|
||||
else
|
||||
@@ -106,6 +137,7 @@ class _members extends \IPS\Api\Controller
|
||||
$existingEmail = \IPS\Member::load( \IPS\Request::i()->email, 'email' );
|
||||
if ( !$existingEmail->member_id )
|
||||
{
|
||||
$member->logHistory( 'core', 'email_change', array( 'old' => $member->name, 'new' => \IPS\Request::i()->name, 'by' => 'api' ) );
|
||||
$member->email = \IPS\Request::i()->email;
|
||||
$member->invalidateSessionsAndLogins();
|
||||
}
|
||||
@@ -128,16 +160,57 @@ class _members extends \IPS\Api\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->password ) )
|
||||
if( isset( \IPS\Request::i()->secondaryGroups ) AND is_array( \IPS\Request::i()->secondaryGroups ) )
|
||||
{
|
||||
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
|
||||
foreach( \IPS\Request::i()->secondaryGroups as $groupId )
|
||||
{
|
||||
try
|
||||
{
|
||||
$handler->changePassword( $member, \IPS\Request::i()->password );
|
||||
$group = \IPS\Member\Group::load( $groupId );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_GROUP', '1C292/7', 403 );
|
||||
}
|
||||
catch( \BadMethodCallException $e ){}
|
||||
}
|
||||
|
||||
$member->mgroup_others = implode( ',', \IPS\Request::i()->secondaryGroups );
|
||||
}
|
||||
elseif( isset( \IPS\Request::i()->secondaryGroups ) AND \IPS\Request::i()->secondaryGroups == '' )
|
||||
{
|
||||
$member->mgroup_others = '';
|
||||
}
|
||||
|
||||
if( isset( \IPS\Request::i()->registrationIpAddress ) AND filter_var( \IPS\Request::i()->registrationIpAddress, FILTER_VALIDATE_IP ) )
|
||||
{
|
||||
$member->ip_address = \IPS\Request::i()->registrationIpAddress;
|
||||
}
|
||||
|
||||
if( isset( \IPS\Request::i()->rawProperties ) AND is_array( \IPS\Request::i()->rawProperties ) )
|
||||
{
|
||||
foreach( \IPS\Request::i()->rawProperties as $property => $value )
|
||||
{
|
||||
$member->$property = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->password ) )
|
||||
{
|
||||
/* Setting the password for the just created member shouldn't be logged to the member history and shouldn't fire the onPassChange Sync call */
|
||||
$logPasswordChange = TRUE;
|
||||
if ( $member->member_id )
|
||||
{
|
||||
$logPasswordChange = FALSE;
|
||||
}
|
||||
$member->setLocalPassword( \IPS\Request::i()->password );
|
||||
$member->save();
|
||||
|
||||
if ( $logPasswordChange )
|
||||
{
|
||||
$member->memberSync( 'onPassChange', array( \IPS\Request::i()->password ) );
|
||||
$member->logHistory( 'core', 'password_change', 'api' );
|
||||
}
|
||||
|
||||
$member->invalidateSessionsAndLogins();
|
||||
}
|
||||
else
|
||||
@@ -145,6 +218,21 @@ class _members extends \IPS\Api\Controller
|
||||
$member->save();
|
||||
}
|
||||
|
||||
/* Validation stuff */
|
||||
if( isset( \IPS\Request::i()->validated ) )
|
||||
{
|
||||
/* If the member is currently validating and we are setting the validated flag to true, then complete the validation */
|
||||
if( \IPS\Request::i()->validated == 1 AND $member->members_bitoptions['validating'] )
|
||||
{
|
||||
$member->validationComplete();
|
||||
}
|
||||
/* If the member is not currently validating, and we set the validated flag to false AND validation is enabled, mark the member validating */
|
||||
elseif( \IPS\Request::i()->validated == 0 AND !$member->members_bitoptions['validating'] AND \IPS\Settings::i()->reg_auth_type != 'none' )
|
||||
{
|
||||
$member->postRegistration();
|
||||
}
|
||||
}
|
||||
|
||||
/* Any custom fields? */
|
||||
if( isset( \IPS\Request::i()->customFields ) )
|
||||
{
|
||||
@@ -182,16 +270,22 @@ class _members extends \IPS\Api\Controller
|
||||
|
||||
/**
|
||||
* POST /core/members
|
||||
* Create a member
|
||||
* Create a member. Requires the standard login handler to be enabled
|
||||
*
|
||||
* @apiclientonly
|
||||
* @apiparam string name Username
|
||||
* @apiparam string email Email address
|
||||
* @apiparam string password Password
|
||||
* @apiparam string password Password (standard login handler only)
|
||||
* @apiparam int group Group ID number
|
||||
* @apiparam string registrationIpAddress IP Address
|
||||
* @apiparam array secondaryGroups Secondary group IDs, or empty value to reset secondary groups
|
||||
* @apiparam object customFields Array of custom fields as fieldId => fieldValue
|
||||
* @apiparam int validated Flag to indicate if the account is validated (1) or not (0)
|
||||
* @apiparam array rawProperties Key => value object of member properties to set. Note that values will be set exactly as supplied without validation. USE AT YOUR OWN RISK.
|
||||
* @throws 1C292/4 USERNAME_EXISTS The username provided is already in use
|
||||
* @throws 1C292/5 EMAIL_EXISTS The email address provided is already in use
|
||||
* @throws 1C292/6 INVALID_GROUP The group ID provided is not valid
|
||||
* @throws 1C292/7 INVALID_GROUP A secondary group ID provided is not valid
|
||||
* @throws 1C292/8 NO_USERNAME_OR_EMAIL No Username or Email Address was provided for the account
|
||||
* @throws 1C292/9 NO_PASSWORD No password was provided for the account
|
||||
* @return \IPS\Member
|
||||
@@ -215,22 +309,29 @@ class _members extends \IPS\Api\Controller
|
||||
|
||||
$member = $this->_createOrUpdate( $member );
|
||||
|
||||
return new \IPS\Api\Response( 201, $member->apiOutput() );
|
||||
return new \IPS\Api\Response( 201, $member->apiOutput( $this->member ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /core/members/{id}
|
||||
* Edit a member
|
||||
*
|
||||
* @apiclientonly
|
||||
* @apiparam string name Username
|
||||
* @apiparam string email Email address
|
||||
* @apiparam string password Password
|
||||
* @apiparam string password Password (standard login handler only)
|
||||
* @apiparam int group Group ID number
|
||||
* @apiparam string registrationIpAddress IP Address
|
||||
* @apiparam array secondaryGroups Secondary group IDs, or empty value to reset secondary groups
|
||||
* @apiparam object customFields Array of custom fields as fieldId => fieldValue
|
||||
* @apiparam int validated Flag to indicate if the account is validated (1) or not (0)
|
||||
* @apiparam array rawProperties Key => value object of member properties to set. Note that values will be set exactly as supplied without validation. USE AT YOUR OWN RISK.
|
||||
* @param int $id ID Number
|
||||
* @throws 2C292/7 INVALID_ID The member ID does not exist
|
||||
* @throws 1C292/4 USERNAME_EXISTS The username provided is already in use
|
||||
* @throws 1C292/5 EMAIL_EXISTS The email address provided is already in use
|
||||
* @throws 1C292/6 INVALID_GROUP The group ID provided is not valid
|
||||
* @throws 1C292/7 INVALID_GROUP A secondary group ID provided is not valid
|
||||
* @return \IPS\Member
|
||||
*/
|
||||
public function POSTitem( $id )
|
||||
@@ -242,10 +343,22 @@ class _members extends \IPS\Api\Controller
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
|
||||
$oldPrimaryGroup = $member->member_group_id;
|
||||
$oldSecondaryGroups = array_unique( array_filter( explode( ',', $member->mgroup_others ) ) );
|
||||
$member = $this->_createOrUpdate( $member );
|
||||
|
||||
if ( $oldPrimaryGroup != $member->member_group_id )
|
||||
{
|
||||
$member->logHistory( 'core', 'group', array( 'type' => 'primary', 'by' => 'api', 'apiKey' => $this->apiKey ? $this->apiKey->id : NULL, 'client' => $this->client ? $this->client->client_id : NULL, 'old' => $oldPrimaryGroup, 'new' => $member->member_group_id ), $this->member ?: FALSE );
|
||||
}
|
||||
$newSecondaryGroups = array_unique( array_filter( explode( ',', $member->mgroup_others ) ) );
|
||||
if ( array_diff( $oldSecondaryGroups, $newSecondaryGroups ) or array_diff( $newSecondaryGroups, $oldSecondaryGroups ) )
|
||||
{
|
||||
$member->logHistory( 'core', 'group', array( 'type' => 'secondary', 'by' => 'api', 'apiKey' => $this->apiKey ? $this->apiKey->id : NULL, 'client' => $this->client ? $this->client->client_id : NULL, 'old' => $oldSecondaryGroups, 'new' => $newSecondaryGroups ), $this->member ?: FALSE );
|
||||
}
|
||||
|
||||
return new \IPS\Api\Response( 200, $member->apiOutput() );
|
||||
return new \IPS\Api\Response( 200, $member->apiOutput( $this->member ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -257,6 +370,7 @@ class _members extends \IPS\Api\Controller
|
||||
* DELETE /core/members/{id}
|
||||
* Deletes a member
|
||||
*
|
||||
* @apiclientonly
|
||||
* @param int $id ID Number
|
||||
* @throws 1C292/2 INVALID_ID The member ID does not exist
|
||||
* @return void
|
||||
@@ -280,4 +394,238 @@ class _members extends \IPS\Api\Controller
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '1C292/2', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /core/members/{id}/follows
|
||||
* Get list of items a member is following
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
* @return \IPS\Api\PaginatedResponse<IPS\core\Followed\Follow>
|
||||
* @throws 2C292/F NO_PERMISSION The authorized user does not have permission to view the follows
|
||||
* @throws 2C292/I INVALID_ID The member could not be found
|
||||
*/
|
||||
public function GETitem_follows( $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Load member */
|
||||
$member = \IPS\Member::load( $id );
|
||||
if( !$member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
/* We can only adjust follows for ourself, if we are an authorized member */
|
||||
if ( $this->member and $member->member_id != $this->member->member_id )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2C292/F', 403 );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return new \IPS\Api\PaginatedResponse(
|
||||
200,
|
||||
\IPS\Db::i()->select( '*', 'core_follow', array( 'follow_member_id=?', $member->member_id ), "follow_added ASC" ),
|
||||
isset( \IPS\Request::i()->page ) ? \IPS\Request::i()->page : 1,
|
||||
'IPS\core\Followed\Follow',
|
||||
\IPS\Db::i()->select( 'COUNT(*)', 'core_follow', array( 'follow_member_id=?', $member->member_id ) )->first(),
|
||||
$this->member,
|
||||
isset( \IPS\Request::i()->perPage ) ? \IPS\Request::i()->perPage : NULL
|
||||
);
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2C292/I', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /core/members/{id}/follows
|
||||
* Store a new follow for the member
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @reqapiparam string followApp Application of the content to follow
|
||||
* @reqapiparam string followArea Area of the content to follow
|
||||
* @reqapiparam int followId ID of the content to follow
|
||||
* @apiparam bool followAnon Whether or not to follow anonymously
|
||||
* @apiparam bool followNotify Whether or not to receive notifications
|
||||
* @apiparam string followType Type of notification to receive (immediate=send a notification immediately, daily=daily notification digest, weekly=weekly notification digest)
|
||||
* @return \IPS\core\Followed\Follow
|
||||
* @throws 2C292/G NO_PERMISSION The authorized user does not have permission to view the follows
|
||||
* @throws 2C292/H INVALID_ID The member could not be found
|
||||
* @throws 2C292/J INVALID_CONTENT The app, area or content ID could not be found
|
||||
*/
|
||||
public function POSTitem_follows( $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Load member */
|
||||
$member = \IPS\Member::load( $id );
|
||||
if( !$member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
/* We can only adjust follows for ourself, if we are an authorized member */
|
||||
if ( $this->member and $member->member_id != $this->member->member_id )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2C292/G', 403 );
|
||||
}
|
||||
|
||||
/* Make sure follow app/area/id is valid (Phil I'm looking at you) */
|
||||
try
|
||||
{
|
||||
$classToFollow = 'IPS\\' . \IPS\Request::i()->followApp . '\\' . mb_ucfirst( \IPS\Request::i()->followArea );
|
||||
|
||||
if( !class_exists( $classToFollow ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
$thingToFollow = $classToFollow::load( \IPS\Request::i()->followId );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_CONTENT', '2C292/J', 404 );
|
||||
}
|
||||
|
||||
/* If we are already following this, update instead of insert */
|
||||
try
|
||||
{
|
||||
$follow = \IPS\core\Followed\Follow::load( md5( \IPS\Request::i()->followApp . ';' . \IPS\Request::i()->followArea . ';' . \IPS\Request::i()->followId . ';' . $member->member_id ) );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
$follow = new \IPS\core\Followed\Follow;
|
||||
$follow->member_id = $member->member_id;
|
||||
$follow->app = \IPS\Request::i()->followApp;
|
||||
$follow->area = \IPS\Request::i()->followArea;
|
||||
$follow->rel_id = \IPS\Request::i()->followId;
|
||||
}
|
||||
|
||||
$follow->is_anon = ( isset( \IPS\Request::i()->followAnon ) ) ? (int) \IPS\Request::i()->followAnon : 0;
|
||||
$follow->notify_do = ( isset( \IPS\Request::i()->followType ) AND \IPS\Request::i()->followType == 'none' ) ? 0 : ( ( isset( \IPS\Request::i()->followNotify ) ) ? (int) \IPS\Request::i()->followNotify : 1 );
|
||||
$follow->notify_freq = ( isset( \IPS\Request::i()->followType ) AND in_array( \IPS\Request::i()->followType, array( 'none', 'immediate', 'daily', 'weekly' ) ) ) ? \IPS\Request::i()->followType : 'immediate';
|
||||
$follow->save();
|
||||
|
||||
/* If we're following a club, follow all nodes in the club automatically */
|
||||
if( $follow->app == 'core' and $follow->area == 'club' )
|
||||
{
|
||||
$thing = \IPS\Member\Club::loadAndCheckPerms( $follow->rel_id );
|
||||
|
||||
foreach ( $thing->nodes() as $node )
|
||||
{
|
||||
$itemClass = $node['node_class']::$contentItemClass;
|
||||
$followApp = $itemClass::$application;
|
||||
$followArea = mb_strtolower( mb_substr( $node['node_class'], mb_strrpos( $node['node_class'], '\\' ) + 1 ) );
|
||||
|
||||
/* If we are already following this, update instead of insert */
|
||||
try
|
||||
{
|
||||
$nodeFollow = \IPS\core\Followed\Follow::load( md5( $followApp . ';' . $followArea . ';' . $node['node_id'] . ';' . $member->member_id ) );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
$nodeFollow = new \IPS\core\Followed\Follow;
|
||||
$nodeFollow->member_id = $member->member_id;
|
||||
$nodeFollow->app = $followApp;
|
||||
$nodeFollow->area = $followArea;
|
||||
$nodeFollow->rel_id = $node['node_id'];
|
||||
}
|
||||
|
||||
$nodeFollow->is_anon = $follow->is_anon;
|
||||
$nodeFollow->notify_do = $follow->notify_do;
|
||||
$nodeFollow->notify_freq = $follow->notify_freq;
|
||||
$nodeFollow->save();
|
||||
}
|
||||
}
|
||||
|
||||
return new \IPS\Api\Response( 200, $follow->apiOutput( $this->member ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2C292/H', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /core/members/{id}/follows
|
||||
* Delete a follow for the member
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @apiparam string followKey Follow Key
|
||||
* @throws 2C292/C INVALID_ID The member could not be found
|
||||
* @throws 2C292/E INVALID_FOLLOW_KEY The follow does not exist or does not belong to this member
|
||||
* @throws 2C292/D NO_PERMISSION The authorized user does not have permission to delete the follow
|
||||
* @return void
|
||||
*/
|
||||
public function DELETEitem_follows( $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Load member */
|
||||
$member = \IPS\Member::load( $id );
|
||||
if( !$member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
/* We can only adjust follows for ourself, if we are an authorized member */
|
||||
if ( $this->member and $member->member_id != $this->member->member_id )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2C292/D', 403 );
|
||||
}
|
||||
|
||||
/* Load our follow, and make sure it belongs to the specified member */
|
||||
try
|
||||
{
|
||||
if( !isset( \IPS\Request::i()->followKey ) )
|
||||
{
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
|
||||
$follow = \IPS\Db::i()->select( '*', 'core_follow', array( 'follow_id=?', \IPS\Request::i()->followKey ) )->first();
|
||||
|
||||
if( $follow['follow_member_id'] != $member->member_id )
|
||||
{
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_FOLLOW_KEY', '2C292/E', 404 );
|
||||
}
|
||||
|
||||
/* Unfollow */
|
||||
\IPS\Db::i()->delete( 'core_follow', array( 'follow_id=?', \IPS\Request::i()->followKey ) );
|
||||
|
||||
/* If this is a club, unfollow all nodes in the club too */
|
||||
if( $follow['follow_app'] == 'core' AND $follow['follow_area'] == 'club' )
|
||||
{
|
||||
$class = 'IPS\Member\Club';
|
||||
|
||||
try
|
||||
{
|
||||
$thing = $class::loadAndCheckPerms( $follow['follow_rel_id'] );
|
||||
|
||||
foreach ( $thing->nodes() as $node )
|
||||
{
|
||||
$itemClass = $node['node_class']::$contentItemClass;
|
||||
$followApp = $itemClass::$application;
|
||||
$followArea = mb_strtolower( mb_substr( $node['node_class'], mb_strrpos( $node['node_class'], '\\' ) + 1 ) );
|
||||
|
||||
\IPS\Db::i()->delete( 'core_follow', array( 'follow_id=? AND follow_member_id=?', md5( $followApp . ';' . $followArea . ';' . $node['node_id'] . ';' . $member->member_id ), $member->member_id ) );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ){}
|
||||
}
|
||||
|
||||
return new \IPS\Api\Response( 200, NULL );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2C292/C', 404 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Personal Conversations API
|
||||
* @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 1 Dec 2017
|
||||
* @note We intentionally have not added any way to fetch messages to match the built in privacy functionality
|
||||
*/
|
||||
|
||||
namespace IPS\core\api;
|
||||
|
||||
/* 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 Personal Conversations API
|
||||
*/
|
||||
class _messages extends \IPS\Api\Controller
|
||||
{
|
||||
/**
|
||||
* POST /core/messages
|
||||
* Create a new personal conversation
|
||||
*
|
||||
* @apiclientonly
|
||||
* @apiparam int from User ID conversation is from
|
||||
* @apiparam array to One or more user IDs conversation is sent to
|
||||
* @apiparam string title Conversation title
|
||||
* @apiparam string body Conversation body
|
||||
* @throws 1C374/2 INVALID_SENDER Sender was not supplied or is invalid
|
||||
* @throws 1C374/3 INVALID_RECIPIENT No recipients were supplied
|
||||
* @throws 1C374/4 INVALID_RECIPIENT One or more recipients are invalid
|
||||
* @throws 1C374/5 MISSING_TITLE_OR_BODY The title and/or body of the conversation were not supplied
|
||||
* @return int Conversation ID
|
||||
*/
|
||||
public function POSTindex()
|
||||
{
|
||||
/* Make sure there is a valid sender */
|
||||
if ( !isset( \IPS\Request::i()->from ) OR !\IPS\Member::load( (int) \IPS\Request::i()->from )->member_id )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_SENDER', '1C374/2', 404 );
|
||||
}
|
||||
|
||||
/* Verify there are recipients and all the recipients are valid */
|
||||
if( !isset( \IPS\Request::i()->to ) OR !is_array( \IPS\Request::i()->to ) OR !count( \IPS\Request::i()->to ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_RECIPIENT', '1C374/3', 404 );
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach( \IPS\Request::i()->to as $to )
|
||||
{
|
||||
if( !\IPS\Member::load( (int) $to )->member_id )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_RECIPIENT', '1C374/4', 404 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we have a title and body */
|
||||
if( !isset( \IPS\Request::i()->title ) OR !isset( \IPS\Request::i()->body ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'MISSING_TITLE_OR_BODY', '1C374/5', 404 );
|
||||
}
|
||||
|
||||
/* Create the conversation */
|
||||
$item = \IPS\core\Messenger\Conversation::createItem( \IPS\Member::load( (int) \IPS\Request::i()->from ), \IPS\Request::i()->ipAddress(), \IPS\DateTime::create(), NULL );
|
||||
$item->title = \IPS\Request::i()->title;
|
||||
$item->to_count = count( \IPS\Request::i()->to );
|
||||
$item->save();
|
||||
|
||||
/* Create the first message */
|
||||
$postContents = \IPS\Text\Parser::parseStatic( \IPS\Request::i()->body, TRUE, NULL, \IPS\Member::load( (int) \IPS\Request::i()->from ), 'core_Messaging' );
|
||||
|
||||
$commentClass = $item::$commentClass;
|
||||
$post = $commentClass::create( $item, $postContents, TRUE, NULL, NULL, \IPS\Member::load( (int) \IPS\Request::i()->from ), \IPS\DateTime::create() );
|
||||
|
||||
$item->first_msg_id = $post->id;
|
||||
$item->save();
|
||||
|
||||
/* Authorize sender and recipients */
|
||||
$item->authorize( array_map( function( $member ) { return (int) $member; }, array_merge( array( \IPS\Request::i()->from ), \IPS\Request::i()->to ) ) );
|
||||
|
||||
/* Send notifications */
|
||||
$post->sendNotifications();
|
||||
|
||||
return new \IPS\Api\Response( 201, $item->id );
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /core/messages/{id}
|
||||
* Add a reply to a personal conversation
|
||||
*
|
||||
* @apiclientonly
|
||||
* @apiparam string body Message body
|
||||
* @apiparam int from Person responding to message (must be part of conversation)
|
||||
* @param int $id ID Number
|
||||
* @throws 1C374/6 INVALID_ID The personal conversation ID does not exist
|
||||
* @throws 1C374/7 INVALID_SENDER The sender ID supplied was not valid
|
||||
* @throws 1C374/8 SENDER_NO_PERMISSON The sender supplied does not have permmission to reply to the conversation
|
||||
* @return bool
|
||||
*/
|
||||
public function POSTitem( $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$message = \IPS\core\Messenger\Conversation::load( $id );
|
||||
|
||||
/* Make sure we have a member, and the member is authorized to reply */
|
||||
if( !isset( \IPS\Request::i()->from ) OR !\IPS\Member::load( (int) \IPS\Request::i()->from )->member_id )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_SENDER', '1C374/7', 404 );
|
||||
}
|
||||
|
||||
if( !$message->canView( \IPS\Member::load( (int) \IPS\Request::i()->from ) ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'SENDER_NO_PERMISSON', '1C374/8', 403 );
|
||||
}
|
||||
|
||||
/* Create the reply */
|
||||
$postContents = \IPS\Text\Parser::parseStatic( \IPS\Request::i()->body, TRUE, NULL, \IPS\Member::load( (int) \IPS\Request::i()->from ), 'core_Messaging' );
|
||||
|
||||
$commentClass = $message::$commentClass;
|
||||
$post = $commentClass::create( $message, $postContents, TRUE, NULL, NULL, \IPS\Member::load( (int) \IPS\Request::i()->from ), \IPS\DateTime::create() );
|
||||
|
||||
/* Send notifications */
|
||||
$post->sendNotifications();
|
||||
|
||||
return new \IPS\Api\Response( 200, TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '1C374/6', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /core/messages/{id}
|
||||
* Deletes a personal conversation
|
||||
*
|
||||
* @apiclientonly
|
||||
* @param int $id ID Number
|
||||
* @throws 1C292/2 INVALID_ID The personal conversation ID does not exist
|
||||
* @return void
|
||||
*/
|
||||
public function DELETEitem( $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$message = \IPS\core\Messenger\Conversation::load( $id );
|
||||
$message->delete();
|
||||
|
||||
return new \IPS\Api\Response( 200, NULL );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '1C374/1', 404 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Search API
|
||||
* @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 17 Oct 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\api;
|
||||
|
||||
/* 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 Search API
|
||||
*/
|
||||
class _search extends \IPS\Api\Controller
|
||||
{
|
||||
/**
|
||||
* GET /core/search
|
||||
* Perform a search and get a list of results
|
||||
*
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
* @apiparam string q String to search for
|
||||
* @apiparam string tags Comma-separated list of tags to search for
|
||||
* @apiparam string type Content type class to restrict searches to
|
||||
* @apiparam int item Restrict searches to comments or reviews made to the specified item
|
||||
* @apiparam string nodes Comma-separated list of node IDs to restrict searches to
|
||||
* @apiparam int search_min_comments Minimum number of comments search results must have for content types that support comments
|
||||
* @apiparam int search_min_replies Minimum number of comments search results must have for content types that require the first comment (e.g. topics)
|
||||
* @apiparam int search_min_reviews Minimum number of reviews search results must have
|
||||
* @apiparam int search_min_views Minimum number of views search results must have
|
||||
* @apiparam string author Restrict searches to results posted by this member (name)
|
||||
* @apiparam string club Comma-separated list of club IDs to restrict searches to
|
||||
* @apiparam string start_before Date period (from current time) that search results should start before
|
||||
* @apiparam string start_after Date period (from current time) that search results should start after
|
||||
* @apiparam string updated_before Date period (from current time) that search results should last be updated before
|
||||
* @apiparam string updated_after Date period (from current time) that search results should last be updated after
|
||||
* @apiparam string sortby Sort by method (newest or relevancy)
|
||||
* @apiparam string eitherTermsOrTags Whether to search both tags and search term ("and") or either ("or")
|
||||
* @apiparam string search_and_or Whether to perform an "and" search or an "or" search for all search terms
|
||||
* @apiparam string search_in Specify "titles" to search in titles only, otherwise titles and content are both searched
|
||||
* @return array
|
||||
* @apiresponse int page api_int_page
|
||||
* @apiresponse int perPage api_int_perpage
|
||||
* @apiresponse int totalResults api_int_totalresults
|
||||
* @apiresponse int totalPages api_int_totalpages
|
||||
* @apiresponse [\IPS\Content\Search\Result] results api_results_thispage
|
||||
*/
|
||||
public function GETindex()
|
||||
{
|
||||
/* Get valid content types */
|
||||
$contentTypes = \IPS\core\modules\front\search\search::contentTypes();
|
||||
|
||||
/* Initialize search */
|
||||
$query = \IPS\Content\Search\Query::init();
|
||||
|
||||
/* Set content type */
|
||||
if ( isset( \IPS\Request::i()->type ) and array_key_exists( \IPS\Request::i()->type, $contentTypes ) )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->item ) )
|
||||
{
|
||||
$class = $contentTypes[ \IPS\Request::i()->type ];
|
||||
try
|
||||
{
|
||||
$item = $class::loadAndCheckPerms( \IPS\Request::i()->item );
|
||||
$query->filterByContent( array( \IPS\Content\Search\ContentFilter::init( $class )->onlyInItems( array( \IPS\Request::i()->item ) ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter = \IPS\Content\Search\ContentFilter::init( $contentTypes[ \IPS\Request::i()->type ] );
|
||||
|
||||
if ( isset( \IPS\Request::i()->nodes ) )
|
||||
{
|
||||
$filter->onlyInContainers( explode( ',', \IPS\Request::i()->nodes ) );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->search_min_comments ) )
|
||||
{
|
||||
$filter->minimumComments( \IPS\Request::i()->search_min_comments );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->search_min_replies ) )
|
||||
{
|
||||
$filter->minimumComments( \IPS\Request::i()->search_min_replies + 1 );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->search_min_reviews ) )
|
||||
{
|
||||
$filter->minimumReviews( \IPS\Request::i()->search_min_reviews );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->search_min_views ) )
|
||||
{
|
||||
$filter->minimumViews( \IPS\Request::i()->search_min_views );
|
||||
}
|
||||
|
||||
$query->filterByContent( array( $filter ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Filter by author */
|
||||
if ( isset( \IPS\Request::i()->author ) )
|
||||
{
|
||||
$author = \IPS\Member::load( \IPS\Request::i()->author, 'name' );
|
||||
if ( $author->member_id )
|
||||
{
|
||||
$query->filterByAuthor( $author );
|
||||
}
|
||||
}
|
||||
|
||||
/* Filter by club */
|
||||
if ( isset( \IPS\Request::i()->club ) AND \IPS\Settings::i()->clubs )
|
||||
{
|
||||
$query->filterByClub( explode( ',', \IPS\Request::i()->club ) );
|
||||
}
|
||||
|
||||
/* Set time cutoffs */
|
||||
foreach ( array( 'start' => 'filterByCreateDate', 'updated' => 'filterByLastUpdatedDate' ) as $k => $method )
|
||||
{
|
||||
$beforeKey = "{$k}_before";
|
||||
$afterKey = "{$k}_after";
|
||||
if ( isset( \IPS\Request::i()->$beforeKey ) or isset( \IPS\Request::i()->$afterKey ) )
|
||||
{
|
||||
foreach ( array( 'before', 'after' ) as $l )
|
||||
{
|
||||
$$l = NULL;
|
||||
$key = "{$l}Key";
|
||||
if ( isset( \IPS\Request::i()->$$key ) AND \IPS\Request::i()->$$key != 'any' )
|
||||
{
|
||||
switch ( \IPS\Request::i()->$$key )
|
||||
{
|
||||
case 'day':
|
||||
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) );
|
||||
break;
|
||||
|
||||
case 'week':
|
||||
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P1W' ) );
|
||||
break;
|
||||
|
||||
case 'month':
|
||||
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) );
|
||||
break;
|
||||
|
||||
case 'six_months':
|
||||
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P6M' ) );
|
||||
break;
|
||||
|
||||
case 'year':
|
||||
$$l = \IPS\DateTime::create()->sub( new \DateInterval( 'P1Y' ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
$$l = \IPS\DateTime::ts( \IPS\Request::i()->$$key );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$query->$method( $after, $before );
|
||||
}
|
||||
}
|
||||
|
||||
/* Set Order */
|
||||
if ( ! isset( \IPS\Request::i()->sortby ) )
|
||||
{
|
||||
\IPS\Request::i()->sortby = $query->getDefaultSortMethod();
|
||||
}
|
||||
|
||||
switch( \IPS\Request::i()->sortby )
|
||||
{
|
||||
case 'newest':
|
||||
$query->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_CREATED );
|
||||
break;
|
||||
|
||||
case 'relevancy':
|
||||
$query->setOrder( \IPS\Content\Search\Query::ORDER_RELEVANCY );
|
||||
break;
|
||||
}
|
||||
|
||||
$flags = ( isset( \IPS\Request::i()->eitherTermsOrTags ) and \IPS\Request::i()->eitherTermsOrTags === 'and' ) ? \IPS\Content\Search\Query::TERM_AND_TAGS : \IPS\Content\Search\Query::TERM_OR_TAGS;
|
||||
$operator = NULL;
|
||||
|
||||
if ( isset( \IPS\Request::i()->search_and_or ) and in_array( \IPS\Request::i()->search_and_or, array( \IPS\Content\Search\Query::OPERATOR_OR, \IPS\Content\Search\Query::OPERATOR_AND ) ) )
|
||||
{
|
||||
$operator = \IPS\Request::i()->search_and_or;
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->search_in ) and \IPS\Request::i()->search_in === 'titles' )
|
||||
{
|
||||
$flags = $flags | \IPS\Content\Search\Query::TERM_TITLES_ONLY;
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return new \IPS\Content\Search\ApiResponse(
|
||||
200,
|
||||
array( $query, $flags, isset( \IPS\Request::i()->q ) ? ( \IPS\Request::i()->q ) : NULL, isset( \IPS\Request::i()->tags ) ? explode( ',', \IPS\Request::i()->tags ) : NULL, $operator ),
|
||||
isset( \IPS\Request::i()->page ) ? \IPS\Request::i()->page : 1,
|
||||
NULL,
|
||||
0,
|
||||
$this->member,
|
||||
isset( \IPS\Request::i()->perPage ) ? \IPS\Request::i()->perPage : NULL
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,12 +6,6 @@
|
||||
"do": "",
|
||||
"restriction": "view_dashboard"
|
||||
},
|
||||
"security": {
|
||||
"tab": "core",
|
||||
"controller": "security",
|
||||
"do": "",
|
||||
"restriction": "security_manage"
|
||||
},
|
||||
"files": {
|
||||
"tab": "core",
|
||||
"controller": "files",
|
||||
@@ -48,7 +42,7 @@
|
||||
"tab": "core",
|
||||
"controller": "api",
|
||||
"do": "",
|
||||
"restriction": "api_manage"
|
||||
"restriction": "api_splash"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
@@ -86,7 +80,7 @@
|
||||
"tab": "core",
|
||||
"controller": "login",
|
||||
"do": "",
|
||||
"restriction": "login_manage"
|
||||
"restriction": "login_access"
|
||||
},
|
||||
"contactus": {
|
||||
"tab": "core",
|
||||
@@ -186,18 +180,6 @@
|
||||
}
|
||||
},
|
||||
"membersettings": {
|
||||
"registration": {
|
||||
"tab": "members",
|
||||
"controller": "registration",
|
||||
"do": "",
|
||||
"restriction": "registration_manage"
|
||||
},
|
||||
"spam": {
|
||||
"tab": "members",
|
||||
"controller": "spam",
|
||||
"do": "",
|
||||
"restriction": "spam_manage"
|
||||
},
|
||||
"profiles": {
|
||||
"tab": "members",
|
||||
"controller": "profiles",
|
||||
@@ -210,12 +192,6 @@
|
||||
"do": "",
|
||||
"restriction": "reps_manage"
|
||||
},
|
||||
"warnings": {
|
||||
"tab": "members",
|
||||
"controller": "warnings",
|
||||
"do": "",
|
||||
"restriction": "warn_settings"
|
||||
},
|
||||
"notifications": {
|
||||
"tab": "members",
|
||||
"controller": "notifications",
|
||||
@@ -235,6 +211,26 @@
|
||||
"restriction": "ranks_manage"
|
||||
}
|
||||
},
|
||||
"moderation": {
|
||||
"reportedContent": {
|
||||
"tab": "members",
|
||||
"controller": "reportedContent",
|
||||
"do": "",
|
||||
"restriction": "reportedContent_manage"
|
||||
},
|
||||
"spam": {
|
||||
"tab": "members",
|
||||
"controller": "spam",
|
||||
"do": "",
|
||||
"restriction": "spam_manage"
|
||||
},
|
||||
"warnings": {
|
||||
"tab": "members",
|
||||
"controller": "warnings",
|
||||
"do": "",
|
||||
"restriction": "warn_settings"
|
||||
}
|
||||
},
|
||||
"staff": {
|
||||
"moderators": {
|
||||
"tab": "members",
|
||||
@@ -327,25 +323,49 @@
|
||||
"do": "",
|
||||
"restriction": "membervisits_manage"
|
||||
},
|
||||
"membersactivity": {
|
||||
"tab": "stats",
|
||||
"controller": "membersactivity",
|
||||
"do": "",
|
||||
"restriction": "membersactivity_manage"
|
||||
},
|
||||
"onlineusers": {
|
||||
"tab": "stats",
|
||||
"controller": "onlineusers",
|
||||
"do": "",
|
||||
"restriction": "onlineusers_manage"
|
||||
},
|
||||
"deviceusage": {
|
||||
"tab": "stats",
|
||||
"controller": "deviceusage",
|
||||
"do": "",
|
||||
"restriction": "deviceusage_manage"
|
||||
}
|
||||
},
|
||||
"activitystats": {
|
||||
"memberactivity": {
|
||||
"communityactivity": {
|
||||
"tab": "stats",
|
||||
"controller": "memberactivity",
|
||||
"controller": "communityactivity",
|
||||
"do": "",
|
||||
"restriction": "memberactivity_manage"
|
||||
"restriction": "communityactivity_manage"
|
||||
},
|
||||
"keywords": {
|
||||
"tab": "stats",
|
||||
"controller": "keywords",
|
||||
"do": "",
|
||||
"restriction": "keywords_manage"
|
||||
},
|
||||
"reactions": {
|
||||
"tab": "stats",
|
||||
"controller": "reactions",
|
||||
"do": "",
|
||||
"restriction": "reactions_manage"
|
||||
},
|
||||
"tags": {
|
||||
"tab": "stats",
|
||||
"controller": "tags",
|
||||
"do": "",
|
||||
"restriction": "tags_manage"
|
||||
}
|
||||
},
|
||||
"messengerstats": {
|
||||
@@ -363,6 +383,18 @@
|
||||
"controller": "clubs",
|
||||
"do": "",
|
||||
"restriction": "clubs_manage"
|
||||
},
|
||||
"fields": {
|
||||
"tab": "community",
|
||||
"controller": "fields",
|
||||
"do": "",
|
||||
"restriction": "fields_manage"
|
||||
},
|
||||
"settings": {
|
||||
"tab": "community",
|
||||
"controller": "settings",
|
||||
"do": "",
|
||||
"restriction": "clubs_settings_manage"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,13 @@
|
||||
"menu_manage": "menu_manage"
|
||||
},
|
||||
"api": {
|
||||
"api_splash": "api_splash",
|
||||
"oauth_manage": "oauth_manage",
|
||||
"oauth_add": "oauth_add",
|
||||
"oauth_edit": "oauth_edit",
|
||||
"oauth_delete": "oauth_delete",
|
||||
"oauth_tokens": "oauth_tokens",
|
||||
"oauth_secrets": "oauth_secrets",
|
||||
"api_manage": "api_manage",
|
||||
"api_add": "api_add",
|
||||
"api_edit": "api_edit",
|
||||
@@ -52,7 +59,11 @@
|
||||
},
|
||||
"settings": {
|
||||
"login": {
|
||||
"login_manage": "login_manage"
|
||||
"login_access": "login_access",
|
||||
"login_manage": "login_manage",
|
||||
"login_settings": "login_settings",
|
||||
"login_account_management": "login_account_management",
|
||||
"registration_settings": "registration_settings"
|
||||
},
|
||||
"email": {
|
||||
"email_manage": "email_manage",
|
||||
@@ -72,9 +83,6 @@
|
||||
"files": {
|
||||
"files_manage": "files_manage"
|
||||
},
|
||||
"security": {
|
||||
"security_manage": "security_manage"
|
||||
},
|
||||
"posting": {
|
||||
"posting_manage": "posting_manage",
|
||||
"posting_manage_profanity": "posting_manage_profanity",
|
||||
@@ -173,31 +181,9 @@
|
||||
"ban": {
|
||||
"ban_manage": "ban_manage"
|
||||
},
|
||||
"spam": {
|
||||
"spam_manage": "spam_manage",
|
||||
"spam_service_log": "spam_service_log",
|
||||
"qanda_manage": "qanda_manage",
|
||||
"qanda_add": "qanda_add",
|
||||
"qanda_edit": "qanda_edit",
|
||||
"qanda_delete": "qanda_delete"
|
||||
},
|
||||
"notifications": {
|
||||
"notifications_manage": "notifications_manage"
|
||||
},
|
||||
"warnings": {
|
||||
"warn_settings": "warn_settings",
|
||||
"reasons_view": "reasons_view",
|
||||
"reasons_edit": "reasons_edit",
|
||||
"reasons_add": "reasons_add",
|
||||
"reasons_delete": "reasons_delete",
|
||||
"actions_view": "actions_view",
|
||||
"actions_edit": "actions_edit",
|
||||
"actions_add": "actions_add",
|
||||
"actions_delete": "actions_delete"
|
||||
},
|
||||
"registration": {
|
||||
"registration_manage": "registration_manage"
|
||||
},
|
||||
"reactions": {
|
||||
"reactions_manage": "reactions_manage"
|
||||
}
|
||||
@@ -285,9 +271,6 @@
|
||||
"dashboard": {
|
||||
"view_dashboard": "view_dashboard"
|
||||
},
|
||||
"security": {
|
||||
"security_manage": "security_manage"
|
||||
},
|
||||
"files": {
|
||||
"files_view": "files_view",
|
||||
"files_delete": "files_delete",
|
||||
@@ -324,14 +307,60 @@
|
||||
"membervisits": {
|
||||
"membervisits_manage": "membervisits_manage"
|
||||
},
|
||||
"memberactivity": {
|
||||
"memberactivity_manage": "memberactivity_manage"
|
||||
},
|
||||
"onlineusers": {
|
||||
"onlineusers_manage": "onlineusers_manage"
|
||||
},
|
||||
"membersactivity": {
|
||||
"membersactivity_manage": "membersactivity_manage"
|
||||
},
|
||||
"deviceusage": {
|
||||
"deviceusage_manage": "deviceusage_manage"
|
||||
}
|
||||
},
|
||||
"system": [],
|
||||
"moderation": {
|
||||
"reportedContent": {
|
||||
"reportedContent_manage": "reportedContent_manage"
|
||||
},
|
||||
"spam": {
|
||||
"spam_manage": "spam_manage",
|
||||
"spam_service_log": "spam_service_log",
|
||||
"qanda_manage": "qanda_manage",
|
||||
"qanda_add": "qanda_add",
|
||||
"qanda_edit": "qanda_edit",
|
||||
"qanda_delete": "qanda_delete",
|
||||
"spam_whitelist_manage": "spam_whitelist_manage",
|
||||
"spam_whitelist_add": "spam_whitelist_add",
|
||||
"spam_whitelist_edit": "spam_whitelist_edit",
|
||||
"spam_whitelist_delete": "spam_whitelist_delete"
|
||||
},
|
||||
"warnings": {
|
||||
"warn_settings": "warn_settings",
|
||||
"reasons_view": "reasons_view",
|
||||
"reasons_edit": "reasons_edit",
|
||||
"reasons_add": "reasons_add",
|
||||
"reasons_delete": "reasons_delete",
|
||||
"actions_view": "actions_view",
|
||||
"actions_edit": "actions_edit",
|
||||
"actions_add": "actions_add",
|
||||
"actions_delete": "actions_delete"
|
||||
},
|
||||
"reportedContentTypes": {
|
||||
"reportedContentTypes_manage": "reportedContentTypes_manage"
|
||||
}
|
||||
},
|
||||
"activitystats": {
|
||||
"communityactivity": {
|
||||
"communityactivity_manage": "communityactivity_manage"
|
||||
},
|
||||
"keywords": {
|
||||
"keywords_manage": "keywords_manage"
|
||||
},
|
||||
"reactions": {
|
||||
"reactionsstats_manage": "reactionsstats_manage"
|
||||
},
|
||||
"tagsusage": {
|
||||
"tagsusage_manage": "tagsusage_manage"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,15 @@
|
||||
{
|
||||
"app=core&module=activitystats&controller=communityactivity": {
|
||||
"lang_key": "menu__core_activitystats_communityactivity",
|
||||
"restriction": null,
|
||||
"keywords": [
|
||||
"active members",
|
||||
"activity",
|
||||
"community activity",
|
||||
"member activity",
|
||||
"new posts"
|
||||
]
|
||||
},
|
||||
"app=core&module=activitystats&controller=keywords": {
|
||||
"lang_key": "menu__core_activitystats_keywords",
|
||||
"restriction": null,
|
||||
@@ -8,15 +19,6 @@
|
||||
"tracking"
|
||||
]
|
||||
},
|
||||
"app=core&module=activitystats&controller=memberactivity": {
|
||||
"lang_key": "menu__core_activitystats_memberactivity",
|
||||
"restriction": null,
|
||||
"keywords": [
|
||||
"active members",
|
||||
"activity",
|
||||
"member activity"
|
||||
]
|
||||
},
|
||||
"app=core&module=applications&controller=api": {
|
||||
"lang_key": "menu__core_applications_api",
|
||||
"restriction": "api_manage",
|
||||
@@ -73,6 +75,15 @@
|
||||
"viglink"
|
||||
]
|
||||
},
|
||||
"app=core&module=applications&controller=enhancements&do=edit&id=core_FacebookPixel": {
|
||||
"lang_key": "menu__core_applications_enhancements",
|
||||
"restriction": "enhancements_manage",
|
||||
"keywords": [
|
||||
"facebook",
|
||||
"facebook pixel",
|
||||
"pixel"
|
||||
]
|
||||
},
|
||||
"app=core&module=applications&controller=enhancements&do=edit&id=core_GoogleMaps&searchResult=form_googlemaps": {
|
||||
"lang_key": "googlemaps",
|
||||
"restriction": "enhancements_manage",
|
||||
@@ -81,15 +92,6 @@
|
||||
"maps"
|
||||
]
|
||||
},
|
||||
"app=core&module=applications&controller=enhancements&do=edit&id=core_Sparkpost": {
|
||||
"lang_key": "enhancements__core_Sparkpost",
|
||||
"restriction": "enhancements_manage",
|
||||
"keywords": [
|
||||
"bulk mail",
|
||||
"email",
|
||||
"sparkpost"
|
||||
]
|
||||
},
|
||||
"app=core&module=applications&controller=enhancements&do=edit&id=core_Viglink&searchResult=form_viglink_account_type": {
|
||||
"lang_key": "viglink_account_type",
|
||||
"restriction": "enhancements_manage",
|
||||
@@ -239,6 +241,22 @@
|
||||
"smilies"
|
||||
]
|
||||
},
|
||||
"app=core&module=editor&controller=emoticons&tab=custom": {
|
||||
"lang_key": "custom_emoji",
|
||||
"restriction": "emoticons_manage",
|
||||
"keywords": [
|
||||
"emoticon",
|
||||
"smiley",
|
||||
"smilie"
|
||||
]
|
||||
},
|
||||
"app=core&module=editor&controller=emoticons&tab=standard": {
|
||||
"lang_key": "standard_emoji",
|
||||
"restriction": "emoticons_manage",
|
||||
"keywords": [
|
||||
"emoji"
|
||||
]
|
||||
},
|
||||
"app=core&module=editor&controller=settings": {
|
||||
"lang_key": "menu__core_editor_settings",
|
||||
"restriction": "settings_manage",
|
||||
@@ -909,27 +927,6 @@
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles": {
|
||||
"lang_key": "menu__core_membersettings_profiles",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
"about me",
|
||||
"custom profile fields"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=completion": {
|
||||
"lang_key": "profile_completion",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
"complete my profile",
|
||||
"complete profile",
|
||||
"complete your profile",
|
||||
"profile completion",
|
||||
"register completion",
|
||||
"registration compltion",
|
||||
"sign up completion"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=fields": {
|
||||
"lang_key": "profile_fields",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
@@ -941,14 +938,27 @@
|
||||
"profile fields"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=form_allow_gravatars": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilecompletion": {
|
||||
"lang_key": "profile_completion",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
"complete my profile",
|
||||
"complete profile",
|
||||
"complete your profile",
|
||||
"profile completion",
|
||||
"register completion",
|
||||
"registration completion",
|
||||
"sign up completion"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=form_allow_gravatars": {
|
||||
"lang_key": "allow_gravatars",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
"gravatar"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=form_letter_photos": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=form_letter_photos": {
|
||||
"lang_key": "letter_photos",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
@@ -962,7 +972,7 @@
|
||||
"profile photo"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=form_profile_comments": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=form_profile_comments": {
|
||||
"lang_key": "profile_comments",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
@@ -970,28 +980,28 @@
|
||||
"profile statuses"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=form_signatures_enabled": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=form_signatures_enabled": {
|
||||
"lang_key": "signatures_enabled",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
"signatures"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=form_user_name_length": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=form_user_name_length": {
|
||||
"lang_key": "user_name_length",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
"name length"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=form_username_characters": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=form_username_characters": {
|
||||
"lang_key": "username_characters",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
"username characters"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=ignore_system_on": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=ignore_system_on": {
|
||||
"lang_key": "ignore_system_on",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
@@ -999,14 +1009,14 @@
|
||||
"ignoring"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=profile_birthday_type": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=profile_birthday_type": {
|
||||
"lang_key": "profile_birthday_type",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
"birthday"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=profile_comment_approval": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=profile_comment_approval": {
|
||||
"lang_key": "profile_comment_approval",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
@@ -1014,7 +1024,7 @@
|
||||
"profile statuses"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=prune_member_history": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=prune_member_history": {
|
||||
"lang_key": "prune_member_history",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
@@ -1022,7 +1032,7 @@
|
||||
"member history"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=profiles&tab=settings&searchResult=user_name_length": {
|
||||
"app=core&module=membersettings&controller=profiles&tab=profilesettings&searchResult=user_name_length": {
|
||||
"lang_key": "user_name_length",
|
||||
"restriction": "profiles_manage",
|
||||
"keywords": [
|
||||
@@ -1049,55 +1059,6 @@
|
||||
"titles"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=registration": {
|
||||
"lang_key": "menu__core_membersettings_registration",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"approve",
|
||||
"confirmation",
|
||||
"coppa",
|
||||
"registration",
|
||||
"validate",
|
||||
"validation"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=registration&searchResult=form_allow_reg": {
|
||||
"lang_key": "allow_reg",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"allow registrations",
|
||||
"new registrations",
|
||||
"registration",
|
||||
"registrations"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=registration&searchResult=new_reg_notify": {
|
||||
"lang_key": "new_reg_notify",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"email on",
|
||||
"email on new registration",
|
||||
"new registrations",
|
||||
"notify",
|
||||
"notify new registration",
|
||||
"registrations"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=registration&searchResult=quick_register": {
|
||||
"lang_key": "quick_register",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"quick register",
|
||||
"register"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=registration&searchResult=use_coppa": {
|
||||
"lang_key": "use_coppa",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"coppa"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=reputation": {
|
||||
"lang_key": "menu__core_membersettings_reputation",
|
||||
"restriction": "reps_manage",
|
||||
@@ -1230,7 +1191,24 @@
|
||||
"winner"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=spam": {
|
||||
"app=core&module=messengerstats&controller=pmstats": {
|
||||
"lang_key": "menu__core_members_pmstats",
|
||||
"restriction": null,
|
||||
"keywords": [
|
||||
"message statistics",
|
||||
"Messenger Statistics",
|
||||
"private messages"
|
||||
]
|
||||
},
|
||||
"app=core&module=moderation&controller=reportedContent": {
|
||||
"lang_key": "menu__core_moderation_reportedContent",
|
||||
"restriction": "reportedContent_manage",
|
||||
"keywords": [
|
||||
"moderation",
|
||||
"report"
|
||||
]
|
||||
},
|
||||
"app=core&module=moderation&controller=spam": {
|
||||
"lang_key": "menu__core_membersettings_spam",
|
||||
"restriction": "spam_manage",
|
||||
"keywords": [
|
||||
@@ -1238,14 +1216,14 @@
|
||||
"spammers"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=spam&do=serviceLogs": {
|
||||
"app=core&module=moderation&controller=spam&do=serviceLogs": {
|
||||
"lang_key": "spamlogs",
|
||||
"restriction": "spam_service_log",
|
||||
"keywords": [
|
||||
"spam logs"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=spam&searchResult=bot_antispam_type": {
|
||||
"app=core&module=moderation&controller=spam&searchResult=bot_antispam_type": {
|
||||
"lang_key": "bot_antispam_type",
|
||||
"restriction": "spam_manage",
|
||||
"keywords": [
|
||||
@@ -1254,7 +1232,7 @@
|
||||
"security question"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=spam&searchResult=guest_captcha": {
|
||||
"app=core&module=moderation&controller=spam&searchResult=guest_captcha": {
|
||||
"lang_key": "guest_captcha_search_target",
|
||||
"restriction": "spam_manage",
|
||||
"keywords": [
|
||||
@@ -1264,7 +1242,7 @@
|
||||
"guest posts"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=spam&tab=captcha": {
|
||||
"app=core&module=moderation&controller=spam&tab=captcha": {
|
||||
"lang_key": "spamprevention_captcha",
|
||||
"restriction": "spam_manage",
|
||||
"keywords": [
|
||||
@@ -1273,14 +1251,14 @@
|
||||
"recaptcha"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=spam&tab=flagging": {
|
||||
"app=core&module=moderation&controller=spam&tab=flagging": {
|
||||
"lang_key": "spamprevention_flagging",
|
||||
"restriction": "spam_manage",
|
||||
"keywords": [
|
||||
"flagging"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=spam&tab=qanda": {
|
||||
"app=core&module=moderation&controller=spam&tab=qanda": {
|
||||
"lang_key": "qanda_settings",
|
||||
"restriction": "qanda_manage",
|
||||
"keywords": [
|
||||
@@ -1290,8 +1268,8 @@
|
||||
"registration"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=spam&tab=service": {
|
||||
"lang_key": "enhancements__core_SpamMonitoring",
|
||||
"app=core&module=moderation&controller=spam&tab=service": {
|
||||
"lang_key": "moderation",
|
||||
"restriction": "spam_manage",
|
||||
"keywords": [
|
||||
"ips spam monitor",
|
||||
@@ -1299,8 +1277,8 @@
|
||||
"ips spam service"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=warnings": {
|
||||
"lang_key": "menu__core_membersettings_warnings",
|
||||
"app=core&module=moderation&controller=warnings": {
|
||||
"lang_key": "menu__core_moderation_warnings",
|
||||
"restriction": "warn_settings",
|
||||
"keywords": [
|
||||
"acknowledge",
|
||||
@@ -1309,7 +1287,7 @@
|
||||
"warnings"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=warnings&tab=settings&searchResult=form_warn_on": {
|
||||
"app=core&module=moderation&controller=warnings&tab=settings&searchResult=form_warn_on": {
|
||||
"lang_key": "warn_on",
|
||||
"restriction": "warn_settings",
|
||||
"keywords": [
|
||||
@@ -1318,7 +1296,7 @@
|
||||
"warning system"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=warnings&tab=settings&searchResult=warn_protected": {
|
||||
"app=core&module=moderation&controller=warnings&tab=settings&searchResult=warn_protected": {
|
||||
"lang_key": "warn_protected",
|
||||
"restriction": "warn_settings",
|
||||
"keywords": [
|
||||
@@ -1326,14 +1304,14 @@
|
||||
"protected"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=warnings&tab=settings&searchResult=warn_show_own": {
|
||||
"app=core&module=moderation&controller=warnings&tab=settings&searchResult=warn_show_own": {
|
||||
"lang_key": "warn_show_own",
|
||||
"restriction": "warn_settings",
|
||||
"keywords": [
|
||||
"own"
|
||||
]
|
||||
},
|
||||
"app=core&module=membersettings&controller=warnings&tab=settings&searchResult=warnings_acknowledge": {
|
||||
"app=core&module=moderation&controller=warnings&tab=settings&searchResult=warnings_acknowledge": {
|
||||
"lang_key": "warnings_acknowledge",
|
||||
"restriction": "warn_settings",
|
||||
"keywords": [
|
||||
@@ -1385,67 +1363,6 @@
|
||||
"uploads"
|
||||
]
|
||||
},
|
||||
"app=core&module=overview&controller=security": {
|
||||
"lang_key": "menu__core_overview_security",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"acp",
|
||||
"admin",
|
||||
"conf",
|
||||
"hack",
|
||||
"htaccess",
|
||||
"http",
|
||||
"security"
|
||||
]
|
||||
},
|
||||
"app=core&module=overview&controller=security&do=settings&searchResult=form_device_management": {
|
||||
"lang_key": "device_management",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"manage authorised browsers",
|
||||
"manage authorised devices",
|
||||
"manage authorized browsers",
|
||||
"manage authorized devices",
|
||||
"manage recently used browsers",
|
||||
"manage recently used devices"
|
||||
]
|
||||
},
|
||||
"app=core&module=overview&controller=security&do=settings&searchResult=form_match_ipaddress": {
|
||||
"lang_key": "match_ipaddress",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"ip address",
|
||||
"session"
|
||||
]
|
||||
},
|
||||
"app=core&module=overview&controller=security&do=settings&searchResult=form_security_remove_acp_link": {
|
||||
"lang_key": "security_remove_acp_link",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"acp",
|
||||
"admin cp",
|
||||
"admincp"
|
||||
]
|
||||
},
|
||||
"app=core&module=overview&controller=security&do=settings&searchResult=form_xforward_matching": {
|
||||
"lang_key": "xforward_matching",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"http_x_forwarded_for",
|
||||
"ip address",
|
||||
"proxies",
|
||||
"proxy"
|
||||
]
|
||||
},
|
||||
"app=core&module=overview&controller=security&do=settings&searchResult=password_strength_meter": {
|
||||
"lang_key": "password_strength_meter",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"meter",
|
||||
"password",
|
||||
"strength"
|
||||
]
|
||||
},
|
||||
"app=core&module=promotion&controller=advertisements": {
|
||||
"lang_key": "menu__core_promotion_advertisements",
|
||||
"restriction": "advertisements_manage",
|
||||
@@ -1638,6 +1555,14 @@
|
||||
"seo"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=advanced&tab=settings&searchResult=match_ipaddress": {
|
||||
"lang_key": "match_ipaddress",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"ip address",
|
||||
"session"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=advanced&tab=settings&searchResult=task_use_cron": {
|
||||
"lang_key": "task_use_cron",
|
||||
"restriction": "advanced_manage_server",
|
||||
@@ -1647,6 +1572,16 @@
|
||||
"tasks"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=advanced&tab=settings&searchResult=xforward_matching": {
|
||||
"lang_key": "xforward_matching",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"http_x_forwarded_for",
|
||||
"ip address",
|
||||
"proxies",
|
||||
"proxy"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=contactus": {
|
||||
"lang_key": "menu__core_settings_contactus",
|
||||
"restriction": "contactus_manage",
|
||||
@@ -1774,6 +1709,15 @@
|
||||
"twitter"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=general&searchResult=form_site_twitter_id": {
|
||||
"lang_key": "site_twitter_id",
|
||||
"restriction": "general_manage",
|
||||
"keywords": [
|
||||
"site twitter",
|
||||
"twitter",
|
||||
"twitter id"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=general&searchResult=form_upgrade_email": {
|
||||
"lang_key": "upgrade_email",
|
||||
"restriction": "general_manage",
|
||||
@@ -1806,7 +1750,85 @@
|
||||
"windows"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&do=settings&searchResult=disable_anonymous": {
|
||||
"app=core&module=settings&controller=login&tab=accountsettings&searchResult=device_management": {
|
||||
"lang_key": "device_management",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"manage authorised browsers",
|
||||
"manage authorised devices",
|
||||
"manage authorized browsers",
|
||||
"manage authorized devices",
|
||||
"manage recently used browsers",
|
||||
"manage recently used devices"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=accountsettings&searchResult=password_strength_meter": {
|
||||
"lang_key": "password_strength_meter",
|
||||
"restriction": "security_manage",
|
||||
"keywords": [
|
||||
"meter",
|
||||
"password",
|
||||
"strength"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=registration": {
|
||||
"lang_key": "menu__core_membersettings_registration",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"approve",
|
||||
"confirmation",
|
||||
"coppa",
|
||||
"registration",
|
||||
"validate",
|
||||
"validation"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=registration&searchResult=allow_reg": {
|
||||
"lang_key": "allow_reg",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"allow registrations",
|
||||
"new registrations",
|
||||
"registration",
|
||||
"registrations"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=registration&searchResult=new_reg_notify": {
|
||||
"lang_key": "new_reg_notify",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"email on",
|
||||
"email on new registration",
|
||||
"new registrations",
|
||||
"notify",
|
||||
"notify new registration",
|
||||
"registrations"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=registration&searchResult=quick_register": {
|
||||
"lang_key": "quick_register",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"quick register",
|
||||
"register"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=registration&searchResult=reg_auth_type": {
|
||||
"lang_key": "reg_auth_type",
|
||||
"restriction": "login_access",
|
||||
"keywords": [
|
||||
"email",
|
||||
"validation"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=registration&searchResult=use_coppa": {
|
||||
"lang_key": "use_coppa",
|
||||
"restriction": "registration_manage",
|
||||
"keywords": [
|
||||
"coppa"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=settings&searchResult=disable_anonymous": {
|
||||
"lang_key": "disable_anonymous",
|
||||
"restriction": "login_manage",
|
||||
"keywords": [
|
||||
@@ -1814,16 +1836,7 @@
|
||||
"anonymous login"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&do=settings&searchResult=form_logins_over_https": {
|
||||
"lang_key": "logins_over_https",
|
||||
"restriction": "login_manage",
|
||||
"keywords": [
|
||||
"https",
|
||||
"secure logins",
|
||||
"ssl"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&do=settings&searchResult=form_new_device_email": {
|
||||
"app=core&module=settings&controller=login&tab=settings&searchResult=form_new_device_email": {
|
||||
"lang_key": "new_device_email",
|
||||
"restriction": "login_manage",
|
||||
"keywords": [
|
||||
@@ -1837,7 +1850,7 @@
|
||||
"new signin email"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&do=settings&searchResult=ipb_bruteforce_attempts": {
|
||||
"app=core&module=settings&controller=login&tab=settings&searchResult=ipb_bruteforce_attempts": {
|
||||
"lang_key": "ipb_bruteforce_attempts",
|
||||
"restriction": "login_manage",
|
||||
"keywords": [
|
||||
@@ -1848,6 +1861,22 @@
|
||||
"logins"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=settings&searchResult=ipb_bruteforce_period": {
|
||||
"lang_key": "ipb_bruteforce_period",
|
||||
"restriction": "login_access",
|
||||
"keywords": [
|
||||
"failed",
|
||||
"login"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=login&tab=settings&searchResult=ipb_bruteforce_unlock": {
|
||||
"lang_key": "ipb_bruteforce_unlock",
|
||||
"restriction": "login_access",
|
||||
"keywords": [
|
||||
"failed",
|
||||
"login"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=mfa": {
|
||||
"lang_key": "menu__core_settings_mfa",
|
||||
"restriction": "mfa_manage",
|
||||
@@ -2134,8 +2163,10 @@
|
||||
"restriction": "posting_manage_profanity",
|
||||
"keywords": [
|
||||
"bad words",
|
||||
"filter",
|
||||
"profanity",
|
||||
"swear words"
|
||||
"swear words",
|
||||
"word filters"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=posting&tab=tags": {
|
||||
@@ -2234,9 +2265,17 @@
|
||||
"lang_key": "guest_terms_bar",
|
||||
"restriction": "terms_manage",
|
||||
"keywords": [
|
||||
"cookie control",
|
||||
"terms bar"
|
||||
]
|
||||
},
|
||||
"app=core&module=settings&controller=terms&searchResult=guest_terms_bar_text": {
|
||||
"lang_key": "guest_terms_bar_text",
|
||||
"restriction": "terms_manage",
|
||||
"keywords": [
|
||||
"cookie control"
|
||||
]
|
||||
},
|
||||
"app=core&module=staff&controller=admin": {
|
||||
"lang_key": "menu__core_staff_admin",
|
||||
"restriction": "restrictions_manage",
|
||||
@@ -2313,15 +2352,6 @@
|
||||
"user activity"
|
||||
]
|
||||
},
|
||||
"app=core&module=stats&controller=pmstats": {
|
||||
"lang_key": "menu__core_members_pmstats",
|
||||
"restriction": null,
|
||||
"keywords": [
|
||||
"message statistics",
|
||||
"Messenger Statistics",
|
||||
"private messages"
|
||||
]
|
||||
},
|
||||
"app=core&module=stats&controller=registrationstats": {
|
||||
"lang_key": "menu__core_members_registrationstats",
|
||||
"restriction": null,
|
||||
|
||||
@@ -103,8 +103,7 @@ class _{class}
|
||||
$this->testSettings();
|
||||
}
|
||||
|
||||
//\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $enabled ), array( 'conf_key=?', 'xxxxxx' ) );
|
||||
//unset( \IPS\Data\Store::i()->settings );
|
||||
//\IPS\Settings::i()->changeValues( array( 'xxxxxx' => $enabled ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief DesignersMode extension: {class}
|
||||
* @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 {date}
|
||||
*/
|
||||
|
||||
namespace IPS\{app}\extensions\core\DesignersMode;
|
||||
|
||||
/* 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 DesignersMode extension: {class}
|
||||
*/
|
||||
class _{class}
|
||||
{
|
||||
/**
|
||||
* Anything need building?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function toBuild()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Designer's mode on
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function on( $data=NULL )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Designer's mode off
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function off( $data=NULL )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile Block
|
||||
* @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 {date}
|
||||
*/
|
||||
|
||||
namespace IPS\{app}\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile Block
|
||||
*/
|
||||
class _{class} extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
return "Hello, World!";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Member ACP Profile - Content Statistics Tab
|
||||
* @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 {date}
|
||||
*/
|
||||
|
||||
namespace IPS\{app}\extensions\core\MemberACPProfileContentTab;
|
||||
|
||||
/* 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 ACP Profile - Content Statistics Tab: Gallery
|
||||
*/
|
||||
class _{class} extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
return "Hello, World!";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile Tab
|
||||
* @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 {date}
|
||||
*/
|
||||
|
||||
namespace IPS\{app}\extensions\core\MemberACPProfileTabs;
|
||||
|
||||
/* 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 Member Profile Tab
|
||||
*/
|
||||
class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
{
|
||||
/**
|
||||
* Get left-column blocks
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function leftColumnBlocks()
|
||||
{
|
||||
return array(
|
||||
'IPS\{app}\extensions\core\MemberACPProfileBlocks\BlockName',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get main-column blocks
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function mainColumnBlocks()
|
||||
{
|
||||
return array(
|
||||
'IPS\{app}\extensions\core\MemberACPProfileBlocks\BlockName',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get right-column blocks
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rightColumnBlocks()
|
||||
{
|
||||
return array(
|
||||
'IPS\{app}\extensions\core\MemberACPProfileBlocks\BlockName',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -87,9 +87,10 @@ class _{class}
|
||||
* @note This is only necessary if availableIn() includes group_promotions
|
||||
* @param \IPS\Member $member Member object to check
|
||||
* @param array $filters Previously defined filters
|
||||
* @param object|NULL $object Calling class
|
||||
* @return bool
|
||||
*/
|
||||
public function matches( \IPS\Member $member, $filters )
|
||||
public function matches( \IPS\Member $member, $filters, $object=NULL )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -23,24 +23,6 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _{class}
|
||||
{
|
||||
/**
|
||||
* Action Buttons
|
||||
*
|
||||
* @param \IPS\Member $member The Member
|
||||
* @return array
|
||||
*/
|
||||
public function actionButtons( $member )
|
||||
{
|
||||
return array(
|
||||
'id' => array(
|
||||
'title' => 'title',
|
||||
'icon' => 'cog',
|
||||
'link' => \IPS\Http\Url::internal( "app={app}&module=&controller=&do=&id={$member->member_id}" ),
|
||||
'class' => ''
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Form
|
||||
*
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Member Restrictions
|
||||
* @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 {date}
|
||||
*/
|
||||
|
||||
namespace IPS\{app}\extensions\core\MemberRestrictions;
|
||||
|
||||
/* 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 Restrictions
|
||||
*/
|
||||
class _{class} extends \IPS\core\MemberACPProfile\Restriction
|
||||
{
|
||||
/**
|
||||
* Modify Edit Restrictions form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( \IPS\Helpers\Form $form )
|
||||
{
|
||||
// $form->add( ... );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Form
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @return array
|
||||
*/
|
||||
public function save( $values )
|
||||
{
|
||||
$return = array();
|
||||
|
||||
// $return['my_restriction'] = array( 'old' => $oldValue, 'new' => $values['my_restriction'] ); // used in changesForHistory()
|
||||
// \IPS\Db::i()->update( ... ); // Actually save the value
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* What restrictions are active on the account?
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function activeRestrictions()
|
||||
{
|
||||
$return = array();
|
||||
|
||||
/*if ( ... )
|
||||
{
|
||||
$return[] = 'my_restricion';
|
||||
}*/
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get details of a change to show on history
|
||||
*
|
||||
* @param array $changes Changes as set in save()
|
||||
* @return array
|
||||
*/
|
||||
public static function changesForHistory( $changes )
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if ( isset( $changes['my_restriction'] ) )
|
||||
{
|
||||
$return[] = \IPS\Member::loggedIn()->language()->addToStack( 'changed_my_restriction', FALSE, array( 'sprintf' => array( $changes['my_restriction']['new'], $changes['my_restriction']['new'] ) ) );
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
@@ -49,10 +49,9 @@ class _{class}
|
||||
* Member has logged on
|
||||
*
|
||||
* @param \IPS\Member $member Member that logged in
|
||||
* @param \IPS\Http\Url $redirectUrl The URL to send the user back to
|
||||
* @return void
|
||||
*/
|
||||
public function onLogin( $member, $returnUrl )
|
||||
public function onLogin( $member )
|
||||
{
|
||||
|
||||
}
|
||||
@@ -61,7 +60,7 @@ class _{class}
|
||||
* Member has logged out
|
||||
*
|
||||
* @param \IPS\Member $member Member that logged out
|
||||
* @param \IPS\Http\Url $redirectUrl The URL to send the user back to
|
||||
* @param \IPS\Http\Url $returnUrl The URL to send the user back to
|
||||
* @return void
|
||||
*/
|
||||
public function onLogout( $member, $returnUrl )
|
||||
|
||||
@@ -35,6 +35,7 @@ class _{class}
|
||||
*/
|
||||
public function settings()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,4 +58,5 @@ class _{class}
|
||||
public function generateSitemap( $filename, $sitemap )
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,7 +45,7 @@
|
||||
{$email->language->addToStack("email_view_other_profile", FALSE, array( 'sprintf' => array( $member->name ) ) )}: {$member->url()}
|
||||
======
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_new_private_message</template_name><template_content_html><![CDATA[{$email->language->addToStack("messenger_notify_title", FALSE, array( 'sprintf' => array( $message->author()->name ) ) )}
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_new_private_message</template_name><template_content_html><![CDATA[{$email->language->addToStack("messenger_notify_title", FALSE, array( 'sprintf' => array( $message->author()->name ) ) )}
|
||||
<br /><br />
|
||||
|
||||
<a href='{$message->url()}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 12px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("messenger_inline_button", FALSE)}</a>
|
||||
@@ -141,7 +141,7 @@
|
||||
|
||||
{$email->language->addToStack("email_url_to_message", FALSE)}: {$message->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>registration_validate</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>registration_validate</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_registration_validate", FALSE)}
|
||||
<br /><br />
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
{$email->language->addToStack("email_validate_link", FALSE)}: {url="app=core&module=system&controller=register&do=validate&vid={$vid}&mid={$member->member_id}" plain="true" base="front"}
|
||||
=====
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_club_request</template_name><template_content_html><![CDATA[<br />
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_club_request</template_name><template_content_html><![CDATA[<br />
|
||||
{$email->language->addToStack("notification__club_request", FALSE, array( 'sprintf' => array( $member->name, $club->name ) ) )}
|
||||
<br /><br />
|
||||
<table width='100%' cellpadding='15' cellspacing='0' border='0' style='background: #f9f9f9;'>
|
||||
@@ -171,17 +171,8 @@
|
||||
</tr>
|
||||
</table>]]></template_content_html><template_data>$club, $member, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("notification__club_request", FALSE, array( 'sprintf' => array( $member->name, $club->name ) ) )}
|
||||
|
||||
{$email->language->addToStack("view_club", FALSE)}: {$club->url()}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_warning_mods</template_name><template_content_html><![CDATA[
|
||||
{{$content = $warning->content();}}
|
||||
|
||||
{{if $content && $content instanceof \IPS\Content\Comment}}
|
||||
{{$item = $content->item();}}
|
||||
{$email->language->addToStack("email_mod_warned_comment", FALSE, array( 'sprintf' => array( \IPS\Member::load( $warning->member )->url(), \IPS\Member::load( $warning->member )->name, \IPS\Member::load( $warning->moderator )->name, $item->indefiniteArticle( $email->language ) ) ) )} <a href='{$content->url()->setQueryString( '_warn', $warning->id )}'>{$content->item()->mapped('title')}</a>
|
||||
{{elseif $content}}
|
||||
{$email->language->addToStack("email_mod_warned_item", FALSE, array( 'sprintf' => array( \IPS\Member::load( $warning->member )->url(), \IPS\Member::load( $warning->member )->name, \IPS\Member::load( $warning->moderator )->name, $content->indefiniteArticle( $email->language ) ) ) )} <a href='{$content->url()->setQueryString( '_warn', $warning->id )}'>{$content->mapped('title')}</a>
|
||||
{{else}}
|
||||
{$email->language->addToStack("email_mod_warned_other", FALSE, array( 'sprintf' => array( \IPS\Member::load( $warning->member )->url(), \IPS\Member::load( $warning->member )->name, \IPS\Member::load( $warning->moderator )->name ) ) )}
|
||||
{{endif}}
|
||||
{$email->language->addToStack("view_club", FALSE)}: {$club->url()}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_warning_mods</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_mod_warned_other", FALSE, array( 'sprintf' => array( \IPS\Member::load( $warning->member )->url(), \IPS\Member::load( $warning->member )->name, \IPS\Member::load( $warning->moderator )->name ) ) )}
|
||||
|
||||
<br />
|
||||
<br />
|
||||
@@ -195,14 +186,6 @@
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 14px;">{$email->language->addToStack("core_warn_reason_" . $warning->reason, FALSE)}</td>
|
||||
</tr>
|
||||
{{endif}}
|
||||
{{if $content}}
|
||||
<tr class='responsive_row'>
|
||||
<td dir='{dir}' width='150' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 14px;" valign='top'><strong>{$email->language->addToStack("email_warn_source", FALSE)}:</strong></td>
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 14px;">
|
||||
<a href='{$content->url()->setQueryString( '_warn', $warning->id )}'>{{if $content instanceof \IPS\Content\Comment}}{$content->item()->mapped('title')}{{else}}{$content->mapped('title')}{{endif}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{endif}}
|
||||
{{if $warning->canViewDetails() or $warning->mq or $warning->rpa or $warning->suspend}}
|
||||
<tr class='responsive_row'>
|
||||
<td dir='{dir}' width='150' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 14px;" valign='top'><strong>{$email->language->addToStack("email_warn_penalty", FALSE)}:</strong></td>
|
||||
@@ -280,19 +263,10 @@
|
||||
<em style='color: #8c8c8c'>— {setting="board_name"}</em>
|
||||
|
||||
]]></template_content_html><template_data>$warning, $email</template_data><template_content_plaintext><![CDATA[
|
||||
{{$content = $warning->content();}}
|
||||
{{if $content && $content instanceof \IPS\Content\Comment}}
|
||||
{{$item = $content->item();}}
|
||||
{$email->language->addToStack("email_mod_warned_comment_plain", FALSE, array( 'sprintf' => array( \IPS\Member::load( $warning->member )->name, \IPS\Member::load( $warning->moderator )->name, $item->indefiniteArticle( $email->language ) ) ) )} {$content->item()->mapped('title')}
|
||||
{{elseif $content}}
|
||||
{$email->language->addToStack("email_mod_warned_item_plain", FALSE, array( 'sprintf' => array( \IPS\Member::load( $warning->member )->name, \IPS\Member::load( $warning->moderator )->name, $content->indefiniteArticle( $email->language ) ) ) )} {$content->mapped('title')}
|
||||
{{else}}
|
||||
{$email->language->addToStack("email_mod_warned_other_plain", FALSE, array( 'sprintf' => array( \IPS\Member::load( $warning->member )->name, \IPS\Member::load( $warning->moderator )->name ) ) )}
|
||||
{{endif}}
|
||||
{$email->language->addToStack("email_mod_warned_other_plain", FALSE, array( 'sprintf' => array( \IPS\Member::load( $warning->member )->name, \IPS\Member::load( $warning->moderator )->name ) ) )}
|
||||
|
||||
=====
|
||||
{{if $warning->canViewDetails()}}{$email->language->addToStack("email_warn_reason", FALSE)}:{$email->language->addToStack("core_warn_reason_" . $warning->reason, FALSE)}{{endif}}
|
||||
{{if $content}}{$email->language->addToStack("email_warn_source", FALSE)}: {{if $content instanceof \IPS\Content\Comment}}{$content->item()->mapped('title')}{{else}}{$content->mapped('title')}{{endif}}{{endif}}
|
||||
{{if $warning->canViewDetails() or $warning->mq or $warning->rpa or $warning->suspend}}{$email->language->addToStack("email_warn_penalty", FALSE)}:
|
||||
{{if $warning->canViewDetails()}}
|
||||
{{if $warning->expire_date}}
|
||||
@@ -321,7 +295,7 @@
|
||||
{{endif}}
|
||||
=====
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_private_message_added</template_name><template_content_html><![CDATA[{$email->language->addToStack("messenger_notify_add_title", FALSE, array( 'sprintf' => array( $added->name ) ) )}
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_private_message_added</template_name><template_content_html><![CDATA[{$email->language->addToStack("messenger_notify_add_title", FALSE, array( 'sprintf' => array( $added->name ) ) )}
|
||||
<br /><br />
|
||||
|
||||
<a href='{$message->url()}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 12px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("messenger_inline_button", FALSE)}</a>
|
||||
@@ -337,14 +311,14 @@
|
||||
<table width='100%' cellpadding='10' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}'>
|
||||
<strong>{$email->language->addToStack("members_in_convo", FALSE, array( 'pluralize' => array( $message->item()->activeParticipants ) ) )}</strong>
|
||||
<strong>{$email->language->addToStack("members_in_convo", FALSE, array( 'pluralize' => array( $message->activeParticipants ) ) )}</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td dir='{dir}'>
|
||||
<table width='100%' cellpadding='0' cellspacing='0' border='0' class='responsive_table'>
|
||||
{{$i = 0;}}
|
||||
{{foreach $message->item()->maps() as $map}}
|
||||
{{foreach $message->maps() as $map}}
|
||||
{{if $map['map_user_active']}}
|
||||
{{if ( $i % 4 ) == 0}}
|
||||
<tr>
|
||||
@@ -387,7 +361,7 @@
|
||||
<table width='100%' cellpadding='15' cellspacing='0' border='0' style='background: #f5f5f5'>
|
||||
<tr>
|
||||
<td dir='{dir}'>
|
||||
<h2 style='margin: 0; font-size: 19px; font-weight: 500'>{$message->item()->title}</h2>
|
||||
<h2 style='margin: 0; font-size: 19px; font-weight: 500'>{$message->title}</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -417,7 +391,7 @@
|
||||
|
||||
{$email->language->addToStack("email_url_to_message", FALSE)}: {$message->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_unapproved_content</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_unapproved_content</template_name><template_content_html><![CDATA[
|
||||
{{if $content->author()->member_id}}
|
||||
{$email->language->addToStack("email_new_content_unapproved", FALSE, array( 'sprintf' => array( $content->author()->url(), $content->author()->name, $content->indefiniteArticle( $email->language ) ) ) )} <a href='{$content->url()}'>{{if $content instanceof \IPS\Content\Comment OR $content instanceof \IPS\Content\Review}}{$content->item()->mapped('title')}{{else}}{$content->mapped('title')}{{endif}}</a>
|
||||
{{elseif $content->author()->real_name}}
|
||||
@@ -446,7 +420,7 @@
|
||||
{{if ( ( $content instanceof \IPS\Content\Comment or $content instanceof \IPS\Content\Review ) and $container = $content->item()->containerWrapper() ) or ( $content instanceof \IPS\Content\Item and $container = $content->containerWrapper() )}}
|
||||
<tr>
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; line-height: 1.5; font-size: 14px; color: #8d8d8d">
|
||||
{$email->language->addToStack("email_posted_in", FALSE, array( 'sprintf' => array( $email->language->addToStack( $container->_titleLanguageKey ) ) ) )}
|
||||
{$email->language->addToStack("email_posted_in", FALSE, array( 'sprintf' => array( $content->container()->getTitleForLanguage( $email->language ) ) ) )}
|
||||
</td>
|
||||
</tr>
|
||||
{{endif}}
|
||||
@@ -479,7 +453,51 @@
|
||||
|
||||
{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $content::$title, FALSE ) ) ) ) )}: {$content->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>account_locked</template_name><template_content_html><![CDATA[<br />
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_automatic_moderation</template_name><template_content_html><![CDATA[{{$item = $reportedContent instanceof \IPS\Content\Item ? $reportedContent : $reportedContent->item();}}
|
||||
{$email->language->addToStack("email_content_automatic_moderation", FALSE, array( 'sprintf' => array( $reportedContent->indefiniteArticle( $email->language ), $reportedContent->url(), $item->mapped('title') ) ) )}
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<table width='100%' cellpadding='0' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}' width='40' valign='top' class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
|
||||
<img src='{$report->author()->get_photo( true, true )}' width='40' height='40' style='border: 1px solid #777777; vertical-align: middle;'>
|
||||
</td>
|
||||
<td dir='{dir}' width='30' valign='top' class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
|
||||
<br />
|
||||
<span style='display: block; width: 0px; height: 0px; border-width: 15px; border-color: transparent #f9f9f9 transparent transparent; border-style: solid'></span>
|
||||
</td>
|
||||
<td dir='{dir}' valign='top' style='background: #f9f9f9;'>
|
||||
<table width='100%' cellpadding='10' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}'>
|
||||
<table width='100%' cellpadding='5' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; line-height: 1.5; font-size: 14px;">
|
||||
{$email->parseTextForEmail( $latestReport['report'], $email->language )|raw}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td dir='{dir}'>
|
||||
<a href='{$report->url()}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $report::$title, FALSE ) ) ) ) )}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br /><br />
|
||||
<em style='color: #8c8c8c'>— {setting="board_name"}</em>]]></template_content_html><template_data>$report, $latestReport, $reportedContent, $email</template_data><template_content_plaintext><![CDATA[{{$item = $reportedContent instanceof \IPS\Content\Item ? $reportedContent : $reportedContent->item();}}
|
||||
{$email->language->addToStack("email_content_automatic_moderation_plain", FALSE, array( 'sprintf' => array( $reportedContent->indefiniteArticle( $email->language ), $item->mapped('title') ) ) )}
|
||||
|
||||
{$email->language->addToStack("go_to_the_report", FALSE)}: {$report->url()}
|
||||
{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $reportedContent::$title, FALSE ) ) ) ) )}: {$reportedContent->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>account_locked</template_name><template_content_html><![CDATA[<br />
|
||||
{$email->language->addToStack("email_account_locked", FALSE, array( 'sprintf' => array( \IPS\Settings::i()->ipb_bruteforce_attempts, $location ) ) )}
|
||||
<br /><br />
|
||||
{$email->language->addToStack("email_account_locked_change_password")}
|
||||
@@ -493,7 +511,9 @@
|
||||
<table width='100%' cellpadding='15' cellspacing='0' border='0' style='background: #f9f9f9;'>
|
||||
<tr>
|
||||
<td dir='{dir}' align='center'>
|
||||
<a href='{url="app=core&module=system&controller=settings&area=password" seoTemplate="settings_password" base="front"}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("email_reset_password", FALSE)}</a>
|
||||
<a href='{url="app=core&module=system&controller=settings&do=secureAccount" seoTemplate="settings_secure" base="front"}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("email_secure_account", FALSE)}</a>
|
||||
{$email->language->addToStack("or", FALSE)}
|
||||
<a href='{url="app=core&module=system&controller=lostpass" seoTemplate="lostpassword" base="front"}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("email_reset_password", FALSE)}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>]]></template_content_html><template_data>$member, $location, $unlockTime=NULL, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("email_account_locked", FALSE, array( 'sprintf' => array( \IPS\Settings::i()->ipb_bruteforce_attempts, $location ) ) )}
|
||||
@@ -505,14 +525,15 @@
|
||||
{$email->language->addToStack("email_account_locked_no_unlock")}
|
||||
{{endif}}
|
||||
|
||||
{$email->language->addToStack("change_password", FALSE)}: {url="app=core&module=system&controller=settings&area=password" seoTemplate="settings_password" base="front"}
|
||||
]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>unsubscribeDigest</template_name><template_content_html><![CDATA[<tr>
|
||||
{$email->language->addToStack("email_secure_account", FALSE)}: {url="app=core&module=system&controller=settings&do=secureAccount" seoTemplate="settings_secure" base="front"}
|
||||
{$email->language->addToStack("or", FALSE)}
|
||||
{$email->language->addToStack("email_reset_password", FALSE)}: {url="app=core&module=system&controller=lostpass" seoTemplate="lostpassword" base="front"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>unsubscribeDigest</template_name><template_content_html><![CDATA[<tr>
|
||||
<td dir='{dir}' valign="top"><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}' valign='middle' align='center' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 12px; line-height: 18px; padding-left: 10px;">
|
||||
{$email->language->addToStack("unsubscribe_blurb", FALSE)} <a href="{url="app=core&module=system&controller=followed&filter=digest" base="front" seoTemplate="followed_content"}" style='color: #4a8aca; text-decoration: none; display: inline-block'>{$email->language->addToStack( 'adjust_digest_prefs', FALSE )}</a>.
|
||||
<br />
|
||||
</td>
|
||||
</tr>]]></template_content_html><template_data>$member, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("unsubscribe_blurb", FALSE)} {$email->language->addToStack( 'adjust_digest_prefs', FALSE )}: {url="app=core&module=system&controller=followed&filter=digest" base="front" seoTemplate="followed_content"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>digests__areaWrapper</template_name><template_content_html><![CDATA[<!-- Add item counts and link to remaining items on site -->
|
||||
</tr>]]></template_content_html><template_data>$member, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("unsubscribe_blurb", FALSE)} {$email->language->addToStack( 'adjust_digest_prefs', FALSE )}: {url="app=core&module=system&controller=followed&filter=digest" base="front" seoTemplate="followed_content"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>digests__areaWrapper</template_name><template_content_html><![CDATA[<!-- Add item counts and link to remaining items on site -->
|
||||
<table width='100%' cellpadding='15' cellspacing='0' border='0' style='background: #f5f5f5'>
|
||||
<tr>
|
||||
<td dir='{dir}'>
|
||||
@@ -529,7 +550,7 @@
|
||||
{$output|raw}
|
||||
</table>
|
||||
<br /><br />]]></template_content_html><template_data>$output, $app, $area, $max, $count, $email</template_data><template_content_plaintext>{$output|raw}
|
||||
</template_content_plaintext></template><template><template_app>core</template_app><template_name>upgrade</template_name><template_content_html><![CDATA[
|
||||
</template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>upgrade</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("dashboard_version_info", FALSE, array( 'sprintf' => $version ))}
|
||||
<br />
|
||||
<br />
|
||||
@@ -559,7 +580,7 @@
|
||||
{$email->language->addToStack('this_is_a_security_update')}
|
||||
{{endif}}
|
||||
|
||||
{$email->language->addToStack("upgrade_now")}: {url="&app=core&module=system&controller=upgrade" base="admin"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_club_join</template_name><template_content_html><![CDATA[<br />
|
||||
{$email->language->addToStack("upgrade_now")}: {url="&app=core&module=system&controller=upgrade" base="admin"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_club_join</template_name><template_content_html><![CDATA[<br />
|
||||
{$email->language->addToStack("notification__club_join", FALSE, array( 'sprintf' => array( $member->name, $club->name ) ) )}
|
||||
<br /><br />
|
||||
<table width='100%' cellpadding='15' cellspacing='0' border='0' style='background: #f9f9f9;'>
|
||||
@@ -570,7 +591,18 @@
|
||||
</tr>
|
||||
</table>]]></template_content_html><template_data>$club, $member, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("notification__club_join", FALSE, array( 'sprintf' => array( $member->name, $club->name ) ) )}
|
||||
|
||||
{$email->language->addToStack("view_club", FALSE)}: {$club->url()}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_new_likes</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("view_club", FALSE)}: {$club->url()}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_unapproved_club</template_name><template_content_html><![CDATA[<br />
|
||||
{$email->language->addToStack("notification__new_club_unapproved", FALSE, array( 'sprintf' => array( $club->owner->name, $club->name ) ) )}
|
||||
<br /><br />
|
||||
<table width='100%' cellpadding='15' cellspacing='0' border='0' style='background: #f9f9f9;'>
|
||||
<tr>
|
||||
<td dir='{dir}' align='center'>
|
||||
<a href='{$club->url()}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("club_view", FALSE)}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>]]></template_content_html><template_data>$club, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("notification__new_club_unapproved", FALSE, array( 'sprintf' => array( $club->owner->name, $club->name ) ) )}
|
||||
|
||||
{$email->language->addToStack("club_view", FALSE)}: {$club->url()}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_new_likes</template_name><template_content_html><![CDATA[
|
||||
{{$item = ( $comment instanceof \IPS\Content\Item ) ? $comment : $comment->item();}}
|
||||
|
||||
{$email->language->addToStack("email_new_likes", FALSE, array( 'sprintf' => array( ( $comment->author()->group['gbw_view_reps'] ) ? $member->name : $email->language->get( 'notifications_anonymous' ), $comment->indefiniteArticle( $email->language ) ) ) )} <a href='{$item->url()}'>{$item->mapped('title')}</a>
|
||||
@@ -614,7 +646,7 @@
|
||||
|
||||
{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $item::$title, FALSE ) ) ) ) )}: {$item->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>email_address_changed</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>email_address_changed</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_email_address_changed", FALSE, array( 'sprintf' => \IPS\Settings::i()->board_name ) )}
|
||||
<br />
|
||||
<br />
|
||||
@@ -657,7 +689,7 @@
|
||||
{$email->language->addToStack("email_old_email", FALSE)}: {$oldEmail}
|
||||
=====
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_unapproved_content_bulk</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_unapproved_content_bulk</template_name><template_content_html><![CDATA[
|
||||
{{if $member->member_id}}
|
||||
{$email->language->addToStack("email_new_content_unapproved_bulk", FALSE, array( 'sprintf' => array( $member->url(), $member->name, $email->language->addToStack( $contentClass::$title . '_pl', FALSE ) ) ) )} <a href='{$container->url()}'>{$container->_title}</a>
|
||||
{{else}}
|
||||
@@ -668,7 +700,7 @@
|
||||
<em style='color: #8c8c8c'>— {setting="board_name"}</em>]]></template_content_html><template_data>$container, $member, $contentClass, $email</template_data><template_content_plaintext><![CDATA[
|
||||
{$email->language->addToStack("email_new_content_unapproved_bulk_plain", FALSE, array( 'sprintf' => array( $member->name, $email->language->addToStack( $contentClass::$title . '_pl', FALSE ) ) ) )} {$container->_title}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>contact_form</template_name><template_content_html><![CDATA[{$email->language->addToStack("email_contact_form", FALSE)}
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>contact_form</template_name><template_content_html><![CDATA[{$email->language->addToStack("email_contact_form", FALSE)}
|
||||
<br />
|
||||
<br />
|
||||
|
||||
@@ -711,7 +743,7 @@
|
||||
|
||||
{$email->language->addToStack("email_contact_said", FALSE, array( 'sprintf' => array( $name, $fromEmail ) ) )}
|
||||
|
||||
{expression="\IPS\Email::buildPlaintextBody( $message )"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_profile_comment</template_name><template_content_html><![CDATA[
|
||||
{expression="\IPS\Email::buildPlaintextBody( $message )"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_profile_comment</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_new_profile_comment", FALSE, array( 'sprintf' => array( $comment->author()->url(), $comment->author()->name ) ) )}
|
||||
|
||||
<br />
|
||||
@@ -764,7 +796,7 @@
|
||||
|
||||
{$email->language->addToStack("email_ignore_user_pm", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>unsubscribeNotification</template_name><template_content_html><![CDATA[{{if $member instanceof \IPS\Member}}
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>unsubscribeNotification</template_name><template_content_html><![CDATA[{{if $member instanceof \IPS\Member}}
|
||||
<tr>
|
||||
<td dir='{dir}' valign="top"><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}' valign='middle' align='center' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 12px; line-height: 18px; padding-left: 10px;">
|
||||
@@ -772,7 +804,7 @@
|
||||
<br />
|
||||
</td>
|
||||
</tr>
|
||||
{{endif}}]]></template_content_html><template_data>$key, $member, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("unsubscribe_blurb", FALSE)} {$email->language->addToStack( 'adjust_notification_prefs', FALSE )}: {url="app=core&module=system&controller=notifications&do=options&type={$key}" seoTemplate="notifications_options"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_new_content</template_name><template_content_html><![CDATA[
|
||||
{{endif}}]]></template_content_html><template_data>$key, $member, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("unsubscribe_blurb", FALSE)} {$email->language->addToStack( 'adjust_notification_prefs', FALSE )}: {url="app=core&module=system&controller=notifications&do=options&type={$key}" seoTemplate="notifications_options"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_new_content</template_name><template_content_html><![CDATA[
|
||||
{{if $content->author()->member_id}}
|
||||
{$email->language->addToStack("email_new_content", FALSE, array( 'sprintf' => array( $content->author()->url(), $content->author()->name, $content->indefiniteArticle( $email->language ) ) ) )} <a href='{$content->url()}'>{$content->mapped('title')}</a>
|
||||
{{elseif $content->author()->real_name}}
|
||||
@@ -800,7 +832,7 @@
|
||||
<table width='100%' cellpadding='5' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; line-height: 1.5; font-size: 14px; color: #8d8d8d">
|
||||
{$email->language->addToStack("email_posted_in", FALSE, array( 'sprintf' => array( $email->language->addToStack( $content->container()->_titleLanguageKey ) ) ) )}
|
||||
{$email->language->addToStack("email_posted_in", FALSE, array( 'sprintf' => array( $content->container()->getTitleForLanguage( $email->language ) ) ) )}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -826,7 +858,7 @@
|
||||
|
||||
{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $content::$title, FALSE ) ) ) ) )}: {$content->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_club_response</template_name><template_content_html><![CDATA[<br />
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_club_response</template_name><template_content_html><![CDATA[<br />
|
||||
{$email->language->addToStack( $response ? "notification__club_response_accepted" : "notification__club_response_declined", FALSE, array( 'sprintf' => array( $club->name ) ) )}
|
||||
<br /><br />
|
||||
<table width='100%' cellpadding='15' cellspacing='0' border='0' style='background: #f9f9f9;'>
|
||||
@@ -837,7 +869,7 @@
|
||||
</tr>
|
||||
</table>]]></template_content_html><template_data>$club, $response, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack( $response ? "notification__club_response_accepted" : "notification__club_response_declined", FALSE, array( 'sprintf' => array($club->name ) ) )}
|
||||
|
||||
{$email->language->addToStack("view_club", FALSE)}: {$club->url()}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>email_change</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("view_club", FALSE)}: {$club->url()}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>email_change</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_complete_email", FALSE)}
|
||||
<br />
|
||||
<br />
|
||||
@@ -877,7 +909,7 @@
|
||||
=====
|
||||
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>lost_password_init</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>lost_password_init</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_lost_pass", FALSE)}
|
||||
<br /><br />
|
||||
|
||||
@@ -893,7 +925,7 @@
|
||||
{$email->language->addToStack("email_reset_password", FALSE)}: {url="app=core&module=system&controller=lostpass&do=validate&vid={$vid}&mid={$member->member_id}" seoTemplate="lostpassword" plain="true" base="front"}
|
||||
=====
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>admin_reg</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>admin_reg</template_name><template_content_html><![CDATA[
|
||||
{expression="$email->language->addToStack( 'email_admin_reg', FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ) ) )"}
|
||||
<br />
|
||||
<br />
|
||||
@@ -945,7 +977,7 @@
|
||||
|
||||
{expression="$email->language->addToStack( 'email_go_to_site', FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ) ) )"}: {setting="base_url"}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_quote</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_quote</template_name><template_content_html><![CDATA[
|
||||
{{$item = $comment instanceof \IPS\Content\Item ? $comment : $comment->item();}}
|
||||
|
||||
{$email->language->addToStack("email_quoted_you", FALSE, array( 'sprintf' => array( $comment->author()->url(), $comment->author()->name, $item->indefiniteArticle( $email->language ) ) ) )}
|
||||
@@ -994,7 +1026,7 @@
|
||||
|
||||
{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $comment::$title, FALSE ) ) ) ) )}: {$comment->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_new_content_bulk</template_name><template_content_html><![CDATA[{{if $member->member_id}}
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_new_content_bulk</template_name><template_content_html><![CDATA[{{if $member->member_id}}
|
||||
{$email->language->addToStack("email_new_content_bulk", FALSE, array( 'sprintf' => array( $member->url(), $member->name, $email->language->addToStack( $contentClass::$title . '_pl_lc', FALSE ) ) ) )} <a href='{$container->url()}'>{$container->_title}</a>
|
||||
{{else}}
|
||||
{$email->language->addToStack("email_new_content_bulk_guest", FALSE, array( 'sprintf' => array( $member->name, $email->language->addToStack( $contentClass::$title . '_pl_lc', FALSE ) ) ) )} <a href='{$container->url()}'>{$container->_title}</a>
|
||||
@@ -1003,7 +1035,7 @@
|
||||
<br /><br />
|
||||
<em style='color: #8c8c8c'>— {setting="board_name"}</em>]]></template_content_html><template_data>$container, $member, $contentClass, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("email_new_content_bulk_plain", FALSE, array( 'sprintf' => array( $member->name, $email->language->addToStack( $contentClass::$title . '_pl_lc', FALSE ) ) ) )} {$container->_title}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>registration_notify</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>registration_notify</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_registration_notify", FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ) ) )}
|
||||
<br />
|
||||
<br />
|
||||
@@ -1051,7 +1083,7 @@
|
||||
|
||||
{$email->language->addToStack("go_to_this_user", FALSE, array( 'sprintf' => array( $member->name ) ) )}: {setting="base_url"}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>emailWrapper</template_name><template_content_html><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>emailWrapper</template_name><template_content_html><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" dir="{dir}">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
@@ -1109,7 +1141,7 @@
|
||||
display: table-cell !important;
|
||||
}
|
||||
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
@media only screen and (max-width: 480px) {
|
||||
a[href^="tel"], a[href^="sms"] {
|
||||
text-decoration: none;
|
||||
color: blue;
|
||||
@@ -1146,9 +1178,15 @@
|
||||
.responsive_fullwidth {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.cOurPicksRow {
|
||||
margin-bottom: 30px;
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) {
|
||||
@media only screen and (min-width: 768px) and (max-width: 1024px) {
|
||||
a[href^="tel"], a[href^="sms"] {
|
||||
text-decoration: none;
|
||||
color: blue;
|
||||
@@ -1163,6 +1201,11 @@
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
/* Share Links */
|
||||
.cShareLink:hover {
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body bgcolor="#f1f1f1" style='direction: {dir}'>
|
||||
@@ -1224,6 +1267,111 @@
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
</tr>
|
||||
{{if $ourPicks AND count( $ourPicks )}}
|
||||
<tr>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}' width='800' bgcolor='#ffffff' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 15px; color: #333333; line-height: 21px;">
|
||||
<table width='100%' cellpadding='0' cellspacing='0' border='0' style='border-bottom: 1px solid #e0e0e0;'>
|
||||
<tr height='15'>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td dir='{dir}' width='30'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}'><strong>{$email->language->addToStack("email_also_interesting")}</strong></td>
|
||||
<td dir='{dir}' width='30'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
</tr>
|
||||
<tr height='15'>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table width='100%' cellpadding='30' cellspacing='0' border='0' class='responsive_table'>
|
||||
<tr>
|
||||
<td>
|
||||
<table width='100%' cellpadding='0' cellspacing='0' border='0' class='responsive_table'>
|
||||
<tr>
|
||||
{{$count = 0;}}
|
||||
{{foreach $ourPicks as $item}}
|
||||
{{if $count == 2}}
|
||||
</tr>
|
||||
<tr height='30'>
|
||||
<td colspan='3' dir='{dir}' class='hidePhone' style='border-bottom: 1px solid #e0e0e0;'>
|
||||
<img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height='30'>
|
||||
<td colspan='3' dir='{dir}' class='hidePhone'>
|
||||
<img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
{{endif}}
|
||||
<td class='responsive_fullwidth cOurPicksRow' dir='{dir}' width='48%' valign='top' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 15px;">
|
||||
{{$staff = \IPS\Member::load( $item->added_by );}}
|
||||
{{$title = $item->objectTitle;}}
|
||||
<h2 style='font-size: 20px; margin: 0;'>
|
||||
<a href="{$item->object()->url()}" style='color: #4a8aca; text-decoration: none;'>{$item->objectTitle}</a>
|
||||
</h2>
|
||||
<p style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 13px; color: #8c8c8c; line-height: 21px; margin: 0">
|
||||
{$item->objectMetaDescription( $email->language )}
|
||||
</p>
|
||||
{{if $text = $item->getText('internal', false)}}
|
||||
<p style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 15px; line-height: 21px; margin-bottom: 0">
|
||||
{truncate="$text" length="100"}
|
||||
</p>
|
||||
{{endif}}
|
||||
<p style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 15px; color: #8c8c8c; line-height: 21px; margin-top: 5px; margin-bottom: 0">
|
||||
<a href="{$item->object()->url()}" style='color: #4a8aca; text-decoration: none;'>{$email->language->addToStack("digests_read_more")}</a>
|
||||
{{if $counts = $item->objectDataCount}}
|
||||
({$counts['words']})
|
||||
{{endif}}
|
||||
</p>
|
||||
<br>
|
||||
|
||||
<table width='100%' cellpadding='0' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}' width='40' valign='top'>
|
||||
<img src='{$staff->get_photo( true, true )}' width='40' height='40' style='border: 1px solid #777777; vertical-align: middle;'>
|
||||
</td>
|
||||
<td dir='{dir}' width='10'>
|
||||
<img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='10' height='1' alt=''>
|
||||
</td>
|
||||
<td dir='{dir}' width='100%' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 13px; color: #8c8c8c;">
|
||||
<strong>{$email->language->addToStack("promoted_by")}</strong><br>
|
||||
{$staff->name}, {datetime="$item->sent" relative="false"}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
{{$count++;}}
|
||||
{{if $count == 1 || $count == 3}}
|
||||
<td dir='{dir}' width='4%' class='hidePhone'>
|
||||
<img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''>
|
||||
</td>
|
||||
{{endif}}
|
||||
{{if ( count( $ourPicks ) === 1 && $count == 1 ) || ( count( $ourPicks ) == 3 && $count == 3 )}}
|
||||
<td width='48%' class='hidePhone'>
|
||||
<img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''>
|
||||
</td>
|
||||
{{endif}}
|
||||
{{endforeach}}
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
</tr>
|
||||
<tr height='25'>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}'><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
</tr>
|
||||
{{endif}}
|
||||
{{if $unsubscribe}}
|
||||
{$unsubscribe|raw}
|
||||
{{endif}}
|
||||
@@ -1236,6 +1384,19 @@
|
||||
<td dir='{dir}' valign="top"><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
</tr>
|
||||
{{endif}}
|
||||
|
||||
{{if \IPS\Settings::i()->site_social_profiles AND \IPS\Settings::i()->social_links_in_email AND $links = json_decode( \IPS\Settings::i()->site_social_profiles, TRUE ) AND count( $links )}}
|
||||
{{$socialColors = array('internal' => '#008b00;', 'delicious' => '#3274D1;', 'deviantart' => '#16A085;', 'digg' => '#14589E;', 'email' => '#444;', 'facebook' => '#3B5998;', 'google' => '#D14836;', 'google-plus' => '#D14836;', 'linkedin' => '#007FB1;', 'reddit' => '#FF4500;', 'stumble' => '#EB4924;', 'twitter' => '#00ACED;', 'vk' => '#507299;', 'weibo' => '#D32F2F;', 'youtube' => '#E62117;', 'foursquare' => '#2D5BE3;', 'etsy' => '#F56400;', 'flickr' => '#202022;', 'github' => '#000000;', 'instagram' => '#E13D62;', 'pinterest' => '#BD081C;', 'slack' => '#42C299;', 'xing' => '#B0D400;');}}
|
||||
<tr>
|
||||
<td dir='{dir}' valign="top"><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}' valign='top' width='800' align='center' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 12px; color: #bdbdbd; line-height: 18px; padding-left: 10px;">
|
||||
{{foreach $links as $profile}}
|
||||
<a href='{$profile['key']}' target='_blank' class='cShareLink' style='width: 28px; height: 28px; line-height: 34px; text-align: center; border-radius: 16px; display: inline-block; color: white !important; font-size: 15px; margin: 4px 2px; background-color: {$socialColors[ $profile['value'] ]}'><img src='{setting="base_url"}applications/core/interface/email/{$profile['value']}.png' width='18' height='18' alt="{$profile['value']}"></a>
|
||||
{{endforeach}}
|
||||
</td>
|
||||
<td dir='{dir}' valign="top"><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
</tr>
|
||||
{{endif}}
|
||||
{{if \IPS\Settings::i()->board_name}}
|
||||
<tr>
|
||||
<td dir='{dir}' valign="top"><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
@@ -1248,7 +1409,7 @@
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
]]></template_content_html><template_data>$subject, $member, $content, $unsubscribe, $placeholderRecipient=FALSE, $introText='', $email</template_data><template_content_plaintext><![CDATA[
|
||||
]]></template_content_html><template_data>$subject, $member, $content, $unsubscribe, $placeholderRecipient=FALSE, $introText='', $email, $ourPicks=NULL</template_data><template_content_plaintext><![CDATA[
|
||||
{{if $member->member_id }}{$email->language->addToStack("email_greeting_member", FALSE, array( 'sprintf' => array( $member->name ) ) )}{{elseif $placeholderRecipient}}{$email->language->addToStack("email_greeting_member", FALSE, array( 'sprintf' => array( '*|member_name|*' ) ) )}{{endif}}
|
||||
{$content|raw}
|
||||
|
||||
@@ -1257,7 +1418,7 @@
|
||||
|
||||
{{if \IPS\Settings::i()->privacy_type != "none"}}{{if \IPS\Settings::i()->privacy_type == "internal"}}{url="app=core&module=system&controller=privacy" seoTemplate="privacy" base="front" plain="true"}{{else}}{setting="privacy_link"}){{endif}}{{endif}}
|
||||
|
||||
{setting="board_name"}{{if \IPS\Settings::i()->site_address and \IPS\Settings::i()->site_address != 'null'}}, {address="\IPS\Settings::i()->site_address"}{{endif}}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_new_status</template_name><template_content_html><![CDATA[
|
||||
{setting="board_name"}{{if \IPS\Settings::i()->site_address and \IPS\Settings::i()->site_address != 'null'}}, {address="\IPS\Settings::i()->site_address"}{{endif}}]]></template_content_plaintext><template_pinned>1</template_pinned></template><template><template_app>core</template_app><template_name>notification_new_status</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_new_status", FALSE, array( 'sprintf' => array( $comment->author()->url(), $comment->author()->name ) ) )}
|
||||
|
||||
<br />
|
||||
@@ -1305,7 +1466,7 @@
|
||||
|
||||
{$email->language->addToStack("email_ignore_user_pm", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_member_follow</template_name><template_content_html><![CDATA[{$email->language->addToStack("notification__member_follow", FALSE, array( 'sprintf' => array( $member->name ) ) )}
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_member_follow</template_name><template_content_html><![CDATA[{$email->language->addToStack("notification__member_follow", FALSE, array( 'sprintf' => array( $member->name ) ) )}
|
||||
|
||||
<br />
|
||||
<br />
|
||||
@@ -1359,7 +1520,7 @@
|
||||
|
||||
{$email->language->addToStack("email_member_following_tip", FALSE)}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_mention</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_mention</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_mentioned", FALSE, array( 'sprintf' => array( $content->author()->name, $content->indefiniteArticle( $email->language ), ( $content instanceof \IPS\Content\Comment ) ? $content->item()->mapped('title') : $content->mapped('title') ) ) )}
|
||||
|
||||
<br />
|
||||
@@ -1405,7 +1566,7 @@
|
||||
<em style='color: #8c8c8c'>— {setting="board_name"}</em>]]></template_content_html><template_data>$content, $email</template_data><template_content_plaintext><![CDATA[
|
||||
{$email->language->addToStack("email_mentioned", FALSE, array( 'sprintf' => array( $content->author()->name, $content->indefiniteArticle( $email->language ), ( $content instanceof \IPS\Content\Comment ) ? $content->item()->mapped('title') : $content->mapped('title') ) ) )}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>registration_complete</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>registration_complete</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_reg_complete", FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ) ) )}
|
||||
|
||||
<br />
|
||||
@@ -1417,7 +1578,7 @@
|
||||
|
||||
{$email->language->addToStack("email_go_to_site", FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ) ) )}: {setting="base_url"}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_club_invitation</template_name><template_content_html><![CDATA[<br />
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_club_invitation</template_name><template_content_html><![CDATA[<br />
|
||||
{$email->language->addToStack("notification__club_invitation_by", FALSE, array( 'sprintf' => array( $invitedBy->name, $club->name ) ) )}
|
||||
<br /><br />
|
||||
<table width='100%' cellpadding='15' cellspacing='0' border='0' style='background: #f9f9f9;'>
|
||||
@@ -1428,13 +1589,13 @@
|
||||
</tr>
|
||||
</table>]]></template_content_html><template_data>$club, $invitedBy, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("notification__club_invitation_by", FALSE, array( 'sprintf' => array( $invitedBy->name, $club->name ) ) )}
|
||||
|
||||
{$email->language->addToStack("club_join", FALSE)}: {$club->url()}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>unsubscribeBulk</template_name><template_content_html><![CDATA[<tr>
|
||||
{$email->language->addToStack("club_join", FALSE)}: {$club->url()}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>unsubscribeBulk</template_name><template_content_html><![CDATA[<tr>
|
||||
<td dir='{dir}' valign="top"><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}' valign='middle' align='center' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 12px; line-height: 18px; padding-left: 10px;">
|
||||
{$email->language->addToStack("unsubscribe_blurb", FALSE)} <a href="{{if $member instanceof \IPS\Member}}{url="app=core&module=system&controller=unsubscribe&email=" seoTemplate="unsubscribe" base="front"}{$member->email}&key={expression="md5( $member->email . ':' . $member->members_pass_hash )"}{{else}}{url="app=core&module=system&controller=unsubscribe&email=" seoTemplate="unsubscribe" base="front"}*|member_email|*&key=*|unsubscribe_key|*{{endif}}" style='color: #4a8aca; text-decoration: none; display: inline-block'>{$email->language->addToStack( 'unsubscribe', FALSE )}</a>.
|
||||
<br />
|
||||
</td>
|
||||
</tr>]]></template_content_html><template_data>$member, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("unsubscribe_blurb", FALSE)} {$email->language->addToStack( 'unsubscribe', FALSE )}: {{if $member instanceof \IPS\Member}}{url="app=core&module=system&controller=unsubscribe&email=" seoTemplate="unsubscribe" base="front"}{$member->email}&key={expression="md5( $member->email . ':' . $member->members_pass_hash )"}{{else}}*|unsubscribe_url|*{{endif}}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_new_review</template_name><template_content_html><![CDATA[
|
||||
</tr>]]></template_content_html><template_data>$member, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("unsubscribe_blurb", FALSE)} {$email->language->addToStack( 'unsubscribe', FALSE )}: {{if $member instanceof \IPS\Member}}{url="app=core&module=system&controller=unsubscribe&email=" seoTemplate="unsubscribe" base="front"}{$member->email}&key={expression="md5( $member->email . ':' . $member->members_pass_hash )"}{{else}}*|unsubscribe_url|*{{endif}}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_new_review</template_name><template_content_html><![CDATA[
|
||||
{{$item = $comment->item();}}
|
||||
|
||||
{{if $comment->author()->member_id}}
|
||||
@@ -1492,7 +1653,7 @@
|
||||
|
||||
{$email->language->addToStack("go_to_this_review", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $comment::$title, FALSE ) ) ) ) )}: {$comment->url('find')}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_profile_reply</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_profile_reply</template_name><template_content_html><![CDATA[
|
||||
{{$item = $comment->item();}}
|
||||
|
||||
{$email->language->addToStack("email_new_profile_reply", FALSE, array( 'sprintf' => array( $comment->author()->url(), $comment->author()->name ) ) )}
|
||||
@@ -1582,7 +1743,7 @@
|
||||
|
||||
{$email->language->addToStack("email_ignore_user_pm", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>new_device</template_name><template_content_html><![CDATA[<br />
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>new_device</template_name><template_content_html><![CDATA[<br />
|
||||
{$email->language->addToStack('new_device_email_intro')}
|
||||
<br />
|
||||
<br />
|
||||
@@ -1622,7 +1783,8 @@
|
||||
<tr>
|
||||
{{if in_array( $device->userAgent()->browser, array( 'Android Browser', 'AppleWebKit', 'Camino', 'Chrome', 'Edge', 'Firefox', 'IEMobile', 'Midori', 'MSIE', 'Opera', 'Puffin', 'Safari', 'SamsungBrowser', 'Silk', 'UCBrowser', 'Vivaldi' ) )}}
|
||||
<td dir='{dir}' width="40" valign="top" class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
|
||||
<img src="{resource="logos/browsers/{expression="str_replace( ' ', '', $device->userAgent()->browser )"}.png" location="interface" app="core"}" width="20" height="20" alt="{$device->userAgent()->browser}" style='border: 0; vertical-align: middle;'>
|
||||
{{$img = str_replace( ' ', '', $device->userAgent()->browser );}}
|
||||
<img src="{resource="logos/browsers/{$img}.png" location="interface" app="core"}" width="20" height="20" alt="{$device->userAgent()->browser}" style='border: 0; vertical-align: middle;'>
|
||||
</td>
|
||||
{{endif}}
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 14px;">
|
||||
@@ -1633,19 +1795,17 @@
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
{{if $device->login_handler and $handlers = \IPS\Login::handlers( TRUE ) and isset( $handlers[ $device->login_handler ] ) and $handler = $handlers[ $device->login_handler ] and method_exists( $handler, 'loginForm' )}}
|
||||
{{if $loginMethod = $device->loginMethod() and $logo = $loginMethod->logoForDeviceInformation()}}
|
||||
<tr class='responsive_row' height="35">
|
||||
<td dir='{dir}' width='150' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 14px;"><strong>{$email->language->addToStack('device_table_login_handler')}</strong></td>
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 14px;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" border="0" bgcolor="#f9f9f9">
|
||||
<tr>
|
||||
{{if $handler::$logo}}
|
||||
<td dir='{dir}' width="40" valign="top" class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
|
||||
<img src="{resource="logos/login/{$handler::$logo}.png" location="interface" app="core"}" width="20" height="20" alt="{$device->userAgent()->browser}" style='border: 0; vertical-align: middle;'>
|
||||
</td>
|
||||
{{endif}}
|
||||
<td dir='{dir}' width="40" valign="top" class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
|
||||
<img src="{$logo}" width="20" height="20" alt="{$email->language->addToStack( 'login_method_' . $loginMethod->id )}" style='border: 0; vertical-align: middle;'>
|
||||
</td>
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 14px;">
|
||||
{$email->language->addToStack( 'login_handler_' . ucfirst( $handler->key ) )}
|
||||
{$email->language->addToStack( 'login_method_' . $loginMethod->id )}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -1687,13 +1847,13 @@
|
||||
|
||||
{$email->language->addToStack('members_device')}: {$device->userAgent()->platform}
|
||||
{$email->language->addToStack('device_table_user_agent')}: {$device->userAgent()->browser}
|
||||
{{if $device->login_handler and $handlers = \IPS\Login::handlers( TRUE ) and isset( $handlers[ $device->login_handler ] ) and $handler = $handlers[ $device->login_handler ] and method_exists( $handler, 'loginForm' )}}{$email->language->addToStack('device_table_login_handler')}: {$email->language->addToStack( 'login_handler_' . ucfirst( $handler->key ) )}{{endif}}
|
||||
{{if $loginMethod = $device->loginMethod() and $logo = $loginMethod->logoForDeviceInformation()}}{$email->language->addToStack('device_table_login_handler')}: {$email->language->addToStack( 'login_method_' . $loginMethod->id )}{{endif}}
|
||||
{{if $location}}{$email->language->addToStack('device_table_location')}: {$location}
|
||||
* {$email->language->addToStack('ip_geolocation_info')}{{endif}}
|
||||
|
||||
{$email->language->addToStack('new_device_email_footer')}
|
||||
|
||||
{{if settings.device_management}}{$email->language->addToStack("new_device_email_action_1", FALSE)}: {url="app=core&module=system&controller=settings&area=devices" seoTemplate="settings_devices" base="front"}{{else}}{$email->language->addToStack("new_device_email_action_2", FALSE)}: {url="app=core&module=system&controller=settings&do=secureAccount" seoTemplate="settings_secure" base="front"}{{endif}}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>digest</template_name><template_content_html><![CDATA[{$email->language->addToStack("digest_$frequency", FALSE)}
|
||||
{{if settings.device_management}}{$email->language->addToStack("new_device_email_action_1", FALSE)}: {url="app=core&module=system&controller=settings&area=devices" seoTemplate="settings_devices" base="front"}{{else}}{$email->language->addToStack("new_device_email_action_2", FALSE)}: {url="app=core&module=system&controller=settings&do=secureAccount" seoTemplate="settings_secure" base="front"}{{endif}}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>digest</template_name><template_content_html><![CDATA[{$email->language->addToStack("digest_$frequency", FALSE)}
|
||||
<br />
|
||||
<br />
|
||||
<em style='color: #8c8c8c'>— {setting="board_name"}</em>
|
||||
@@ -1703,7 +1863,7 @@
|
||||
<br />
|
||||
<%digest%>]]></template_content_html><template_data>$member, $frequency, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("digest_$frequency", FALSE)}
|
||||
|
||||
<%digest%>]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_report_center</template_name><template_content_html><![CDATA[{{$item = $reportedContent instanceof \IPS\Content\Item ? $reportedContent : $reportedContent->item();}}
|
||||
<%digest%>]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_report_center</template_name><template_content_html><![CDATA[{{$item = $reportedContent instanceof \IPS\Content\Item ? $reportedContent : $reportedContent->item();}}
|
||||
{$email->language->addToStack("email_content_reported", FALSE, array( 'sprintf' => array( \IPS\Member::load( $latestReport['report_by'] )->name, $reportedContent->indefiniteArticle( $email->language ), $reportedContent->url(), $item->mapped('title') ) ) )}
|
||||
|
||||
<br />
|
||||
@@ -1747,7 +1907,7 @@
|
||||
{$email->language->addToStack("go_to_the_report", FALSE)}: {$report->url()}
|
||||
{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $reportedContent::$title, FALSE ) ) ) ) )}: {$reportedContent->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>unsubscribeFollow</template_name><template_content_html><![CDATA[<tr>
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>unsubscribeFollow</template_name><template_content_html><![CDATA[<tr>
|
||||
<td dir='{dir}' valign="top"><img src='{setting="base_url"}applications/core/interface/email/spacer.png' width='1' height='1' alt=''></td>
|
||||
<td dir='{dir}' valign='middle' align='center' style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 12px; line-height: 18px; padding-left: 10px;">
|
||||
*|unsubscribe_blurb|*<br>
|
||||
@@ -1756,7 +1916,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
]]></template_content_html><template_data>$key, $member, $email</template_data><template_content_plaintext><![CDATA[*|unsubscribe_blurb|*
|
||||
{$email->language->addToStack("unsubscribe_blurb", FALSE)} {$email->language->addToStack( 'unfollow', FALSE )} ( *|unfollow_link|* ) {$email->language->addToStack( 'or', FALSE )} {$email->language->addToStack( 'adjust_notification_prefs', FALSE )} ( {url="app=core&module=system&controller=notifications&do=options&type={$key}" base="front" seoTemplate="notifications_options"} )]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>notification_new_comment</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("unsubscribe_blurb", FALSE)} {$email->language->addToStack( 'unfollow', FALSE )} ( *|unfollow_link|* ) {$email->language->addToStack( 'or', FALSE )} {$email->language->addToStack( 'adjust_notification_prefs', FALSE )} ( {url="app=core&module=system&controller=notifications&do=options&type={$key}" base="front" seoTemplate="notifications_options"} )]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_new_comment</template_name><template_content_html><![CDATA[
|
||||
{{$item = $comment->item();}}
|
||||
|
||||
{{if $comment->author()->member_id}}
|
||||
@@ -1812,7 +1972,7 @@
|
||||
|
||||
{$email->language->addToStack("go_to_this_post", FALSE)}: {$comment->url('find')}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>warning</template_name><template_content_html><![CDATA[{{$content = $warning->content();}}
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>warning</template_name><template_content_html><![CDATA[{{$content = $warning->content();}}
|
||||
|
||||
{{if $content && $content instanceof \IPS\Content\Comment}}
|
||||
{{$item = $content->item();}}
|
||||
@@ -1970,7 +2130,7 @@
|
||||
{{endif}}
|
||||
|
||||
-- {setting="board_name"}
|
||||
]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>error_log</template_name><template_content_html><![CDATA[
|
||||
]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>error_log</template_name><template_content_html><![CDATA[
|
||||
{expression="$email->language->addToStack( 'email_error_log', FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ) ) )"}
|
||||
<br />
|
||||
<br />
|
||||
@@ -2021,7 +2181,7 @@
|
||||
|
||||
{$email->language->addToStack("email_error_log_info", FALSE)}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>mfaRecovery</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>mfaRecovery</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("mfa_recovery_email_html", FALSE)}
|
||||
<br /><br />
|
||||
|
||||
@@ -2037,7 +2197,7 @@
|
||||
{$email->language->addToStack("mfa_recovery_email_confirm", FALSE)}: {url="app=core&module=system&controller=settings&do=mfarecoveryvalidate&vid={$vid}&mid={$member->member_id}" seoTemplate="mfarecoveryvalidate" plain="true" base="front"}
|
||||
=====
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template><template><template_app>core</template_app><template_name>password_changed</template_name><template_content_html><![CDATA[
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>password_changed</template_name><template_content_html><![CDATA[
|
||||
{$email->language->addToStack("email_password_changed", FALSE, array( 'sprintf' => \IPS\Settings::i()->board_name ) )}
|
||||
|
||||
|
||||
@@ -2045,4 +2205,48 @@
|
||||
<em style='color: #8c8c8c'>— {setting="board_name"}</em>]]></template_content_html><template_data>$email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("email_password_changed", FALSE, array( 'sprintf' => \IPS\Settings::i()->board_name ) )}
|
||||
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext></template></emails>
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>core</template_app><template_name>notification_new_react</template_name><template_content_html><![CDATA[
|
||||
{{$item = ( $comment instanceof \IPS\Content\Item ) ? $comment : $comment->item();}}
|
||||
|
||||
{$email->language->addToStack("email_new_reacted", FALSE, array( 'sprintf' => array( ( $comment->author()->group['gbw_view_reps'] ) ? $member->name : $email->language->get( 'notifications_anonymous' ), $comment->indefiniteArticle( $email->language ) ) ) )} <a href='{$item->url()}'>{$item->mapped('title')}</a>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<table width='100%' cellpadding='0' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}' width='40' valign='top' class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
|
||||
<img src='{$comment->author()->get_photo( true, true )}' width='40' height='40' style='border: 1px solid #777777; vertical-align: middle;'>
|
||||
</td>
|
||||
<td dir='{dir}' width='30' valign='top' class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
|
||||
<br />
|
||||
<span style='display: block; width: 0px; height: 0px; border-width: 15px; border-color: transparent #f9f9f9 transparent transparent; border-style: solid'></span>
|
||||
</td>
|
||||
<td dir='{dir}' valign='top' style='background: #f9f9f9;'>
|
||||
<table width='100%' cellpadding='10' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}'>
|
||||
<table width='100%' cellpadding='5' cellspacing='0' border='0'>
|
||||
<tr>
|
||||
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; line-height: 1.5; font-size: 14px;">
|
||||
{$email->parseTextForEmail( $comment->content(), $email->language )|raw}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td dir='{dir}'>
|
||||
<a href='{$comment->url()}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $comment::$title, FALSE ) ) ) ) )}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br /><br />
|
||||
<em style='color: #8c8c8c'>— {setting="board_name"}</em>]]></template_content_html><template_data>$comment, $member, $email</template_data><template_content_plaintext><![CDATA[
|
||||
{{$item = ( $comment instanceof \IPS\Content\Item ) ? $comment : $comment->item();}}{$email->language->addToStack("email_new_reacted", FALSE, array( 'sprintf' => array( ( $comment->author()->group['gbw_view_reps'] ) ? $member->name : $email->language->get( 'notifications_anonymous' ), $item->indefiniteArticle( $email->language ) ) ) )} {$item->mapped('title')}
|
||||
|
||||
{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $item::$title, FALSE ) ) ) ) )}: {$item->url()}
|
||||
|
||||
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template></emails>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -75,26 +75,14 @@
|
||||
"settings_signature": {
|
||||
"friendly": "settings/signature",
|
||||
"real": "app=core&module=system&controller=settings&area=signature"
|
||||
},
|
||||
"settings_Facebook": {
|
||||
"friendly": "settings/facebook",
|
||||
"real": "app=core&module=system&controller=settings&area=profilesync&service=Facebook"
|
||||
},
|
||||
"settings_Google": {
|
||||
"friendly": "settings/google",
|
||||
"real": "app=core&module=system&controller=settings&area=profilesync&service=Google"
|
||||
},
|
||||
"settings_Linkedin": {
|
||||
"friendly": "settings/linkedin",
|
||||
"real": "app=core&module=system&controller=settings&area=profilesync&service=LinkedIn"
|
||||
},
|
||||
"settings_Microsoft": {
|
||||
"friendly": "settings/microsoft",
|
||||
"real": "app=core&module=system&controller=settings&area=profilesync&service=Microsoft"
|
||||
},
|
||||
"settings_Twitter": {
|
||||
"friendly": "settings/twitter",
|
||||
"real": "app=core&module=system&controller=settings&area=profilesync&service=Twitter"
|
||||
},
|
||||
"settings_login": {
|
||||
"friendly": "settings/login",
|
||||
"real": "app=core&module=system&controller=settings&area=login"
|
||||
},
|
||||
"settings_apps": {
|
||||
"friendly": "settings/apps",
|
||||
"real": "app=core&module=system&controller=settings&area=apps"
|
||||
},
|
||||
"settings": {
|
||||
"friendly": "settings",
|
||||
@@ -117,6 +105,11 @@
|
||||
"friendly": "attachments",
|
||||
"real": "app=core&module=system&controller=attachments"
|
||||
},
|
||||
"cookies": {
|
||||
"friendly": "cookies",
|
||||
"real": "app=core&module=system&controller=cookies",
|
||||
"alias": "cookies"
|
||||
},
|
||||
|
||||
/* Messenger */
|
||||
"messenger_compose": {
|
||||
|
||||
+4252
-1974
File diff suppressed because it is too large.
Load diff
+2801
-341
File diff suppressed because it is too large.
Load diff
@@ -86,7 +86,11 @@
|
||||
},
|
||||
"messengerstats": {
|
||||
"default_controller": "",
|
||||
"protected": false
|
||||
"protected": 0
|
||||
},
|
||||
"moderation": {
|
||||
"default_controller": "",
|
||||
"protected": 0
|
||||
}
|
||||
},
|
||||
"front": {
|
||||
@@ -119,7 +123,7 @@
|
||||
"protected": 0
|
||||
},
|
||||
"contact": {
|
||||
"default_controller": null,
|
||||
"default_controller": "contact",
|
||||
"protected": 0
|
||||
},
|
||||
"status": {
|
||||
@@ -139,19 +143,7 @@
|
||||
"protected": 0
|
||||
},
|
||||
"promote": {
|
||||
"default_controller": "promote",
|
||||
"protected": 0
|
||||
},
|
||||
"activity": {
|
||||
"default_controller": "",
|
||||
"protected": 0
|
||||
},
|
||||
"dashboard": {
|
||||
"default_controller": "dashboard",
|
||||
"protected": 1
|
||||
},
|
||||
"discovery": {
|
||||
"default_controller": "",
|
||||
"default_controller": "ourpicks",
|
||||
"protected": 0
|
||||
}
|
||||
}
|
||||
|
||||
+2556
-1080
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1 +1 @@
|
||||
{"profilesync":"P0Y0M0DT1H0M0S","updatecheck":"P0Y0M1DT0H0M0S","cleanup":"P0Y0M1DT0H0M0S","sitemapgenerator":"P0Y0M0DT0H15M0S","connect":"P0Y0M0DT1H0M0S","queue":"P0Y0M0DT0H1M0S","pop":"P0Y0M0DT0H10M0S","digest":"P0Y0M0DT0H10M0S","publish":"P0Y0M0DT0H10M0S","clearcache":"P0Y0M0DT0H10M0S","clearsessions":"P0Y0M0DT0H30M0S","viewupdates":"P0Y0M0DT0H5M0S","imageproxy":"P0Y0M0DT0H30M0S","cleanupattachments":"P0Y0M0DT12H0M0S","cleanupfiles":"P0Y0M1DT0H0M0S","unlockmembers":"P0Y0M0DT1H0M0S","leaderboard":"P0Y0M0DT6H0M0S","deletecontent":"P0Y0M1DT0H0M0S","clubrebuild":"P0Y0M0DT0H20M0S","onlineusers":"P0Y0M0DT0H15M0S","promote":"P0Y0M0DT0H5M0S"}
|
||||
{"profilesync":"P0Y0M0DT1H0M0S","updatecheck":"P0Y0M1DT0H0M0S","cleanup":"P0Y0M1DT0H0M0S","sitemapgenerator":"P0Y0M0DT0H15M0S","queue":"P0Y0M0DT0H1M0S","pop":"P0Y0M0DT0H10M0S","digest":"P0Y0M0DT0H10M0S","publish":"P0Y0M0DT0H10M0S","clearcache":"P0Y0M0DT0H10M0S","clearsessions":"P0Y0M0DT0H30M0S","viewupdates":"P0Y0M0DT0H5M0S","imageproxy":"P0Y0M0DT0H30M0S","cleanupattachments":"P0Y0M0DT12H0M0S","cleanupfiles":"P0Y0M1DT0H0M0S","unlockmembers":"P0Y0M0DT1H0M0S","leaderboard":"P0Y0M0DT6H0M0S","deletecontent":"P0Y0M1DT0H0M0S","clubrebuild":"P0Y0M0DT0H20M0S","onlineusers":"P0Y0M0DT0H15M0S","promote":"P0Y0M0DT0H5M0S","prunesearchindex":"P0Y0M1DT0H0M0S","prunesystemlogs":"P0Y0M1DT0H0M0S","automaticmoderation":"P0Y0M0DT0H10M0S","usagereporting":"P0Y0M7DT0H0M0S","userAgentStatistics":"P0Y0M0DT0H30M0S"}
|
||||
+6766
-2566
File diff suppressed because it is too large.
Load diff
@@ -212,5 +212,56 @@
|
||||
"101117": "4.2.0 Beta 8",
|
||||
"102000": "4.2.0",
|
||||
"102001": "4.2.0",
|
||||
"102002": "4.2.0"
|
||||
"102002": "4.2.0",
|
||||
"102003": "4.2.0",
|
||||
"102004": "4.2.1",
|
||||
"102005": "4.2.2 Beta 1",
|
||||
"102006": "4.2.2 Beta 2",
|
||||
"102007": "4.2.2",
|
||||
"102008": "4.2.2",
|
||||
"102009": "4.2.2",
|
||||
"102010": "4.2.3 Beta 1",
|
||||
"102011": "4.2.3",
|
||||
"102012": "4.2.3",
|
||||
"102013": "4.2.3",
|
||||
"102014": "4.2.4 Beta 1",
|
||||
"102015": "4.2.4 Beta 2",
|
||||
"102016": "4.2.4",
|
||||
"102017": "4.2.4",
|
||||
"102018": "4.2.4",
|
||||
"102019": "4.2.4",
|
||||
"102020": "4.2.4",
|
||||
"102021": "4.2.5 Beta 1",
|
||||
"102022": "4.2.5 Beta 2",
|
||||
"102023": "4.2.5 Beta 3",
|
||||
"102024": "4.2.5",
|
||||
"102025": "4.2.5",
|
||||
"102026": "4.2.5",
|
||||
"102027": "4.2.5",
|
||||
"102028": "4.2.5",
|
||||
"102029": "4.2.5",
|
||||
"102030": "4.2.6 Beta 1",
|
||||
"102031": "4.2.6 Beta 1",
|
||||
"102032": "4.2.6 Beta 2",
|
||||
"102033": "4.2.6 Beta 3",
|
||||
"102034": "4.2.6",
|
||||
"102035": "4.2.6",
|
||||
"102036": "4.2.6",
|
||||
"102037": "4.2.7 Beta 1",
|
||||
"102038": "4.2.7 Beta 2",
|
||||
"102039": "4.2.7 Beta 3",
|
||||
"102040": "4.2.7 Beta 4",
|
||||
"102041": "4.2.7 Beta 5",
|
||||
"102042": "4.2.7",
|
||||
"102043": "4.2.7",
|
||||
"102044": "4.2.7",
|
||||
"102045": "4.2.7",
|
||||
"102046": "4.2.7",
|
||||
"102047": "4.2.8",
|
||||
"102048": "4.2.8",
|
||||
"103000": "4.3.0 Beta 1",
|
||||
"103002": "4.3.0 Beta 2",
|
||||
"103003": "4.3.0 Beta 3",
|
||||
"103004": "4.3.0 Beta 4",
|
||||
"103005": "4.3.0"
|
||||
}
|
||||
@@ -7,17 +7,6 @@
|
||||
"menu_style": "menu",
|
||||
"embeddable": true
|
||||
},
|
||||
"announcements": {
|
||||
"class": "\\IPS\\Widget\\PermissionCache",
|
||||
"restrict": [
|
||||
"sidebar",
|
||||
"cms"
|
||||
],
|
||||
"default_area": "header",
|
||||
"allow_reuse": false,
|
||||
"menu_style": "menu",
|
||||
"embeddable": true
|
||||
},
|
||||
"stats": {
|
||||
"class": "\\IPS\\Widget\\StaticCache",
|
||||
"restrict": [],
|
||||
@@ -101,5 +90,16 @@
|
||||
"allow_reuse": true,
|
||||
"menu_style": "modal",
|
||||
"embeddable": true
|
||||
},
|
||||
"newsletter": {
|
||||
"class": "\\IPS\\Widget",
|
||||
"restrict": [
|
||||
"sidebar",
|
||||
"cms"
|
||||
],
|
||||
"default_area": "sidebar",
|
||||
"allow_reuse": false,
|
||||
"menu_style": "modal",
|
||||
"embeddable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Community Enhancement: Facebook Pixel
|
||||
* @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 16 May 2017
|
||||
*/
|
||||
|
||||
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 Enhancement: Facebook Pixel
|
||||
*/
|
||||
class _FacebookPixel
|
||||
{
|
||||
/**
|
||||
* @brief IPS-provided enhancement?
|
||||
*/
|
||||
public $ips = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Enhancement is enabled?
|
||||
*/
|
||||
public $enabled = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Enhancement has configuration options?
|
||||
*/
|
||||
public $hasOptions = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Icon data
|
||||
*/
|
||||
public $icon = "facebook.png";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->enabled = ( \IPS\Settings::i()->fb_pixel_enabled and \IPS\Settings::i()->fb_pixel_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$validation = function( $val ) {
|
||||
if ( $val and !\IPS\Request::i()->fb_pixel_id )
|
||||
{
|
||||
throw new \DomainException('fb_pixel_id_req');
|
||||
}
|
||||
};
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'fb_pixel_id', \IPS\Settings::i()->fb_pixel_id ? \IPS\Settings::i()->fb_pixel_id : '', FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'fb_pixel_enabled', \IPS\Settings::i()->fb_pixel_enabled, FALSE, array(), $validation ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'fb_pixel_delay', \IPS\Settings::i()->fb_pixel_delay, FALSE, array(), $validation, NULL, \IPS\Member::loggedIn()->language()->addToStack('fb_pixel_delay_seconds') ) );
|
||||
|
||||
if ( $form->values() )
|
||||
{
|
||||
$form->saveAsSettings();
|
||||
\IPS\Session::i()->log( 'acplog__enhancements_edited', array( 'enhancements__core_FacebookPixel' => TRUE ) );
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
'help' => array(
|
||||
'title' => 'learn_more',
|
||||
'icon' => 'question-circle',
|
||||
'link' => \IPS\Http\Url::ips( 'docs/facebookpixel' ),
|
||||
'target' => '_blank'
|
||||
),
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'enhancements__core_FacebookPixel', $form );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable
|
||||
*
|
||||
* @param $enabled bool Enable/Disable
|
||||
* @return void
|
||||
*/
|
||||
public function toggle( $enabled )
|
||||
{
|
||||
if ( $enabled )
|
||||
{
|
||||
if ( \IPS\Settings::i()->fb_pixel_id )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 1 ), array( 'conf_key=?', 'fb_pixel_enabled' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \DomainException;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'fb_pixel_enabled' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,6 @@ class _GeoIP
|
||||
*/
|
||||
public function toggle( $enabled )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'ipsgeoip' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'ipsgeoip' => 0 ) );
|
||||
}
|
||||
}
|
||||
@@ -112,9 +112,15 @@ class _GoogleMaps
|
||||
} ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'googlemaps', \IPS\Settings::i()->googlemaps, FALSE, array(), $validation ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'googleplacesautocomplete', \IPS\Settings::i()->googleplacesautocomplete, FALSE, array(), $validation ) );
|
||||
if ( $form->values() )
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$form->saveAsSettings();
|
||||
if( $values['googlemaps'] > 0 )
|
||||
{
|
||||
$values['mapbox'] = 0;
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplog__enhancements_edited', array( 'enhancements__core_GoogleMaps' => TRUE ) );
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
@@ -139,22 +145,21 @@ class _GoogleMaps
|
||||
*/
|
||||
public function toggle( $enabled )
|
||||
{
|
||||
if ( $enabled )
|
||||
/* If we're disabling, just disable */
|
||||
if( !$enabled )
|
||||
{
|
||||
if ( \IPS\Settings::i()->google_maps_api_key )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 1 ), array( '( conf_key=? OR conf_key=? )', 'googlemaps', 'googleplacesautocomplete' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \DomainException;
|
||||
}
|
||||
\IPS\Settings::i()->changeValues( array( 'googlemaps' => 0, 'googleplacesautocomplete' => 0 ) );
|
||||
}
|
||||
|
||||
/* Otherwise if we already have an API key, just toggle on */
|
||||
if( $enabled && \IPS\Settings::i()->google_maps_api_key )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'googlemaps' => 1, 'googleplacesautocomplete' => 1, 'mapbox' => 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( '( conf_key=? OR conf_key=? )', 'googlemaps', 'googleplacesautocomplete' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
/* Otherwise we need to let them enter an API key before we can enable. Throwing an exception causes you to be redirected to the settings page. */
|
||||
throw new \DomainException;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Community Enhancement: Mapbox
|
||||
* @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 1 Nov 2017
|
||||
*/
|
||||
|
||||
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 Enhancement: Mapbox
|
||||
*/
|
||||
class _Mapbox
|
||||
{
|
||||
/**
|
||||
* @brief IPS-provided enhancement?
|
||||
*/
|
||||
public $ips = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Enhancement is enabled?
|
||||
*/
|
||||
public $enabled = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Enhancement has configuration options?
|
||||
*/
|
||||
public $hasOptions = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Icon data
|
||||
*/
|
||||
public $icon = "mapbox.png";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->enabled = ( \IPS\Settings::i()->mapbox_api_key and ( \IPS\Settings::i()->mapbox ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$validation = function( $val ) {
|
||||
if ( $val and !\IPS\Request::i()->mapbox_api_key )
|
||||
{
|
||||
throw new \DomainException('mapbox_api_key_req');
|
||||
}
|
||||
};
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'mapbox_api_key', \IPS\Settings::i()->mapbox_api_key, FALSE, array(), function( $val ) {
|
||||
if ( $val )
|
||||
{
|
||||
/* Check API */
|
||||
try
|
||||
{
|
||||
$location = '-73.961452,40.714224';
|
||||
|
||||
$response = \IPS\Http\Url::external( "https://api.mapbox.com/geocoding/v5/mapbox.places/{$location}.json" )->setQueryString( array(
|
||||
'access_token' => $val,
|
||||
) )->request()->get()->decodeJson();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
throw new \DomainException('mapbox_api_error');
|
||||
}
|
||||
|
||||
if ( isset( $response['message'] ) )
|
||||
{
|
||||
throw new \DomainException('mapbox_api_key_invalid');
|
||||
}
|
||||
|
||||
}
|
||||
} ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'mapbox', \IPS\Settings::i()->mapbox, FALSE, array(), $validation ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if( $values['mapbox'] > 0 )
|
||||
{
|
||||
$values['googlemaps'] = 0;
|
||||
$values['googleplacesautocomplete'] = 0;
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplog__enhancements_edited', array( 'enhancements__core_MapboxMaps' => TRUE ) );
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
'help' => array(
|
||||
'title' => 'learn_more',
|
||||
'icon' => 'question-circle',
|
||||
'link' => \IPS\Http\Url::ips( 'docs/mapboxmaps' ),
|
||||
'target' => '_blank'
|
||||
),
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'enhancements__core_MapboxMaps', $form );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable
|
||||
*
|
||||
* @param $enabled bool Enable/Disable
|
||||
* @return void
|
||||
*/
|
||||
public function toggle( $enabled )
|
||||
{
|
||||
/* If we're disabling, just disable */
|
||||
if( !$enabled )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'mapbox' => 0 ) );
|
||||
}
|
||||
|
||||
/* Otherwise if we already have an API key, just toggle on */
|
||||
if( $enabled && \IPS\Settings::i()->mapbox_api_key )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'mapbox' => 1, 'googlemaps' => 0, 'googleplacesautocomplete' => 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise we need to let them enter an API key before we can enable. Throwing an exception causes you to be redirected to the settings page. */
|
||||
throw new \DomainException;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,18 +76,23 @@ class _SendGrid
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sendgrid_click_tracking', \IPS\Settings::i()->sendgrid_click_tracking, FALSE, array(), NULL, NULL, NULL, 'sendgrid_click_tracking' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'sendgrid_ip_pool', \IPS\Settings::i()->sendgrid_ip_pool ?: NULL, FALSE, array( 'nullLang' => 'sendgrid_ip_pool_none' ), NULL, NULL, NULL, 'sendgrid_ip_pool' ) );
|
||||
|
||||
if ( $form->values() )
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->testSettings( $form->values() );
|
||||
$this->testSettings( $values );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '2C339/1', 500 );
|
||||
}
|
||||
|
||||
$form->saveAsSettings();
|
||||
if( $values['sendgrid_use_for'] > 0 )
|
||||
{
|
||||
$values['sparkpost_use_for'] = 0;
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplog__enhancements_edited', array( 'enhancements__core_SendGrid' => TRUE ) );
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
@@ -116,15 +121,13 @@ class _SendGrid
|
||||
/* If we're disabling, just disable */
|
||||
if( !$enabled )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'sendgrid_use_for' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'sendgrid_use_for' => 0 ) );
|
||||
}
|
||||
|
||||
/* Otherwise if we already have an API key, just toggle bulk mail on */
|
||||
if( $enabled && \IPS\Settings::i()->sendgrid_api_key )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 1 ), array( 'conf_key=?', 'sendgrid_use_for' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'sendgrid_use_for' => 1, 'sparkpost_use_for' => 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -147,8 +150,7 @@ class _SendGrid
|
||||
{
|
||||
if( \IPS\Settings::i()->mail_method == 'sendgrid' )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 'mail' ), array( 'conf_key=?', 'mail_method' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'mail_method' => 'mail' ) );
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -50,7 +50,7 @@ class _SpamMonitoring
|
||||
public function __construct()
|
||||
{
|
||||
$licenseData = \IPS\IPS::licenseKey();
|
||||
if( !$licenseData or !isset( $licenseData['products']['spam'] ) or !$licenseData['products']['spam'] or strtotime( $licenseData['expires'] ) < time() )
|
||||
if( !$licenseData or !isset( $licenseData['products']['spam'] ) or !$licenseData['products']['spam'] or ( !$licenseData['cloud'] AND strtotime( $licenseData['expires'] ) < time() ) )
|
||||
{
|
||||
$this->enabled = false;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ class _SpamMonitoring
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
{
|
||||
//Do not show error message. We will see error message in Settings
|
||||
// \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' ) );
|
||||
@@ -97,8 +97,7 @@ class _SpamMonitoring
|
||||
$this->testSettings();
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $enabled ), array( 'conf_key=?', 'spam_service_enabled' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'spam_service_enabled' => $enabled ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +114,7 @@ class _SpamMonitoring
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack('spam_service_nokey', FALSE, array( 'sprintf' => array( \IPS\Http\Url::internal( 'app=core&module=settings&controller=licensekey', null ) ) ) ) );
|
||||
}
|
||||
if ( strtotime( $licenseData['expires'] ) < time() )
|
||||
if ( !$licenseData['cloud'] AND strtotime( $licenseData['expires'] ) < time() )
|
||||
{
|
||||
throw new \DomainException('licensekey_expired');
|
||||
}
|
||||
|
||||
@@ -1,198 +1,3 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Community Enhancements: Sparkpost integration
|
||||
* @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 29 March 2016
|
||||
*/
|
||||
|
||||
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: Sparkpost integration
|
||||
*/
|
||||
class _Sparkpost
|
||||
{
|
||||
/**
|
||||
* @brief IPS-provided enhancement?
|
||||
*/
|
||||
public $ips = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Enhancement is enabled?
|
||||
*/
|
||||
public $enabled = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Enhancement has configuration options?
|
||||
*/
|
||||
public $hasOptions = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Icon data
|
||||
*/
|
||||
public $icon = "sparkpost.png";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->enabled = ( \IPS\Settings::i()->sparkpost_api_key && \IPS\Settings::i()->sparkpost_use_for );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'sparkpost_use_for', \IPS\Settings::i()->sparkpost_use_for, TRUE, array(
|
||||
'options' => array(
|
||||
'0' => 'sparkpost_donot_use',
|
||||
'1' => 'sparkpost_bulkmail_use',
|
||||
'2' => 'sparkpost_all_use'
|
||||
),
|
||||
'toggles' => array(
|
||||
'0' => array(),
|
||||
'1' => array( 'sparkpost_api_key', 'sparkpost_click_tracking', 'sparkpost_ip_pool' ),
|
||||
'2' => array( 'sparkpost_api_key', 'sparkpost_click_tracking', 'sparkpost_ip_pool' ),
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'sparkpost_api_key', \IPS\Settings::i()->sparkpost_api_key, FALSE, array(), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('sparkpost_api_key_suffix'), 'sparkpost_api_key' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sparkpost_click_tracking', \IPS\Settings::i()->sparkpost_click_tracking, FALSE, array(), NULL, NULL, NULL, 'sparkpost_click_tracking' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'sparkpost_ip_pool', \IPS\Settings::i()->sparkpost_ip_pool ?: NULL, FALSE, array( 'nullLang' => 'sparkpost_ip_pool_none' ), NULL, NULL, NULL, 'sparkpost_ip_pool' ) );
|
||||
|
||||
if ( $form->values() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->testSettings( $form->values() );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '2S123/1', 500 );
|
||||
}
|
||||
|
||||
$form->saveAsSettings();
|
||||
\IPS\Session::i()->log( 'acplog__enhancements_edited', array( 'enhancements__core_Sparkpost' => TRUE ) );
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
'help' => array(
|
||||
'title' => 'learn_more',
|
||||
'icon' => 'question-circle',
|
||||
'link' => \IPS\Http\Url::ips( 'docs/sparkpost' ),
|
||||
'target' => '_blank'
|
||||
),
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable
|
||||
*
|
||||
* @param $enabled bool Enable/Disable
|
||||
* @return void
|
||||
* @throws \DomainException
|
||||
*/
|
||||
public function toggle( $enabled )
|
||||
{
|
||||
/* If we're disabling, just disable */
|
||||
if( !$enabled )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'sparkpost_use_for' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
|
||||
/* Otherwise if we already have an API key, just toggle bulk mail on */
|
||||
if( $enabled && \IPS\Settings::i()->sparkpost_api_key )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 1 ), array( 'conf_key=?', 'sparkpost_use_for' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise we need to let them enter an API key before we can enable. Throwing an exception causes you to be redirected to the settings page. */
|
||||
throw new \DomainException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Settings
|
||||
*
|
||||
* @param array $values Form values
|
||||
* @return void
|
||||
* @throws \LogicException
|
||||
*/
|
||||
protected function testSettings( $values )
|
||||
{
|
||||
/* If we've disabled, just shut off */
|
||||
if( (int) $values['sparkpost_use_for'] === 0 )
|
||||
{
|
||||
if( \IPS\Settings::i()->mail_method == 'sparkpost' )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 'mail' ), array( 'conf_key=?', 'mail_method' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we enable Sparkpost but do not supply an API key, this is a problem */
|
||||
if( !$values['sparkpost_api_key'] )
|
||||
{
|
||||
throw new \InvalidArgumentException( "sparkpost_enable_need_details" );
|
||||
}
|
||||
|
||||
/* Test Sparkpost settings */
|
||||
try
|
||||
{
|
||||
$domain = mb_substr( \IPS\Settings::i()->email_out, mb_strpos( \IPS\Settings::i()->email_out, '@' ) + 1 );
|
||||
$sparkpost = new \IPS\Email\Outgoing\SparkPost( $values['sparkpost_api_key'] );
|
||||
$sendingDomains = $sparkpost->sendingDomains();
|
||||
if ( isset( $sendingDomains['errors'] ) )
|
||||
{
|
||||
throw new \DomainException('sparkpost_bad_credentials');
|
||||
}
|
||||
$isOkay = FALSE;
|
||||
foreach ( $sendingDomains['results'] as $sendingDomain )
|
||||
{
|
||||
if ( $sendingDomain['domain'] == $domain )
|
||||
{
|
||||
if ( $sendingDomain['status']['ownership_verified'] )
|
||||
{
|
||||
$isOkay = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \DomainException('sparkpost_domain_not_verified');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !$isOkay )
|
||||
{
|
||||
throw new \DomainException('sparkpost_domain_not_registered');
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
throw new \DomainException( 'sparkpost_bad_credentials' );
|
||||
}
|
||||
}
|
||||
}
|
||||
// this file intentionally left blank
|
||||
@@ -201,15 +201,13 @@ class _Viglink
|
||||
/* If we're disabling, just disable */
|
||||
if( !$enabled )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'viglink_enabled' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'viglink_enabled' => 0 ) );
|
||||
}
|
||||
|
||||
/* Otherwise if we already have an API key, just toggle on */
|
||||
if( $enabled && \IPS\Settings::i()->viglink_api_key )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 1 ), array( 'conf_key=?', 'viglink_enabled' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'viglink_enabled' => 1 ) );
|
||||
}
|
||||
/* Otherwise we need to let them enter an API key before we can enable. Throwing an exception causes you to be redirected to the settings page. */
|
||||
else
|
||||
|
||||
@@ -76,7 +76,7 @@ class _Email
|
||||
$sender = explode( ',', \IPS\Settings::i()->contact_emails );
|
||||
}
|
||||
$mail = \IPS\Email::buildFromTemplate( 'core', 'contact_form', array( \IPS\Member::loggedIn(), $fromName, $fromEmail, $content ), \IPS\Email::TYPE_TRANSACTIONAL );
|
||||
$mail->send( $sender , array(), array(), NULL, $fromName, array( 'Reply-To' => \IPS\Email::encodeHeader( $fromName, ( \IPS\Member::loggedIn()->member_id ? \IPS\Member::loggedIn()->email : $values['email_address'] ) ) ) );
|
||||
$mail->send( $sender , array(), array(), NULL, $fromName, array( 'Reply-To' => \IPS\Email::encodeHeader( $fromName, ( \IPS\Member::loggedIn()->member_id ? \IPS\Member::loggedIn()->email : $values['email_address'] ) ) ), FALSE );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -40,13 +40,11 @@ class _AdminNotes
|
||||
public function getBlock()
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'form', 'save', \IPS\Http\Url::internal( "app=core&module=overview&controller=dashboard&do=getBlock&appKey=core&blockKey=core_AdminNotes" )->csrf() );
|
||||
$form->add( new \IPS\Helpers\Form\TextArea( 'admin_notes', ( isset( \IPS\Settings::i()->acp_notes ) ) ? htmlspecialchars( \IPS\Settings::i()->acp_notes, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) : '' ) );
|
||||
$form->add( new \IPS\Helpers\Form\TextArea( 'admin_notes', ( isset( \IPS\Settings::i()->acp_notes ) ) ? htmlspecialchars( \IPS\Settings::i()->acp_notes, ENT_DISALLOWED, 'UTF-8', FALSE ) : '' ) );
|
||||
|
||||
if( $values = $form->values() )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $values['admin_notes'] ), array( 'conf_key=?', 'acp_notes' ) );
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => time() ), array( 'conf_key=?', 'acp_notes_updated' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'acp_notes' => $values['admin_notes'], 'acp_notes_updated' => time() ) );
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
|
||||
@@ -40,8 +40,8 @@ class _BackgroundQueue
|
||||
public function getBlock()
|
||||
{
|
||||
$rows = array();
|
||||
|
||||
$select = \IPS\Db::i()->select( '*', 'core_queue', NULL, 'priority ASC, date ASC' );
|
||||
|
||||
$select = \IPS\Db::i()->select( '*', 'core_queue', array( 'app_enabled=?', 1 ), 'priority ASC, date ASC' )->join( 'core_applications', "app=app_directory" );
|
||||
if ( count( $select ) )
|
||||
{
|
||||
foreach ( $select as $queueData )
|
||||
|
||||
@@ -1,94 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Dashboard extension: Show a notice if there are failed IPS Connect communications
|
||||
* @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 03 Dec 2013
|
||||
*/
|
||||
|
||||
// Removed
|
||||
|
||||
namespace IPS\core\extensions\core\Dashboard;
|
||||
|
||||
/* 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 Dashboard extension: Show a notice if there are failed IPS Connect communications
|
||||
*/
|
||||
class _IpsconnectMaster
|
||||
{
|
||||
/**
|
||||
* Can the current user view this dashboard item?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canView()
|
||||
{
|
||||
$handlers = \IPS\Login::handlers( TRUE );
|
||||
return (bool) ( array_key_exists( 'Ipsconnect', $handlers ) and $handlers['Ipsconnect']->enabled );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block HTML show on the dashboard
|
||||
*
|
||||
* @return string
|
||||
* @note We may want to consider doing something when there are failed queued requests but the slave record no longer exists. For now I don't want to automatically
|
||||
clear them because it may be indicative of a bug elsewhere, but down the road we may want to simply delete the requests from the queue table and not show the failure.
|
||||
*/
|
||||
public function getBlock()
|
||||
{
|
||||
/* Are we deleting the slave? */
|
||||
if( \IPS\Request::i()->deleteSlave )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_ipsconnect_queue', array( 'slave_id=?', intval( \IPS\Request::i()->deleteSlave ) ) );
|
||||
\IPS\Db::i()->delete( 'core_ipsconnect_slaves', array( 'slave_id=?', intval( \IPS\Request::i()->deleteSlave ) ) );
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => \IPS\Db::i()->select( 'COUNT(*)', 'core_ipsconnect_slaves', array( 'slave_enabled=?', 1 ) )->first() ), array( 'conf_key=?', 'connect_slaves' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('connect_slave_deleted');
|
||||
\IPS\Session::i()->log( 'acplog__slave_deleted' );
|
||||
}
|
||||
|
||||
/* Do we have any fails to show? */
|
||||
$fails = \IPS\Db::i()->select( 'DISTINCT(slave_id)', 'core_ipsconnect_queue' );
|
||||
|
||||
if( count($fails) )
|
||||
{
|
||||
$failures = array();
|
||||
|
||||
foreach( $fails as $slave )
|
||||
{
|
||||
try
|
||||
{
|
||||
$slave = \IPS\Db::i()->select( '*', 'core_ipsconnect_slaves', array( 'slave_id=? AND slave_enabled=?', $slave, 1 ) )->first();
|
||||
$fails = count( \IPS\Db::i()->select( 'id', 'core_ipsconnect_queue', array( 'slave_id=?', $slave['slave_id'] ) ) );
|
||||
|
||||
$failures[] = array(
|
||||
'slave' => $slave,
|
||||
'count' => $fails
|
||||
);
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
/* This means that the slave record doesn't actually exist or is disabled */
|
||||
}
|
||||
}
|
||||
|
||||
if( count( $failures ) )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'dashboard' )->connectFailures( $failures, count($failures) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'dashboard' )->noConnectFailures();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ class _LatestNews
|
||||
*/
|
||||
public function getBlock()
|
||||
{
|
||||
return NULL;
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,6 +50,9 @@ class _LatestNews
|
||||
*/
|
||||
protected function refreshNews()
|
||||
{
|
||||
return NULL;
|
||||
\IPS\Data\Store::i()->ips_news = json_encode( array(
|
||||
'content' => \IPS\Http\Url::ips( 'news' )->request()->get()->decodeJson(),
|
||||
'time' => time()
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ class _OnlineUsers
|
||||
/* Add Rows */
|
||||
$online = array();
|
||||
$seen = array();
|
||||
foreach( \IPS\Db::i()->select( "*", 'core_sessions', array( 'running_time>?', \IPS\DateTime::create()->sub( new \DateInterval('PT30M') )->getTimestamp() ), 'running_time DESC' ) as $row )
|
||||
foreach( \IPS\Session\Store::i()->getOnlineUsers( \IPS\Session\Store::ONLINE_MEMBERS | \IPS\Session\Store::ONLINE_GUESTS, 'desc' ) as $row )
|
||||
{
|
||||
$key = ( $row['member_id'] ? $row['member_id'] : $row['id'] );
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class _Registrations
|
||||
*/
|
||||
public function canView()
|
||||
{
|
||||
return TRUE;
|
||||
return \IPS\Member::loggedIn()->hasAcpRestriction( 'core' , 'members', 'registrations_manage' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,80 +39,31 @@ class _Registrations
|
||||
*/
|
||||
public function getBlock()
|
||||
{
|
||||
/* Init Chart */
|
||||
$chart = new \IPS\Helpers\Chart;
|
||||
|
||||
/* Specify headers */
|
||||
$chart->addHeader( \IPS\Member::loggedIn()->language()->addToStack('date'), 'string' ); // Since we're displaying a column chart, it makes more sense to use a string so they plotted as discreet columns rather than in the middle of dates
|
||||
$chart->addHeader( \IPS\Member::loggedIn()->language()->addToStack('members'), 'number' );
|
||||
|
||||
$data = array();
|
||||
|
||||
/* We use midnight as a basis so we can include todays registrations */
|
||||
$date = new \IPS\DateTime( 'tomorrow', new \DateTimeZone( \IPS\Member::loggedIn()->timezone ) );
|
||||
|
||||
/* We need to clone $date here for use in the query later */
|
||||
$today = clone $date;
|
||||
|
||||
/* And we do this over a period of seven days - the query will also do this on the cloned object later. */
|
||||
$date->sub( new \DateInterval( 'P7D' ) );
|
||||
|
||||
while ( $date->getTimestamp() < time() )
|
||||
{
|
||||
$data[ $date->format( 'Y-n-j' ) ] = 0;
|
||||
$date->add( new \DateInterval( 'P1D' ) );
|
||||
}
|
||||
/* We can use the registration stats controller for this */
|
||||
$chart = new \IPS\Helpers\Chart\Database(
|
||||
\IPS\Http\Url::internal( 'app=core&module=stats&controller=registrationstats' ),
|
||||
'core_members',
|
||||
'joined',
|
||||
'',
|
||||
array(
|
||||
'isStacked' => FALSE,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4
|
||||
),
|
||||
'ColumnChart',
|
||||
'weekly',
|
||||
array( 'start' => \IPS\DateTime::create()->sub( new \DateInterval( 'P30D' ) ), 'end' => \IPS\DateTime::ts( time() ) )
|
||||
);
|
||||
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('stats_new_registrations'), 'number', 'COUNT(*)', FALSE );
|
||||
$chart->availableTypes = array( 'AreaChart', 'ColumnChart', 'BarChart' );
|
||||
|
||||
/* 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( 'joined>? AND name<>? AND email<>?', $today->sub( new \DateInterval( 'P7D' ) )->getTimestamp(), '', '' );
|
||||
|
||||
/* Add Rows */
|
||||
foreach( \IPS\Db::i()->select( 'joined', 'core_members', $where, 'joined DESC' ) AS $joined )
|
||||
{
|
||||
$time = \IPS\DateTime::ts( $joined )->format( 'Y-n-j' );
|
||||
|
||||
/* Occasionally, timezone differences mean that we fall just over the beginning or end, which results in an undefined index. We can
|
||||
ignore any registrations for dates that haven't been initialized. */
|
||||
if( isset( $data[ $time ] ) )
|
||||
{
|
||||
$data[ $time ] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
uksort( $data, function( $a, $b )
|
||||
{
|
||||
return strnatcmp( $a, $b );
|
||||
} );
|
||||
|
||||
/* Add to graph */
|
||||
foreach ( $data as $time => $d )
|
||||
{
|
||||
$datetime = new \IPS\DateTime;
|
||||
$exploded = explode( '-', $time );
|
||||
$datetime->setDate( $exploded[0], $exploded[1], $exploded[2] );
|
||||
|
||||
$chart->addRow( array( $datetime->format( 'j M Y' ), $d ) );
|
||||
}
|
||||
|
||||
/* Work out the ticks */
|
||||
$ticks = array();
|
||||
$increment = ceil( max($data) / 5 );
|
||||
|
||||
for ($i = 1; $i <= 5; $i++)
|
||||
{
|
||||
$v = $increment * $i;
|
||||
$ticks[] = array( 'v' => $v, 'f' => (string) $v );
|
||||
}
|
||||
$chart->where[] = array( '( name<>? AND email<>? )', '', '' );
|
||||
|
||||
/* Output */
|
||||
return \IPS\Theme::i()->getTemplate( 'dashboard' )->registrations( $chart->render( 'ColumnChart', array(
|
||||
'legend' => array( 'position' => 'none' ),
|
||||
'areaOpacity' => 0.4,
|
||||
'lineWidth' => 1,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'vAxis' => array( 'ticks' => $ticks ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
) ) );
|
||||
return \IPS\Theme::i()->getTemplate( 'dashboard' )->registrations( $chart );
|
||||
}
|
||||
}
|
||||
@@ -238,8 +238,7 @@ class _Admin
|
||||
|
||||
if( $newMessage !== FALSE )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $newMessage ), "conf_key='site_offline_message'" );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
\IPS\Settings::i()->changeValues( array( 'site_offline_message' => $newMessage ) );
|
||||
}
|
||||
|
||||
/* Application disabled messages */
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Editor Extension: Review Responses
|
||||
* @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 Jan 2018
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\EditorLocations;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Review Responses
|
||||
*/
|
||||
class _ReviewResponses
|
||||
{
|
||||
/**
|
||||
* Can we use HTML in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canUseHtml( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form\Editor $field The editor field
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canAttach( $member, $field )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array $attachment The attachment data
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
|
||||
{
|
||||
try
|
||||
{
|
||||
$class = $id3 . '\\Review';
|
||||
$item = $class::load( $id1 );
|
||||
return $item->canView( $member );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attachment lookup
|
||||
*
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function attachmentLookup( $id1, $id2, $id3 )
|
||||
{
|
||||
$class = $id3 . '\\Review';
|
||||
|
||||
return $class::load( $id2 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Editor Extension: 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 13 Feb 2018
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\EditorLocations;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Widget, Used for all the core widgets which need an editor
|
||||
*/
|
||||
class _Widget
|
||||
{
|
||||
/**
|
||||
* Array containing all widgets utilizing this Extension
|
||||
*/
|
||||
protected static $widgets = array(
|
||||
'guestSignUp',
|
||||
'newsletter',
|
||||
);
|
||||
|
||||
/**
|
||||
* Can we use HTML in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canUseHtml( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form\Editor $field The editor field
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canAttach( $member, $field )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array $attachment The attachment data
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attachment lookup
|
||||
*
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function attachmentLookup( $id1, $id2, $id3 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild attachment images in non-content item areas
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildAttachmentImages( $offset, $max )
|
||||
{
|
||||
return $this->performRebuild( $offset, $max, array( 'IPS\Text\Parser', 'rebuildAttachmentUrls' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild content post-upgrade
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildContent( $offset, $max )
|
||||
{
|
||||
return $this->performRebuild( $offset, $max, array( 'IPS\Text\LegacyParser', 'parseStatic' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Store image proxy status ( true = enabled )
|
||||
*/
|
||||
protected $_imageProxyStatus = null;
|
||||
|
||||
/**
|
||||
* Rebuild content to add or remove image proxy
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @param bool $status Enable/Disable Image Proxy
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildImageProxy( $offset, $max, $status=TRUE )
|
||||
{
|
||||
$this->_imageProxyStatus = $status;
|
||||
|
||||
return $this->performRebuild( $offset, $max, 'parseImageProxy' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform rebuild - abstracted as the call for rebuildContent() and rebuildAttachmentImages() is nearly identical
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @param callable $callback Method to call to rebuild content
|
||||
* @return int Number completed
|
||||
*/
|
||||
protected function performRebuild( $offset, $max, $callback )
|
||||
{
|
||||
$did = 0;
|
||||
|
||||
$areas = array( 'core_widget_areas' );
|
||||
if ( \IPS\Application::appIsEnabled('cms') )
|
||||
{
|
||||
$areas[] = 'cms_page_widget_areas';
|
||||
}
|
||||
|
||||
foreach ( $areas as $table )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', $table ) as $area )
|
||||
{
|
||||
$did++;
|
||||
|
||||
$widgetsColumn = $table == 'core_widget_areas' ? 'widgets' : 'area_widgets';
|
||||
$whereClause = $table == 'core_widget_areas' ? array( 'id=? AND area=?', $area['id'], $area['area'] ) : array( 'area_page_id=? AND area_area=?', $area['area_page_id'], $area['area_area'] );
|
||||
|
||||
$widgets = json_decode( $area[ $widgetsColumn ], TRUE );
|
||||
$update = FALSE;
|
||||
|
||||
foreach ( $widgets as $k => $widget )
|
||||
{
|
||||
if ( in_array( $widget['key'], static::$widgets ) )
|
||||
{
|
||||
$appOrPlugin = isset( $widget['plugin'] ) ? \IPS\Plugin::load( $widget['plugin'] ) : \IPS\Application::load( $widget['app'] );
|
||||
|
||||
$widgetObject = \IPS\Widget::load( $appOrPlugin, $widget['key'], $widget['unique'] );
|
||||
$key = $widgetObject::$editorKey;
|
||||
|
||||
if ( isset( $widget['configuration'][$key ] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( $callback == 'parseImageProxy' )
|
||||
{
|
||||
$rebuilt = \IPS\Text\Parser::parseImageProxy( $widget['configuration'][$key ], $this->_imageProxyStatus );
|
||||
}
|
||||
else
|
||||
{
|
||||
$rebuilt = call_user_func( $callback, $widget['configuration'][$key ] );
|
||||
}
|
||||
}
|
||||
catch( \InvalidArgumentException $e )
|
||||
{
|
||||
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
|
||||
{
|
||||
$rebuilt = preg_replace( "#\[/?([^\]]+?)\]#", '', $widget['configuration'][$key ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $rebuilt )
|
||||
{
|
||||
$widgets[ $k ]['configuration'][$key] =$rebuilt;
|
||||
$update = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( $update )
|
||||
{
|
||||
\IPS\Db::i()->update( $table, array( $widgetsColumn => json_encode( $widgets ) ), $whereClause );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $did;
|
||||
}
|
||||
|
||||
/**
|
||||
* Total content count to be used in progress indicator
|
||||
*
|
||||
* @return int Total Count
|
||||
*/
|
||||
public function contentCount()
|
||||
{
|
||||
$count = 0;
|
||||
|
||||
$areas = array( 'core_widget_areas' );
|
||||
if ( \IPS\Application::appIsEnabled('cms') )
|
||||
{
|
||||
$areas[] = 'cms_page_widget_areas';
|
||||
}
|
||||
|
||||
foreach ( $areas as $table )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', $table ) as $area )
|
||||
{
|
||||
$widgetsColumn = $table == 'core_widget_areas' ? 'widgets' : 'area_widgets';
|
||||
|
||||
$widgets = json_decode( $area[ $widgetsColumn ], TRUE );
|
||||
|
||||
foreach ( $widgets as $k => $widget )
|
||||
{
|
||||
if ( in_array( $widget['key'], static::$widgets ) )
|
||||
{
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief File Storage Extension: ClubField
|
||||
* @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 11 Aug 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\FileStorage;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: ClubField
|
||||
*/
|
||||
class _ClubField
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$count = 0;
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs_fields', array( "f_type=?", 'Upload' ) ) AS $row )
|
||||
{
|
||||
$count += \IPS\Db::i()->select( 'COUNT(*)', 'core_clubs_fieldvalues', array( "field_{$row['f_id']}<>? AND field_{$row['f_id']} IS NOT NULL", '' ) )->first();
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move stored files
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @param int $storageConfiguration New storage configuration ID
|
||||
* @param int|NULL $oldConfiguration Old storage configuration ID
|
||||
* @throws \UnderflowException When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void|int An offset integer to use on the next cycle, or nothing
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs_fields', array( "f_type=?", 'Upload' ) ) AS $row )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs_fieldvalues', array( "field_{$row['f_id']}<>? AND field_{$row['f_id']} IS NOT NULL", '' ) ) AS $field )
|
||||
{
|
||||
try
|
||||
{
|
||||
$moved = \IPS\File::get( $oldConfiguration ?: 'core_ClubField', $field[ "field_{$row['f_id']}" ] )->move( $storageConfiguration );
|
||||
\IPS\Db::i()->update( 'core_clubs_fieldvalues', array( "field_{$row['f_id']}" => (string) $moved ), array( "club_id=?", $field['club_id'] ) );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
// Any issues are logged
|
||||
}
|
||||
catch( \Throwable $e )
|
||||
{
|
||||
// Any issues are logged
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all URLs
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @return void
|
||||
*/
|
||||
public function fixUrls( $offset )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs_fields', array( "f_type=?", 'Upload' ) ) AS $row )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs_fieldvalues', array( "field_{$row['f_id']}<>? AND field_{$row['f_id']} IS NOT NULL" ) ) AS $field )
|
||||
{
|
||||
$new = \IPS\File::repairUrl( $field[ "field_{$row['f_id']}" ] );
|
||||
|
||||
\IPS\Db::i()->update( 'core_clubs_fieldvalues', array( "field_{$row['f_id']}" => $new ), array( "club_id=?", $field['club_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs_fields', array( "f_type=?", 'Upload' ) ) AS $row )
|
||||
{
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_clubs_fieldvalues', array( "field_{$row['f_id']}=?", (string) $file ) )->first() )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs_fields', array( "f_type=?", 'Upload' ) ) AS $row )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs_fieldvalues', array( "field_{$row['f_id']}<>? AND field_{$row['f_id']} IS NOT NULL" ) ) AS $field )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'core_ClubField', $field[ "field_{$row['f_id']}" ] )->delete();
|
||||
}
|
||||
catch( \OutOfRangeException $e ) {}
|
||||
|
||||
\IPS\Db::i()->update( 'core_clubs_fieldvalues', array( "field_{$row['f_id']}" => NULL ), array( "club_id=?", $field['club_id'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,7 +135,7 @@ class _Clubs
|
||||
{
|
||||
if ( $new = \IPS\File::repairUrl( $club[ $photoKey ] ) )
|
||||
{
|
||||
$fixed[ $location ] = $new;
|
||||
$fixed[ $photoKey ] = $new;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,8 @@ class _Emoticons
|
||||
\IPS\Db::i()->update( 'core_emoticons', array( 'image' => (string) $file, 'image_2x' => (string) $image_2x ), array( 'id=?', $emoticon['id'] ) );
|
||||
}
|
||||
|
||||
unset( \IPS\Data\Store::i()->emoticons );
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => time() ), array( 'conf_key=?', 'emoji_cache' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
@@ -93,7 +94,8 @@ class _Emoticons
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_emoticons', $fixed, array( 'id=?', $emoticon['id'] ) );
|
||||
|
||||
unset( \IPS\Data\Store::i()->emoticons );
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => time() ), array( 'conf_key=?', 'emoji_cache' ) );
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
|
||||
@@ -45,6 +45,12 @@ class _Imageproxycache
|
||||
{
|
||||
$cache = \IPS\Db::i()->select( '*', 'core_image_proxy', array(), 'md5_url', array( $offset, 1 ) )->first();
|
||||
|
||||
/* Don't move a file if it doesn't have a filename */
|
||||
if( $cache['location'] === NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'core_Imageproxycache', $cache['location'] )->move( $storageConfiguration );
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief File Storage Extension: Login Methods
|
||||
* @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 May 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\FileStorage;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Login Methods
|
||||
*/
|
||||
class _Login
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$count = 0;
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_login_methods' ) as $method )
|
||||
{
|
||||
$settings = json_decode( $method['login_settings'], TRUE );
|
||||
if ( isset( $settings['button_icon'] ) and $settings['button_icon'] )
|
||||
{
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move stored files
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @param int $storageConfiguration New storage configuration ID
|
||||
* @param int|NULL $oldConfiguration Old storage configuration ID
|
||||
* @throws \UnderflowException When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void|int An offset integer to use on the next cycle, or nothing
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_login_methods' ) as $method )
|
||||
{
|
||||
$settings = json_decode( $method['login_settings'], TRUE );
|
||||
if ( isset( $settings['button_icon'] ) and $settings['button_icon'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$settings['button_icon'] = (string) \IPS\File::get( $oldConfiguration ?: 'core_Login', $settings['button_icon'] )->move( $storageConfiguration );
|
||||
\IPS\Db::i()->update( 'core_login_methods', array( 'login_settings' => json_encode( $settings ) ), array( 'login_id=?', $method['login_id'] ) );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
}
|
||||
unset( \IPS\Data\Store::i()->loginMethods );
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_login_methods' ) as $method )
|
||||
{
|
||||
$settings = json_decode( $method['login_settings'], TRUE );
|
||||
if ( isset( $settings['button_icon'] ) and $settings['button_icon'] == (string) $file )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_login_methods' ) as $method )
|
||||
{
|
||||
$settings = json_decode( $method['login_settings'], TRUE );
|
||||
if ( isset( $settings['button_icon'] ) and $settings['button_icon'] == (string) $file )
|
||||
{
|
||||
\IPS\File::get( 'core_Login', $settings['button_icon'] )->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ class _Profile
|
||||
\IPS\File::get( 'core_Profile', $member['pp_cover_photo'] )->delete();
|
||||
}
|
||||
|
||||
if ( mb_substr( $member['pp_photo_type'], 0, 5 ) === 'sync-' or $member['pp_photo_type'] === 'custom' )
|
||||
if ( mb_substr( $member['pp_photo_type'], 0, 5 ) === 'sync-' or $member['pp_photo_type'] === 'custom' or $member['pp_photo_type'] === 'letter' )
|
||||
{
|
||||
if( $member['pp_main_photo'] )
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ class _Promote
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( $oldConfiguration ?: 'core_Profile', $location )->move( $storageConfiguration );
|
||||
\IPS\File::get( $oldConfiguration ?: 'core_Promote', $location )->move( $storageConfiguration );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
|
||||
@@ -36,6 +36,9 @@ class _Theme
|
||||
{
|
||||
/* Clear out CSS as custom URL may have changed */
|
||||
\IPS\Theme::deleteCompiledCss();
|
||||
|
||||
/* Trash this JS */
|
||||
\IPS\Output::clearJsFiles();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,7 +52,7 @@ class _Clubs extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
*/
|
||||
public function canAccessContent()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'online' ) );
|
||||
return \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'clubs' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,15 +31,19 @@ class _Content
|
||||
*/
|
||||
public function process( &$form, $group )
|
||||
{
|
||||
$contentClasses = array();
|
||||
/* Set up available content classes for customizations - add in conversations which do not have a content router extension */
|
||||
$contentClasses = array( 'IPS\core\Messenger\Conversation' => 'personal_conversation_pl' );
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter', $group ) as $class )
|
||||
{
|
||||
foreach ( $class->classes as $class )
|
||||
{
|
||||
$contentClasses[ $class ] = $class::$title . '_pl';
|
||||
if ( isset( $class::$databaseColumnMap['author'] ) )
|
||||
{
|
||||
$contentClasses[ $class ] = $class::$title . '_pl';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Uploading */
|
||||
if ( \IPS\Settings::i()->attach_allowed_types != 'none' )
|
||||
{
|
||||
@@ -47,9 +51,9 @@ class _Content
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'g_attach', ( $group->g_attach_max != 0 ), FALSE, array( 'togglesOn' => array( 'g_attach_max', 'g_attach_per_post', 'gbw_delete_attachments' ) ) ) );
|
||||
if( $group->g_id != \IPS\Settings::i()->guest_group )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'g_attach_max', $group->g_attach_max, 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_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_attach_per_post, 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( 'filesize_raw_k' ), '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' ) );
|
||||
@@ -134,6 +138,8 @@ class _Content
|
||||
|
||||
if( $group->g_id != \IPS\Settings::i()->guest_group )
|
||||
{
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'gbw_immune_auto_mod', $group->g_bitoptions['gbw_immune_auto_mod'] ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'g_lock_unlock_own', !$group->g_lock_unlock_own ? 0 : ( $group->g_lock_unlock_own == '1' ? '1' : explode( ',', $group->g_lock_unlock_own ) ), FALSE, array(
|
||||
'options' => array_filter( $contentClasses, function( $class ) {
|
||||
return in_array( 'IPS\Content\Lockable', class_implements( $class ) );
|
||||
@@ -144,7 +150,7 @@ class _Content
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'g_can_report', !$group->g_can_report ? 0 : ( $group->g_can_report == '1' ? '1' : explode( ',', $group->g_can_report ) ), FALSE, array(
|
||||
'options' => array_filter( $contentClasses, function( $class ) {
|
||||
return in_array( 'IPS\Content\ReportCenter', class_implements( $class ) );
|
||||
return \IPS\IPS::classUsesTrait( $class, 'IPS\Content\Reportable' );
|
||||
}, ARRAY_FILTER_USE_KEY ),
|
||||
'unlimited' => '1'
|
||||
) ) );
|
||||
@@ -218,7 +224,7 @@ class _Content
|
||||
$values['gbw_disable_tagging'] = \IPS\Settings::i()->tags_enabled ? !$values['gbw_disable_tagging'] : $group->g_bitoptions['gbw_disable_tagging'];
|
||||
$values['gbw_disable_prefixes'] = ( \IPS\Settings::i()->tags_enabled AND \IPS\Settings::i()->tags_can_prefix ) ? !$values['gbw_disable_prefixes'] : $group->g_bitoptions['gbw_disable_prefixes'];
|
||||
|
||||
$bwKeys = array( 'gbw_disable_tagging', 'gbw_disable_prefixes', 'gbw_delete_attachments', 'gbw_post_highlight', 'gbw_promote' );
|
||||
$bwKeys = array( 'gbw_disable_tagging', 'gbw_disable_prefixes', 'gbw_delete_attachments', 'gbw_post_highlight', 'gbw_promote', 'gbw_immune_auto_mod' );
|
||||
|
||||
foreach ( $bwKeys as $k )
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ class _GroupSettings
|
||||
{
|
||||
return array( 'prefix' => $element->value['prefix'], 'suffix' => $element->value['suffix'] );
|
||||
}
|
||||
elseif ( isset( $element->value['color'] ) )
|
||||
elseif ( isset( $element->value['color'] ) AND $element->value['color'] )
|
||||
{
|
||||
$color = mb_strtolower( $element->value['color'] );
|
||||
if ( mb_substr( $color, 0, 1 ) !== '#' )
|
||||
@@ -101,7 +101,7 @@ class _GroupSettings
|
||||
}
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'g_view_board', $group->g_id ? $group->g_view_board : TRUE, FALSE, array( 'togglesOn' => array_merge( $tabs, array( 'group_username', 'g_dohtml', 'g_use_search', "{$form->id}_header_group_privacy", 'g_hide_online_list', 'gbw_hide_group', "{$form->id}_header_group_signatures", 'g_use_signatures', "{$form->id}_header_group_staff", 'g_access_offline', 'g_search_flood', 'gbw_cannot_be_ignored' ) ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'g_view_board', $group->g_id ? $group->g_view_board : TRUE, FALSE, array( 'togglesOn' => array_merge( $tabs, array( 'group_username', 'g_dohtml', 'g_use_search', "gbw_cannot_be_ignored", "{$form->id}_header_group_signatures", 'g_use_signatures', "{$form->id}_header_group_staff", 'g_access_offline', 'g_search_flood', 'gbw_cannot_be_ignored' ) ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'g_access_offline', $group->g_access_offline, FALSE, array(), NULL, NULL, NULL, 'g_access_offline' ) );
|
||||
|
||||
/* Usernames */
|
||||
@@ -130,24 +130,35 @@ class _GroupSettings
|
||||
{
|
||||
$value[0] = 0;
|
||||
}
|
||||
|
||||
if ( isset( $value['unlimited'] ) AND $value['unlimited'] )
|
||||
else
|
||||
{
|
||||
$value[0] = -1;
|
||||
$value[3] = 0;
|
||||
}
|
||||
elseif ( !isset( $value[0] ) )
|
||||
{
|
||||
$value[0] = 0;
|
||||
}
|
||||
|
||||
if ( isset( $value['always'] ) AND $value['always'] )
|
||||
{
|
||||
$value[1] = 0;
|
||||
$value[2] = 0;
|
||||
if ( isset( $value['unlimited'] ) AND $value['unlimited'] )
|
||||
{
|
||||
$value[0] = -1;
|
||||
$value[3] = 0;
|
||||
}
|
||||
elseif ( !isset( $value[0] ) )
|
||||
{
|
||||
$value[0] = 0;
|
||||
}
|
||||
|
||||
if ( isset( $value['always'] ) AND $value['always'] )
|
||||
{
|
||||
$value[1] = 0;
|
||||
$value[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
'validate' => function( $element )
|
||||
{
|
||||
$value = $element->value;
|
||||
|
||||
if( ( isset( $value[1] ) AND $value[1] < 0 ) OR ( isset( $value[2] ) AND $value[2] < 0 ) OR ( isset( $value[3] ) AND $value[3] < 0 ) )
|
||||
{
|
||||
throw new \DomainException( 'only_positive_values' );
|
||||
}
|
||||
}
|
||||
), NULL, NULL, NULL, 'group_username' ) );
|
||||
}
|
||||
@@ -240,7 +251,7 @@ class _GroupSettings
|
||||
{
|
||||
$group->g_dname_changes = ( isset( $values['group_username']['canchange'] ) and $values['group_username']['canchange'] ) ? $values['group_username'][0] : 0;
|
||||
$group->g_displayname_unit = ( isset( $values['group_username']['canchange'] ) ) ? (int) $values['group_username'][1] : 0;
|
||||
$group->g_bitoptions['gbw_displayname_unit_type'] = $values['group_username'][2];
|
||||
$group->g_bitoptions['gbw_displayname_unit_type'] = ( isset( $values['group_username'][2] ) ) ? $values['group_username'][2] : 0;
|
||||
$group->g_dname_date = ( isset( $values['group_username']['canchange'] ) ) ? $values['group_username'][3] : 1;
|
||||
}
|
||||
|
||||
@@ -291,4 +302,48 @@ class _GroupSettings
|
||||
$group->g_bitoptions['gbw_cannot_be_ignored'] = !$values['can_be_ignored'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
* @param \IPS\Member\Group $group The group
|
||||
* @return void
|
||||
*/
|
||||
public function delete( $group )
|
||||
{
|
||||
if ( $group->g_icon )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'core_Theme', $group->g_icon )->delete();
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy Group
|
||||
*
|
||||
* @param \IPS\Member\Group $oldGroup The old, just cloned group
|
||||
* @param \IPS\Member\Group $newGroup The new group
|
||||
* @return void
|
||||
*/
|
||||
public function cloneGroup( $oldGroup, $newGroup )
|
||||
{
|
||||
if ( $oldGroup->g_icon )
|
||||
{
|
||||
try
|
||||
{
|
||||
$icon = \IPS\File::get( 'core_Theme', $oldGroup->g_icon );
|
||||
$newIcon = \IPS\File::create( 'core_Theme', $icon->originalFilename, $icon->contents() );
|
||||
$newGroup->g_icon = (string) $newIcon;
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$newGroup->icon = NULL;
|
||||
}
|
||||
|
||||
$newGroup->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,9 +83,17 @@ class _Social
|
||||
\IPS\Member\Club::TYPE_OPEN => 'club_type_open',
|
||||
\IPS\Member\Club::TYPE_CLOSED => 'club_type_closed',
|
||||
\IPS\Member\Club::TYPE_PRIVATE => 'club_type_private',
|
||||
\IPS\Member\Club::TYPE_READONLY => 'club_type_readonly',
|
||||
),
|
||||
), NULL, NULL, NULL, 'g_create_clubs' ) );
|
||||
|
||||
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->clubs_paid_on )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'gbw_paid_clubs', $group->g_id ? ( $group->g_bitoptions['gbw_paid_clubs'] ) : FALSE ) );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'g_club_limit', $group->g_club_limit ?: -1, FALSE, array( 'unlimited' => -1 ) ) );
|
||||
|
||||
$availableClubNodes = array();
|
||||
foreach ( \IPS\Member\Club::availableNodeTypes() as $class )
|
||||
{
|
||||
@@ -176,6 +184,12 @@ class _Social
|
||||
{
|
||||
$group->g_create_clubs = implode( ',', $values['g_create_clubs'] );
|
||||
$group->g_club_allowed_nodes = ( count( $values['g_club_allowed_nodes'] ) === count( \IPS\Member\Club::availableNodeTypes() ) ) ? '*' : implode( ',', $values['g_club_allowed_nodes'] );
|
||||
$group->g_club_limit = $values['g_club_limit'] == -1 ? NULL : $values['g_club_limit'];
|
||||
|
||||
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->clubs_paid_on )
|
||||
{
|
||||
$bwKeys[] = 'gbw_paid_clubs';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ class _GroupLimits
|
||||
'g_delete_own_posts' => array( $this, '_perAppSettings' ),
|
||||
'g_lock_unlock_own' => array( $this, '_perAppSettings' ),
|
||||
'g_can_report' => array( $this, '_perAppSettings' ),
|
||||
'g_club_allowed_nodes' => array( $this, '_clubNodes' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -134,7 +135,6 @@ class _GroupLimits
|
||||
/* If signatures are currently enabled but aren't in the group we are checking, signatures should not be disabled */
|
||||
elseif ( $index == 0 and $_cur[ $index ] < $values[ $index ] )
|
||||
{
|
||||
|
||||
$_new[ $index ] = $_cur[ $index ];
|
||||
}
|
||||
else if( $_cur[ $index ] > $values[ $index ] )
|
||||
@@ -145,6 +145,13 @@ class _GroupLimits
|
||||
{
|
||||
$_new[ $index ] = $values[ $index ];
|
||||
}
|
||||
|
||||
/* If we are not allowed to use any images, ignore the dimensions specified.
|
||||
Otherwise group A with 0 images and no limits on sizes and group B with 1 images at 200x200 results in 1 image allowed unlimited sizes. */
|
||||
if( ( $index == 2 OR $index == 3 ) AND $values[1] == 0 )
|
||||
{
|
||||
$_new[ $index ] = $_cur[ $index ];
|
||||
}
|
||||
}
|
||||
|
||||
ksort($_new);
|
||||
@@ -353,4 +360,26 @@ class _GroupLimits
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Available node types for clubs
|
||||
*
|
||||
* @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 _clubNodes( $a, $b, $k, $member )
|
||||
{
|
||||
if ( $a[$k] == '*' or $b[$k] == '*' )
|
||||
{
|
||||
return '*';
|
||||
}
|
||||
|
||||
/* We need to merge all content types */
|
||||
$nodeTypes = array_unique( array_merge( explode( ",", $a[$k]), explode( ",", $b[$k]) ) );
|
||||
|
||||
return implode( ",", $nodeTypes );
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ class _Content extends \IPS\Content\ExtensionGenerator
|
||||
try
|
||||
{
|
||||
$comment = $class::load( $data[ $class::$databasePrefix . $class::$databaseColumnId ] );
|
||||
return "<a href='" . $comment->url() . "' target='_blank'>" . htmlspecialchars( $comment->item()->mapped('title'), \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . '</a>';
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $comment->url(), TRUE, $comment->item()->mapped('title') );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -135,7 +135,7 @@ class _Content extends \IPS\Content\ExtensionGenerator
|
||||
}
|
||||
}
|
||||
|
||||
return "<a href='" . $class::load( $data[ $class::$databasePrefix . $class::$databaseColumnId ] )->url() . "' target='_blank'>" . htmlspecialchars( $val, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . '</a>';
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $class::load( $data[ $class::$databasePrefix . $class::$databaseColumnId ] )->url(), TRUE, $val );
|
||||
},
|
||||
);
|
||||
if( isset( $class::$databaseColumnMap['container'] ) )
|
||||
@@ -144,7 +144,7 @@ class _Content extends \IPS\Content\ExtensionGenerator
|
||||
{
|
||||
$nodeClass = $class::$containerNodeClass;
|
||||
$node = $nodeClass::load( $val );
|
||||
return "<a href='" . $node->url() . "' target='_blank'>" . htmlspecialchars( $node->_title, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . '</a>';
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $node->url(), TRUE, $node->_title );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,6 @@ class _MemberHistory
|
||||
*/
|
||||
public function findByMember( $member )
|
||||
{
|
||||
return \IPS\Db::i()->select( "log_ip_address AS ip, COUNT(*) AS count, MIN(log_date) AS first, MAX(log_date) AS last", 'core_member_history', array( 'log_member=?', $member->member_id ), NULL, NULL, 'log_ip_address' )->setKeyField( 'ip' );
|
||||
return \IPS\Db::i()->select( "log_ip_address AS ip, COUNT(*) AS count, MIN(log_date) AS first, MAX(log_date) AS last", 'core_member_history', array( 'log_by=?', $member->member_id ), NULL, NULL, 'log_ip_address' )->setKeyField( 'ip' );
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ class _Ratings
|
||||
{
|
||||
$class = $row['class'];
|
||||
$rated = $class::load( $row['item_id'] );
|
||||
return "<a href='" . $rated->url() . "' target='_blank'>" . htmlspecialchars( $rated->mapped('title'), \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . "</a>";
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $rated->url(), TRUE, $rated->mapped('title') );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
|
||||
@@ -95,7 +95,7 @@ class _Registration
|
||||
'name' => function( $val, $row )
|
||||
{
|
||||
$link = ( \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation === 'front' ) ? \IPS\Member::constructFromData( $row )->url() : \IPS\Member::constructFromData( $row )->acpUrl();
|
||||
return "<a href='" . $link . "'>" . htmlentities( $val, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . "</a>";
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $link, TRUE, $val );
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ class _ReportComments
|
||||
try
|
||||
{
|
||||
$report = \IPS\core\Reports\Report::load( $row['rid'] );
|
||||
return "<a href='" . $report->url() . "' target='_blank'>" . htmlspecialchars( $report->mapped('title'), \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . "</a>";
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $report->url(), TRUE, $report->mapped('title') );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ class _Reports
|
||||
try
|
||||
{
|
||||
$report = \IPS\core\Reports\Report::load( $row['rid'] );
|
||||
return "<a href='" . $report->url() . "' target='_blank'>" . htmlspecialchars( $report->mapped('title'), \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . "</a>";
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $report->url(), TRUE, $reort->mapped('title') );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
|
||||
@@ -87,7 +87,7 @@ class _Validations
|
||||
{
|
||||
$member = \IPS\Member::load( $row['member_id'] );
|
||||
$link = ( \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation === 'front' ) ? $member->url() : $member->acpUrl();
|
||||
return "<a href='" . $link . "'>" . htmlentities( $member->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . "</a>";
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $link, FALSE, $member->name );
|
||||
},
|
||||
'validatingType' => function( $val, $row )
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ class _Votes
|
||||
try
|
||||
{
|
||||
$poll = \IPS\Poll::load( $val );
|
||||
return htmlspecialchars( $poll->poll_question, \IPS\HTMLENTITIES, 'UTF-8', FALSE );
|
||||
return htmlspecialchars( $poll->poll_question, ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Basic Information Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Basic Information Block
|
||||
*/
|
||||
class _BasicInformation extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$hasPassword = FALSE;
|
||||
$canChangePassword = \IPS\Login\Handler::findMethod( 'IPS\Login\Handler\Standard' );
|
||||
$activeIntegrations = array();
|
||||
foreach ( \IPS\Login::methods() as $method )
|
||||
{
|
||||
if ( $method->canProcess( $this->member ) )
|
||||
{
|
||||
if ( !( $method instanceof \IPS\Login\Handler\Standard ) )
|
||||
{
|
||||
$activeIntegrations[] = $method->_title;
|
||||
}
|
||||
if ( $method->canChangePassword( $this->member ) )
|
||||
{
|
||||
$hasPassword = TRUE;
|
||||
$canChangePassword = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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() )
|
||||
{
|
||||
$accountActions[] = array(
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'login_as_x', FALSE, array( 'sprintf' => array( $this->member->name ) ) ),
|
||||
'icon' => 'key',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=login&id={$this->member->member_id}" ),
|
||||
'class' => '',
|
||||
'target' => '_blank'
|
||||
);
|
||||
}
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'members_merge' ) )
|
||||
{
|
||||
$accountActions[] = array(
|
||||
'title' => 'merge_with_another_account',
|
||||
'icon' => 'level-up',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=merge&id={$this->member->member_id}" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('merge') )
|
||||
);
|
||||
}
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_delete' ) and ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_delete_admin' ) or !$this->member->isAdmin() ) and $this->member->member_id != \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$accountActions[] = array(
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=delete&id={$this->member->member_id}" ),
|
||||
'data' => array( 'delete' => '', 'delete-warning' => \IPS\Member::loggedIn()->language()->addToStack( 'member_delete_confirm_desc' ), 'noajax' => '' )
|
||||
);
|
||||
}
|
||||
|
||||
$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
|
||||
{
|
||||
$activeSubscription = \IPS\nexus\Subscription::loadActiveByMember( $this->member );
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->basicInformation( $this->member, $canChangePassword, $hasPassword, $activeIntegrations, $accountActions, $activeSubscription );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Content Statistics Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Content Statistics
|
||||
*/
|
||||
class _ContentStatistics extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
{
|
||||
/**
|
||||
* @brief Percentages
|
||||
*/
|
||||
protected $percentages = array();
|
||||
|
||||
/**
|
||||
* @brief Raw Counts
|
||||
*/
|
||||
protected $rawCounts = array();
|
||||
|
||||
/**
|
||||
* Get Block Title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function blockTitle()
|
||||
{
|
||||
return 'content_statistics';
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Member $member Member
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Member $member )
|
||||
{
|
||||
parent::__construct( $member );
|
||||
|
||||
$classes = array();
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter' ) as $contentRouter )
|
||||
{
|
||||
foreach ( $contentRouter->classes as $class )
|
||||
{
|
||||
$include = FALSE;
|
||||
$exploded = explode( '\\', $class );
|
||||
if ( in_array( 'IPS\Content\Item', class_parents( $class ) ) )
|
||||
{
|
||||
if ( $class::incrementPostCount() )
|
||||
{
|
||||
$include = TRUE;
|
||||
$classes[ $exploded[1] ]['items'][] = $class;
|
||||
}
|
||||
if ( isset( $class::$commentClass ) )
|
||||
{
|
||||
$commentClass = $class::$commentClass;
|
||||
if ( $commentClass::incrementPostCount() )
|
||||
{
|
||||
$include = TRUE;
|
||||
$classes[ $exploded[1] ]['comments'][] = $commentClass;
|
||||
}
|
||||
}
|
||||
if ( isset( $class::$reviewClass ) )
|
||||
{
|
||||
$reviewClass = $class::$reviewClass;
|
||||
if ( $reviewClass::incrementPostCount() )
|
||||
{
|
||||
$include = TRUE;
|
||||
$classes[ $exploded[1] ]['comments'][] = $class::$reviewClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( in_array( 'IPS\Content\Comment', class_parents( $class ) ) )
|
||||
{
|
||||
if ( $class::incrementPostCount() )
|
||||
{
|
||||
$include = TRUE;
|
||||
$classes[ $exploded[1] ]['comments'][] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $include and !isset( $this->percentages[ $exploded[1] ] ) )
|
||||
{
|
||||
$this->percentages[ $exploded[1] ] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sum = 0;
|
||||
$counts = array();
|
||||
foreach ( $classes as $app => $types )
|
||||
{
|
||||
foreach ( $types as $type => $typeClasses )
|
||||
{
|
||||
foreach ( $typeClasses as $class )
|
||||
{
|
||||
if( !isset( $class::$databaseColumnMap['author'] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$authorColumn = $class::$databasePrefix . $class::$databaseColumnMap['author'];
|
||||
|
||||
if ( !isset( $counts[ $app ][ $type ] ) )
|
||||
{
|
||||
$counts[ $app ][ $type ] = 0;
|
||||
}
|
||||
if ( !isset( $this->rawCounts[ $app ][ $class ] ) )
|
||||
{
|
||||
$this->rawCounts[ $app ][ $class ] = 0;
|
||||
}
|
||||
|
||||
$count = $class::memberPostCount( $member );
|
||||
$sum += $count;
|
||||
$counts[ $app ][ $type ] += $count;
|
||||
$this->rawCounts[ $app ][ $class ] += $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $sum )
|
||||
{
|
||||
foreach ( $counts as $app => $types )
|
||||
{
|
||||
if ( array_sum( $types ) )
|
||||
{
|
||||
$this->percentages[ $app ] = round( 100 / $sum * array_sum( $types ), 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Tab Names
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function tabs()
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if ( array_sum( $this->percentages ) )
|
||||
{
|
||||
$return['breakdown'] = 'content_count_breakdown';
|
||||
}
|
||||
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'MemberACPProfileContentTab', TRUE, NULL, NULL, FALSE ) as $class )
|
||||
{
|
||||
try
|
||||
{
|
||||
$ext = new $class( $this->member );
|
||||
$exploded = explode( '\\', $class );
|
||||
$return[ $exploded[1] . '_' . $exploded[5] ] = 'content_stats__' . $exploded[1] . '_' . $exploded[5];
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function tabOutput( $tab )
|
||||
{
|
||||
if ( $tab == 'breakdown' )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->contentBreakdown( $this->member, $this->percentages, $this->rawCounts );
|
||||
}
|
||||
else
|
||||
{
|
||||
$exploded = explode( '_', $tab );
|
||||
$class = 'IPS\\' . $exploded[0] . '\\extensions\\core\\MemberACPProfileContentTab\\' . $exploded[1];
|
||||
|
||||
if ( class_exists( $class ) )
|
||||
{
|
||||
$ext = new $class( $this->member );
|
||||
return $ext->output();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Devices & IP Addresses Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Devices & IP Addresses Block
|
||||
*/
|
||||
class _DevicesAndIPAddresses extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$lastUsedIp = $this->member->lastUsedIp();
|
||||
$devices = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_members_known_devices', array( 'member_id=?', $this->member->member_id ), 'last_seen DESC', 5 ), 'IPS\Member\Device' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->devicesAndIPAddresses( $this->member, $lastUsedIp, $devices );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Groups Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Groups Block
|
||||
*/
|
||||
class _Groups extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$secondaryGroups = array();
|
||||
foreach ( array_filter( array_map( "intval", explode( ',', $this->member->mgroup_others ) ) ) as $secondaryGroupId )
|
||||
{
|
||||
try
|
||||
{
|
||||
$secondaryGroups[] = \IPS\Member\Group::load( $secondaryGroupId );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->groups( $this->member, $secondaryGroups );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Window
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
/* Check permission */
|
||||
if ( $this->member->isAdmin() )
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'member_move_admin1' );
|
||||
}
|
||||
|
||||
/* If we are editing ourselves, we can only move ourselves into a group with the same restrictions as what we have now... */
|
||||
if ( $this->member->member_id == \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
/* Get the row... */
|
||||
try
|
||||
{
|
||||
$currentRestrictions = \IPS\Db::i()->select( 'row_perm_cache', 'core_admin_permission_rows', array( 'row_id=? AND row_id_type=?', $this->member->member_group_id, 'group' ) )->first();
|
||||
$availableGroups = array();
|
||||
foreach( \IPS\Db::i()->select( 'row_id', 'core_admin_permission_rows', array( 'row_perm_cache=? AND row_id_type=?', $currentRestrictions, 'group' ) ) AS $groupId )
|
||||
{
|
||||
$availableGroups[ $groupId ] = \IPS\Member\Group::load( $groupId );
|
||||
}
|
||||
}
|
||||
/* If we don't have a row in core_admin_permission_rows, we're an admin as a member rather than apart of our group, so we can be moved anywhere and it won't matter because member-level restrictions override group-level */
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$availableGroups = \IPS\Member\Group::groups( TRUE, FALSE );
|
||||
}
|
||||
}
|
||||
/* Not editing ourselves - do we have the Can move members into admin groups"" restriction? */
|
||||
else
|
||||
{
|
||||
$availableGroups = \IPS\Member\Group::groups( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_move_admin2' ), FALSE );
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form( 'group_form', 'save', NULL, array(
|
||||
'data-controller' => 'core.admin.members.form',
|
||||
'data-adminGroups' => json_encode( iterator_to_array( \IPS\Db::i()->select( 'row_id', 'core_admin_permission_rows', array( 'row_id_type=?', 'group' ) ) ) )
|
||||
)) ;
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'group', $this->member->member_group_id, TRUE, array( 'options' => $availableGroups, 'parse' => 'normal' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'secondary_groups', array_filter( explode( ',', $this->member->mgroup_others ) ), FALSE, array( 'options' => \IPS\Member\Group::groups( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_move_admin2' ), FALSE ), 'multiple' => TRUE, 'parse' => 'normal' ) ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$oldPrimary = $this->member->member_group_id;
|
||||
$oldSecondary = array_filter( explode( ',', $this->member->mgroup_others ) );
|
||||
|
||||
$changes = array();
|
||||
if ( $this->member->member_group_id != $values['group'] )
|
||||
{
|
||||
$this->member->logHistory( 'core', 'group', array( 'type' => 'primary', 'by' => 'manual', 'old' => $this->member->member_group_id, 'new' => $values['group'] ) );
|
||||
}
|
||||
$currentSecondary = array_filter( explode( ',', $this->member->mgroup_others ) );
|
||||
if ( array_diff( $currentSecondary, $values['secondary_groups'] ) or array_diff( $values['secondary_groups'], $currentSecondary ) )
|
||||
{
|
||||
$this->member->logHistory( 'core', 'group', array( 'type' => 'secondary', 'by' => 'manual', 'old' => $currentSecondary, 'new' => $values['secondary_groups'] ) );
|
||||
}
|
||||
|
||||
$this->member->member_group_id = $values['group'];
|
||||
$this->member->mgroup_others = implode( ',', $values['secondary_groups'] );
|
||||
$this->member->save();
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__members_edited_groups', array( $this->member->name => FALSE ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=view&id={$this->member->member_id}" ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Header Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Header Block
|
||||
*/
|
||||
class _Header extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
/* Sparkline */
|
||||
$rows = array();
|
||||
$cutoff = \IPS\DateTime::create()->setTime( 0, 0, 0 )->sub( new \DateInterval('P30D') );
|
||||
$date = clone $cutoff;
|
||||
while ( $date->getTimestamp() < time() )
|
||||
{
|
||||
$rows[ $date->format( 'Y-n-j' ) ] = 0;
|
||||
$date->add( new \DateInterval( 'P1D' ) );
|
||||
}
|
||||
$sparkline = new \IPS\Helpers\Chart;
|
||||
$classes = array();
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter' ) as $contentRouter )
|
||||
{
|
||||
foreach ( $contentRouter->classes as $class )
|
||||
{
|
||||
$classes[] = $class;
|
||||
if ( isset( $class::$commentClass ) )
|
||||
{
|
||||
$classes[] = $class::$commentClass;
|
||||
}
|
||||
if ( isset( $class::$reviewClass ) )
|
||||
{
|
||||
$classes[] = $class::$reviewClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ( $classes as $class )
|
||||
{
|
||||
if( !isset( $class::$databaseColumnMap['author'] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$dateColumn = $class::$databasePrefix . ( isset( $class::$databaseColumnMap['updated'] ) ? $class::$databaseColumnMap['updated'] : $class::$databaseColumnMap['date'] );
|
||||
$authorColumn = $class::$databasePrefix . $class::$databaseColumnMap['author'];
|
||||
foreach ( \IPS\Db::i()->select( "COUNT(*) AS count, DATE_FORMAT( FROM_UNIXTIME( IFNULL( {$dateColumn}, 0 ) ), '%Y-%c-%e' ) as time", $class::$databaseTable, array( "{$dateColumn}>? AND {$authorColumn}=?", $cutoff->getTimestamp(), $this->member->member_id ), NULL, NULL, array( $authorColumn, $dateColumn ) ) as $row )
|
||||
{
|
||||
$rows[ $row['time'] ] += $row['count'];
|
||||
}
|
||||
}
|
||||
$sparkline->addHeader( \IPS\Member::loggedIn()->language()->addToStack('date'), 'date' );
|
||||
$sparkline->addHeader( \IPS\Member::loggedIn()->language()->addToStack('members_posts'), 'number' );
|
||||
foreach ( $rows as $time => $val )
|
||||
{
|
||||
$datetime = new \IPS\DateTime;
|
||||
$datetime->setTime( 0, 0, 0 );
|
||||
$exploded = explode( '-', $time );
|
||||
$datetime->setDate( $exploded[0], $exploded[1], $exploded[2] );
|
||||
|
||||
$sparkline->addRow( array( $datetime, $val ) );
|
||||
}
|
||||
$sparkline = $sparkline->render( 'AreaChart', array(
|
||||
'areaOpacity' => 0.4,
|
||||
'backgroundColor' => '#fafafa',
|
||||
'colors' => array( '#10967e' ),
|
||||
'chartArea' => array(
|
||||
'left' => 0,
|
||||
'top' => 0,
|
||||
'width' => '100%',
|
||||
'height' => '100%',
|
||||
),
|
||||
'hAxis' => array(
|
||||
'baselineColor' => '#F3F3F3',
|
||||
'gridlines' => array(
|
||||
'count' => 0,
|
||||
)
|
||||
),
|
||||
'height' => 60,
|
||||
'legend' => array(
|
||||
'position' => 'none',
|
||||
),
|
||||
'lineWidth' => 1,
|
||||
'vAxis' => array(
|
||||
'baselineColor' => '#F3F3F3',
|
||||
'gridlines' => array(
|
||||
'count' => 0,
|
||||
)
|
||||
),
|
||||
) );
|
||||
|
||||
/* Validating */
|
||||
$validatingRow = NULL;
|
||||
if ( $this->member->members_bitoptions['validating'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$validatingRow = \IPS\Db::i()->select( '*', 'core_validating', array( 'member_id=?', $this->member->member_id ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
|
||||
/* Output */
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->header( $this->member, $validatingRow, $sparkline );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Window
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
/* Build Form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
if ( \IPS\Request::i()->type == 'content' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'member_content_items', $this->member->member_posts, FALSE ) );
|
||||
}
|
||||
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 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2C114/U', 404, '' );
|
||||
}
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( \IPS\Request::i()->type == 'content' )
|
||||
{
|
||||
$this->member->member_posts = $values['member_content_items'];
|
||||
\IPS\Session::i()->log( 'acplog__members_edited_content', array( $this->member->name => FALSE ) );
|
||||
}
|
||||
elseif ( \IPS\Settings::i()->reputation_enabled and \IPS\Request::i()->type == 'reputation' )
|
||||
{
|
||||
$this->member->pp_reputation_points = $values['member_reputation'];
|
||||
\IPS\Session::i()->log( 'acplog__members_edited_rep', array( $this->member->name => FALSE ) );
|
||||
}
|
||||
$this->member->save();
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=view&id={$this->member->member_id}" ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Locations Map Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Locations Map Block
|
||||
*/
|
||||
class _Locations extends \IPS\core\MemberACPProfile\LazyLoadingBlock
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function lazyOutput()
|
||||
{
|
||||
$mapMarkers = array();
|
||||
if ( \IPS\Settings::i()->ipsgeoip and \IPS\Settings::i()->googlemaps and \IPS\Settings::i()->google_maps_api_key )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( 'DISTINCT ip_address', 'core_members_known_ip_addresses', array( 'member_id=?', $this->member->member_id ) ) as $ipAddress )
|
||||
{
|
||||
try
|
||||
{
|
||||
$location = \IPS\GeoLocation::getByIp( $ipAddress );
|
||||
$mapMarkers[ $ipAddress ] = array(
|
||||
'lat' => floatval( $location->lat ),
|
||||
'long' => floatval( $location->long ),
|
||||
'title' => $ipAddress
|
||||
);
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->locations( $this->member, $mapMarkers );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Login Methods Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Login Methods Block
|
||||
*/
|
||||
class _LoginMethods extends \IPS\core\MemberACPProfile\LazyLoadingBlock
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function lazyOutput()
|
||||
{
|
||||
$loginMethods = array();
|
||||
foreach ( \IPS\Login::methods() as $method )
|
||||
{
|
||||
if ( $method->canProcess( $this->member ) and !( $method instanceof \IPS\Login\Handler\Standard ) )
|
||||
{
|
||||
$link = NULL;
|
||||
try
|
||||
{
|
||||
$link = $method->userLink( $method->userId( $this->member ), $method->userProfileName( $this->member ) );
|
||||
|
||||
$syncOptions = FALSE;
|
||||
foreach ( $method->syncOptions( $this->member ) as $option )
|
||||
{
|
||||
if ( $option == 'photo' and !$this->member->group['g_edit_profile'] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( $option == 'cover' and ( !$this->member->group['g_edit_profile'] or !$this->member->group['gbw_allow_upload_bgimage'] ) )
|
||||
{
|
||||
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'] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$syncOptions = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
$canDisassociate = FALSE;
|
||||
foreach ( \IPS\Login::methods() as $_method )
|
||||
{
|
||||
if ( $_method->id != $method->id and $_method->canProcess( $this->member ) )
|
||||
{
|
||||
$canDisassociate = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$loginMethods[ $method->id ] = array(
|
||||
'title' => $method->_title,
|
||||
'blurb' => \IPS\Member::loggedIn()->language()->addToStack( 'profilesync_headline', FALSE, array( 'sprintf' => array( $method->userProfileName( $this->member ) ) ) ),
|
||||
'icon' => $method->userProfilePhoto( $this->member ),
|
||||
'logo' => $method->logoForUcp(),
|
||||
'link' => $link,
|
||||
'edit' => $syncOptions,
|
||||
'delete'=> $canDisassociate
|
||||
);
|
||||
}
|
||||
catch ( \IPS\Login\Exception $e )
|
||||
{
|
||||
$loginMethods[ $method->id ] = array( 'title' => $method->_title, 'blurb' => \IPS\Member::loggedIn()->language()->addToStack('profilesync_reauth_needed'), 'logo' => $method->logoForUcp(), 'link' => $link );
|
||||
}
|
||||
catch( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'login_method_connect' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->loginMethods( $this->member, $loginMethods );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: MFA Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: MFA Block
|
||||
*/
|
||||
class _MFA extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
if ( !\IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_mfa' ) )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$mfaEnabled = FALSE;
|
||||
$configuredHandlers = array();
|
||||
$hasSecurityQuestions = FALSE;
|
||||
$showEditButton = ( \IPS\Settings::i()->mfa_required_groups != '*' and !$this->member->inGroup( explode( ',', \IPS\Settings::i()->mfa_required_groups ) ) );
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
if ( $handler->isEnabled() and $handler->memberCanUseHandler( $this->member ) )
|
||||
{
|
||||
$mfaEnabled = TRUE;
|
||||
|
||||
if ( $handler->memberHasConfiguredHandler( $this->member ) )
|
||||
{
|
||||
if ( $handler instanceof \IPS\MFA\SecurityQuestions\Handler )
|
||||
{
|
||||
$hasSecurityQuestions = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$configuredHandlers[ $key ] = $handler;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$showEditButton and count( $handler->acpConfiguration( $this->member ) ) )
|
||||
{
|
||||
$showEditButton = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $mfaEnabled )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->mfa( $this->member, $configuredHandlers, $hasSecurityQuestions, $showEditButton );
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Window
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function edit()
|
||||
{
|
||||
/* Check permission */
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'member_mfa' );
|
||||
|
||||
/* Get all the fields we'll need */
|
||||
$fields = array();
|
||||
$optOutToggles = array();
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
if ( $handler->isEnabled() and $handler->memberCanUseHandler( $this->member ) )
|
||||
{
|
||||
foreach ( $handler->acpConfiguration( $this->member ) as $id => $field )
|
||||
{
|
||||
$fields[] = $field;
|
||||
}
|
||||
$optOutToggles[] = "mfa_{$key}_title";
|
||||
}
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
if ( \IPS\Settings::i()->mfa_required_groups != '*' and !$this->member->inGroup( explode( ',', \IPS\Settings::i()->mfa_required_groups ) ) )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'mfa_opt_out_admin', $this->member->members_bitoptions['security_questions_opt_out'], FALSE, array( 'togglesOff' => $optOutToggles ) ) );
|
||||
}
|
||||
foreach ( $fields as $id => $field )
|
||||
{
|
||||
if ( $field instanceof \IPS\Helpers\Form\Matrix )
|
||||
{
|
||||
$form->addMatrix( $field->id, $field );
|
||||
}
|
||||
else
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* Reset the failure count and unlock if necessary */
|
||||
$this->member->failed_mfa_attempts = 0;
|
||||
$mfaDetails = $this->member->mfa_details;
|
||||
if ( isset( $mfaDetails['_lockouttime'] ) )
|
||||
{
|
||||
unset( $mfaDetails['_lockouttime'] );
|
||||
$this->member->mfa_details = $mfaDetails;
|
||||
}
|
||||
|
||||
/* Did we opt out? */
|
||||
if ( isset( $values['mfa_opt_out_admin'] ) )
|
||||
{
|
||||
/* Opt-Out: Disable all handlers */
|
||||
if ( $values['mfa_opt_out_admin'] )
|
||||
{
|
||||
if ( !$this->member->members_bitoptions['security_questions_opt_out'] )
|
||||
{
|
||||
$this->member->members_bitoptions['security_questions_opt_out'] = TRUE;
|
||||
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
if ( $handler->memberHasConfiguredHandler( $this->member ) )
|
||||
{
|
||||
$handler->disableHandlerForMember( $this->member );
|
||||
}
|
||||
}
|
||||
|
||||
$this->member->logHistory( 'core', 'mfa', array( 'handler' => 'questions', 'enable' => FALSE, 'optout' => TRUE ) );
|
||||
$this->member->save();
|
||||
}
|
||||
}
|
||||
/* Opt-In */
|
||||
elseif ( $this->member->members_bitoptions['security_questions_opt_out'] )
|
||||
{
|
||||
$this->member->members_bitoptions['security_questions_opt_out'] = FALSE;
|
||||
$this->member->save();
|
||||
$this->member->logHistory( 'core', 'mfa', array( 'handler' => 'questions', 'enable' => FALSE, 'optout' => FALSE ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Save each of the handlers */
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
if ( $handler->isEnabled() and $handler->memberCanUseHandler( $this->member ) )
|
||||
{
|
||||
$handler->acpConfigurationSave( $this->member, $values );
|
||||
}
|
||||
}
|
||||
|
||||
/* Log and Redirect */
|
||||
\IPS\Session::i()->log( 'acplog__members_edited_mfa', array( $this->member->name => FALSE ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=view&id={$this->member->member_id}" ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: OAuth Apps
|
||||
* @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 29 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Groups Block
|
||||
*/
|
||||
class _OAuth extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'applications', 'oauth_tokens' ) and \IPS\Db::i()->select( 'COUNT(*)', 'core_oauth_clients', array( \IPS\Db::i()->findInSet( 'oauth_grant_types', array( 'authorization_code', 'implicit', 'password' ) ) ) )->first() )
|
||||
{
|
||||
|
||||
$tokens = array();
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_oauth_server_access_tokens', array( 'member_id=?', $this->member->member_id ), 'issued DESC' ) as $token )
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
$client = \IPS\Api\OAuthClient::load( $token['client_id'] );
|
||||
|
||||
$tokens[] = array(
|
||||
'title' => $client->_title,
|
||||
'use_refresh_tokens' => $client->use_refresh_tokens,
|
||||
'data' => $token
|
||||
);
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->oauth( $this->member, $tokens );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Profile Data Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Profile Data Block
|
||||
*/
|
||||
class _ProfileData extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
{
|
||||
/**
|
||||
* @brief Fields
|
||||
*/
|
||||
protected $fields = array();
|
||||
|
||||
/**
|
||||
* @brief Clubs
|
||||
*/
|
||||
protected $clubs = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Member $member Member
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Member $member )
|
||||
{
|
||||
parent::__construct( $member );
|
||||
|
||||
$this->fields = $this->member->profileFields( \IPS\core\ProfileFields\Field::STAFF );
|
||||
$this->clubs = \IPS\Settings::i()->clubs ? \IPS\Member\Club::clubs( NULL, NULL, 'last_activity', array( 'member' => $this->member, 'statuses' => array( \IPS\Member\Club::STATUS_MODERATOR, \IPS\Member\Club::STATUS_EXPIRED_MODERATOR, \IPS\Member\Club::STATUS_LEADER ) ) ) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Block Title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function blockTitle()
|
||||
{
|
||||
return 'profile_data';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Tab Names
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function tabs()
|
||||
{
|
||||
$return = array();
|
||||
if ( count( $this->fields ) || $this->member->member_title || $this->member->rank['title'] || $this->member->rank['image'] || \IPS\Settings::i()->profile_birthday_type != 'none' || \IPS\Settings::i()->signatures_enabled )
|
||||
{
|
||||
$return['fields'] = 'profile_fields';
|
||||
}
|
||||
if ( count( $this->clubs ) )
|
||||
{
|
||||
$return['clubs'] = 'club_ownership';
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Edit Link?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function showEditLink()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function tabOutput( $tab )
|
||||
{
|
||||
if ( $tab == 'fields' )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->profileData( $this->member, $this->fields );
|
||||
}
|
||||
elseif ( $tab == 'clubs' )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->clubs( $this->member, $this->clubs );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Window
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
/* Build basic form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addHeader('profile_data');
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'member_title', $this->member->member_title, FALSE, array( 'maxLength' => 64 ) ) );
|
||||
if ( \IPS\Settings::i()->profile_birthday_type !== 'none' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'bday', array( 'year' => $this->member->bday_year, 'month' => $this->member->bday_month, 'day' => $this->member->bday_day ), FALSE, array( 'getHtml' => function( $element )
|
||||
{
|
||||
return strtr( \IPS\Member::loggedIn()->language()->preferredDateFormat(), array(
|
||||
'DD' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_day( $element->name, $element->value, $element->error ),
|
||||
'MM' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_month( $element->name, $element->value, $element->error ),
|
||||
'YY' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_year( $element->name, $element->value, $element->error ),
|
||||
'YYYY' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_year( $element->name, $element->value, $element->error ),
|
||||
) );
|
||||
} ) ) );
|
||||
}
|
||||
if ( \IPS\Settings::i()->signatures_enabled )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'signature', $this->member->signature, FALSE, array( 'app' => 'core', 'key' => 'Signatures', 'autoSaveKey' => "sig-{$this->member->member_id}", 'attachIds' => array( $this->member->member_id ) ) ) );
|
||||
}
|
||||
|
||||
/* Profile Fields */
|
||||
try
|
||||
{
|
||||
$values = \IPS\Db::i()->select( '*', 'core_pfields_content', array( 'member_id=?', $this->member->member_id ) )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$values = array();
|
||||
}
|
||||
if( count( $values ) )
|
||||
{
|
||||
foreach ( \IPS\core\ProfileFields\Field::fields( $values, \IPS\core\ProfileFields\Field::STAFF ) as $group => $fields )
|
||||
{
|
||||
$form->addHeader( "core_pfieldgroups_{$group}" );
|
||||
foreach ( $fields as $field )
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* Profile Fields */
|
||||
try
|
||||
{
|
||||
$profileFields = \IPS\Db::i()->select( '*', 'core_pfields_content', array( 'member_id=?', $this->member->member_id ) )->first();
|
||||
|
||||
if ( !is_array( $profileFields ) ) // If \IPS\Db::i()->select()->first() has only one column, then the contents of that column is returned. We do not want this here
|
||||
{
|
||||
$profileFields = array();
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$profileFields = array();
|
||||
}
|
||||
$profileFields['member_id'] = $this->member->member_id;
|
||||
foreach ( \IPS\core\ProfileFields\Field::fields( $profileFields, \IPS\core\ProfileFields\Field::STAFF ) as $group => $fields )
|
||||
{
|
||||
foreach ( $fields as $id => $field )
|
||||
{
|
||||
$profileFields[ "field_{$id}" ] = $field::stringValue( !empty( $values[ $field->name ] ) ? $values[ $field->name ] : NULL );
|
||||
}
|
||||
}
|
||||
$this->member->changedCustomFields = $profileFields;
|
||||
\IPS\Db::i()->replace( 'core_pfields_content', $profileFields );
|
||||
|
||||
/* Profile Preferences */
|
||||
$this->member->member_title = $values['member_title'];
|
||||
if ( $values['bday'] )
|
||||
{
|
||||
$this->member->bday_day = $values['bday']['day'];
|
||||
$this->member->bday_month = $values['bday']['month'];
|
||||
$this->member->bday_year = $values['bday']['year'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->member->bday_day = NULL;
|
||||
$this->member->bday_month = NULL;
|
||||
$this->member->bday_year = NULL;
|
||||
}
|
||||
if ( \IPS\Settings::i()->signatures_enabled )
|
||||
{
|
||||
$this->member->signature = $values['signature'];
|
||||
}
|
||||
$this->member->save();
|
||||
|
||||
/* Log and Redirect */
|
||||
\IPS\Session::i()->log( 'acplog__members_edited_profile', array( $this->member->name => FALSE ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=view&id={$this->member->member_id}" ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Quotas Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Quotas Block
|
||||
*/
|
||||
class _Quotas extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$messengerCount = NULL;
|
||||
$messengerPercent = NULL;
|
||||
if ( $this->member->canAccessModule( \IPS\Application\Module::get( 'core', 'messaging', 'front' ) ) and !$this->member->members_disable_pm )
|
||||
{
|
||||
$messengerCount = \IPS\Db::i()->select( 'count(*)', 'core_message_topic_user_map', array( 'map_user_id=? AND map_user_active=1', $this->member->member_id ) )->first();
|
||||
|
||||
if ( $this->member->group['g_max_messages'] > 0 )
|
||||
{
|
||||
$messengerPercent = floor( 100 / $this->member->group['g_max_messages'] * $messengerCount );;
|
||||
}
|
||||
}
|
||||
|
||||
$attachmentStorage = NULL;
|
||||
$attachmentPercent = NULL;
|
||||
if ( $this->member->group['g_attach_max'] != 0 )
|
||||
{
|
||||
$attachmentStorage = \IPS\Db::i()->select( 'SUM(attach_filesize)', 'core_attachments', array( 'attach_member_id=?', $this->member->member_id ) )->first();
|
||||
if ( !$attachmentStorage )
|
||||
{
|
||||
$attachmentStorage = 0;
|
||||
}
|
||||
|
||||
if ( $this->member->group['g_attach_max'] > 0 )
|
||||
{
|
||||
$attachmentPercent = floor( 100 / ( $this->member->group['g_attach_max'] * 1024 ) * $attachmentStorage );
|
||||
}
|
||||
}
|
||||
|
||||
$viewAttachmentsLink = NULL;
|
||||
if ( $attachmentStorage and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'overview', 'files_view' ) )
|
||||
{
|
||||
$viewAttachmentsLink = \IPS\Http\Url::internal('app=core&module=overview&controller=files&advanced_search_submitted=1')->setQueryString( 'attach_member_id', $this->member->name )->csrf();
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->quotas( $this->member, $messengerCount, $messengerPercent, $attachmentStorage, $attachmentPercent, $viewAttachmentsLink );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Window
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$old = $this->member->members_disable_pm;
|
||||
if ( \IPS\Request::i()->enable )
|
||||
{
|
||||
$this->member->members_disable_pm = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( \IPS\Request::i()->prompt ) // Member cannot re-enable
|
||||
{
|
||||
$this->member->members_disable_pm = 2;
|
||||
}
|
||||
else // Member can re-enable
|
||||
{
|
||||
$this->member->members_disable_pm = 1;
|
||||
}
|
||||
}
|
||||
$this->member->save();
|
||||
if ( $old != $this->member->members_disable_pm )
|
||||
{
|
||||
$this->member->logHistory( 'core', 'warning', array( 'restrictions' => array( 'members_disable_pm' => array( 'old' => $old, 'new' => $this->member->members_disable_pm ) ) ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=view&id={$this->member->member_id}" ), 'saved' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Warnings Block
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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 Member Profile: Warnings Block
|
||||
*/
|
||||
class _Warnings extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$restrictions = array();
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'MemberRestrictions', TRUE, 'core', 'Content', FALSE ) as $class )
|
||||
{
|
||||
try
|
||||
{
|
||||
$ext = new $class( $this->member );
|
||||
if ( $ext->enabled() )
|
||||
{
|
||||
foreach ( $ext->activeRestrictions() as $v )
|
||||
{
|
||||
$restrictions[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
$flagActions = array();
|
||||
$spamOption = explode( ',', \IPS\Settings::i()->spm_option );
|
||||
if ( in_array( 'delete', $spamOption ) )
|
||||
{
|
||||
$flagActions[] = \IPS\Member::loggedIn()->language()->addToStack('spam_flag_confirm_delete');
|
||||
}
|
||||
elseif ( in_array( 'unapprove', $spamOption ) )
|
||||
{
|
||||
$flagActions[] = \IPS\Member::loggedIn()->language()->addToStack('spam_flag_confirm_unapprove');
|
||||
}
|
||||
if ( in_array( 'ban', $spamOption ) )
|
||||
{
|
||||
$flagActions[] = \IPS\Member::loggedIn()->language()->addToStack('spam_flag_confirm_ban');
|
||||
}
|
||||
elseif ( in_array( 'disable', $spamOption ) )
|
||||
{
|
||||
$flagActions[] = \IPS\Member::loggedIn()->language()->addToStack('spam_flag_confirm_disable');
|
||||
}
|
||||
if ( \IPS\Settings::i()->spam_service_enabled and \IPS\Settings::i()->spam_service_send_to_ips )
|
||||
{
|
||||
$flagActions[] = \IPS\Member::loggedIn()->language()->addToStack('spam_flag_confirm_report');
|
||||
}
|
||||
if ( count( $flagActions ) )
|
||||
{
|
||||
$flagMessage = sprintf( \IPS\Member::loggedIn()->language()->get('spam_flag_confirm'), \IPS\Member::loggedIn()->language()->formatList( $flagActions ) );
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate('memberprofile')->warnings( $this->member, $restrictions, $flagMessage );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Window
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
/* Get extensions */
|
||||
$extensions = array();
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'MemberRestrictions', TRUE, 'core', 'Content', FALSE ) as $class )
|
||||
{
|
||||
try
|
||||
{
|
||||
$ext = new $class( $this->member );
|
||||
if ( $ext->enabled() )
|
||||
{
|
||||
$exploded = explode( '\\', $class );
|
||||
$extensions[ $exploded[1] . '_' . $exploded[5] ] = $ext;
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
/* Build Form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
if ( \IPS\Settings::i()->warn_on )
|
||||
{
|
||||
$form->addHeader( 'warnings' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'member_warnings', $this->member->warn_level, FALSE ) );
|
||||
}
|
||||
foreach ( $extensions as $key => $ext )
|
||||
{
|
||||
$form->addHeader( 'member_restrictions__' . $key );
|
||||
$ext->form( $form );
|
||||
}
|
||||
|
||||
/* Handle Submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$changes = array();
|
||||
|
||||
if ( \IPS\Settings::i()->warn_on )
|
||||
{
|
||||
if ( $this->member->warn_level != $values['member_warnings'] )
|
||||
{
|
||||
$changes['member_warnings'] = array( 'old' => $this->member->warn_level, 'new' => $values['member_warnings'] );
|
||||
$this->member->warn_level = $values['member_warnings'];
|
||||
}
|
||||
}
|
||||
foreach ( $extensions as $key => $ext )
|
||||
{
|
||||
foreach ( $ext->save( $values ) as $k => $v )
|
||||
{
|
||||
$changes[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $changes ) )
|
||||
{
|
||||
$this->member->logHistory( 'core', 'warning', array( 'restrictions' => $changes ) );
|
||||
}
|
||||
|
||||
$this->member->save();
|
||||
\IPS\Session::i()->log( 'acplog__members_edited_restrictions', array( $this->member->name => FALSE ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=view&id={$this->member->member_id}" ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Main Tab
|
||||
* @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 20 Nov 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberACPProfileTabs;
|
||||
|
||||
/* 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 Member Profile: Main Tab
|
||||
*/
|
||||
class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
{
|
||||
/**
|
||||
* Get left-column blocks
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
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'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get main-column blocks
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function mainColumnBlocks()
|
||||
{
|
||||
return array(
|
||||
'IPS\core\extensions\core\MemberACPProfileBlocks\Header',
|
||||
'IPS\core\extensions\core\MemberACPProfileBlocks\ContentStatistics',
|
||||
'IPS\core\extensions\core\MemberACPProfileBlocks\Quotas',
|
||||
'IPS\core\extensions\core\MemberACPProfileBlocks\Warnings',
|
||||
'IPS\core\extensions\core\MemberACPProfileBlocks\ProfileData',
|
||||
);
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -30,7 +30,7 @@ class _Content
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
{
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions', 'automatic_moderation' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,9 +112,10 @@ class _Content
|
||||
* @note This is only necessary if availableIn() includes group_promotions
|
||||
* @param \IPS\Member $member Member object to check
|
||||
* @param array $filters Previously defined filters
|
||||
* @param object|NULL $object Calling class
|
||||
* @return bool
|
||||
*/
|
||||
public function matches( \IPS\Member $member, $filters )
|
||||
public function matches( \IPS\Member $member, $filters, $object=NULL )
|
||||
{
|
||||
/* If we aren't filtering by this, then any member matches */
|
||||
if( !isset( $filters['content_count_operator'] ) OR !isset( $filters['content_count_score'] ) )
|
||||
@@ -138,4 +139,31 @@ class _Content
|
||||
/* If we are still here, then there wasn't an appropriate operator (maybe they selected 'any') so return true */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a lovely human description for this rule if used
|
||||
*
|
||||
* @param mixed $filters The array returned from the save() method
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function getDescription( $filters )
|
||||
{
|
||||
if ( ! empty( $filters['content_count_score'] ) and $filters['content_count_score'] > 0 )
|
||||
{
|
||||
switch ( $filters['content_count_operator'] )
|
||||
{
|
||||
case 'gt':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_content_gt_desc', NULL, array( 'sprintf' => array( $filters['content_count_score'] ) ) );
|
||||
break;
|
||||
case 'lt':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_content_lt_desc', NULL, array( 'sprintf' => array( $filters['content_count_score'] ) ) );
|
||||
break;
|
||||
case 'eq':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_content_eq_desc', NULL, array( 'sprintf' => array( $filters['content_count_score'] ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class _Group
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
{
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions', 'automatic_moderation' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +70,41 @@ class _Group
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a lovely human description for this rule if used
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function getDescription( $data )
|
||||
{
|
||||
if ( $data['groups'] )
|
||||
{
|
||||
$_groups = explode( ',', $data['groups'] );
|
||||
$humanGroups = array();
|
||||
|
||||
foreach( $_groups as $gid )
|
||||
{
|
||||
/* Uses datastore so not as bad as it looks mkay */
|
||||
try
|
||||
{
|
||||
$humanGroups[] = \IPS\Member\Group::load( $gid )->name;
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $humanGroups ) )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_group_desc', NULL, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $humanGroups ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the filter data
|
||||
*
|
||||
@@ -115,9 +150,10 @@ class _Group
|
||||
* @note This is only necessary if availableIn() includes group_promotions
|
||||
* @param \IPS\Member $member Member object to check
|
||||
* @param array $filters Previously defined filters
|
||||
* @param object|NULL $object Calling class
|
||||
* @return bool
|
||||
*/
|
||||
public function matches( \IPS\Member $member, $filters )
|
||||
public function matches( \IPS\Member $member, $filters, $object=NULL )
|
||||
{
|
||||
/* If we aren't filtering by this, then any member matches */
|
||||
if( !isset( $filters['groups'] ) OR !$filters['groups'] )
|
||||
@@ -127,7 +163,15 @@ class _Group
|
||||
|
||||
$_groups = explode( ',', $filters['groups'] );
|
||||
|
||||
/* This intentionally checks secondary groups, as SQL filtering also checks secondary groups */
|
||||
return (bool) count( array_intersect( $_groups, $member->groups ) );
|
||||
/* If no object is passed, or the property is not set, then we will check secondary groups */
|
||||
if( $object === NULL OR !isset( $object->memberFilterCheckSecondaryGroups ) OR $object->memberFilterCheckSecondaryGroups === TRUE )
|
||||
{
|
||||
/* This checks secondary groups */
|
||||
return (bool) count( array_intersect( $_groups, $member->groups ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return in_array( $member->member_group_id, $_groups );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class _Joined
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
{
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions', 'automatic_moderation' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ class _Joined
|
||||
public function getSettingField( $criteria )
|
||||
{
|
||||
return array(
|
||||
new \IPS\Helpers\Form\Custom( 'bmf_members_joined', array( 0 => isset( $criteria['range'] ) ? $criteria['range'] : '', 1 => isset( $criteria['days'] ) ? $criteria['days'] : NULL ), FALSE, array(
|
||||
new \IPS\Helpers\Form\Custom( 'bmf_members_joined', array( 0 => isset( $criteria['range'] ) ? $criteria['range'] : '', 1 => isset( $criteria['days'] ) ? $criteria['days'] : NULL, 3 => isset( $criteria['days_lt'] ) ? $criteria['days_lt'] : NULL ), FALSE, array(
|
||||
'getHtml' => function( $element )
|
||||
{
|
||||
$dateRange = new \IPS\Helpers\Form\DateRange( "{$element->name}[0]", $element->value[0], FALSE );
|
||||
@@ -62,9 +62,16 @@ class _Joined
|
||||
*/
|
||||
public function save( $post )
|
||||
{
|
||||
if( isset( $post['bmf_members_joined'][2] ) AND $post['bmf_members_joined'][2] == 'days' )
|
||||
if ( isset( $post['bmf_members_joined'][2] ) )
|
||||
{
|
||||
return $post['bmf_members_joined'][1] ? array( 'days' => intval( $post['bmf_members_joined'][1] ) ) : FALSE;
|
||||
if ( $post['bmf_members_joined'][2] == 'days' )
|
||||
{
|
||||
return $post['bmf_members_joined'][1] ? array( 'days' => intval( $post['bmf_members_joined'][1] ) ) : FALSE;
|
||||
}
|
||||
else if ( $post['bmf_members_joined'][2] == 'days_lt' )
|
||||
{
|
||||
return $post['bmf_members_joined'][3] ? array( 'days_lt' => intval( $post['bmf_members_joined'][3] ) ) : FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -83,20 +90,26 @@ class _Joined
|
||||
{
|
||||
if( !empty($data['range']) AND !empty($data['range']['end']) )
|
||||
{
|
||||
$start = ( $data['range']['start']['date'] ) ? new \IPS\DateTime( $data['range']['start']['date'] ) : NULL;
|
||||
$end = ( $data['range']['end']['date'] ) ? new \IPS\DateTime( $data['range']['end']['date'] ) : NULL;
|
||||
$start = ( $data['range']['start'] ) ? new \IPS\DateTime( $data['range']['start'] ) : NULL;
|
||||
$end = ( $data['range']['end'] ) ? new \IPS\DateTime( $data['range']['end'] ) : NULL;
|
||||
|
||||
if( $start and $end )
|
||||
{
|
||||
return "core_members.joined BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}";
|
||||
}
|
||||
}
|
||||
elseif( !empty($data['days']) )
|
||||
elseif( !empty( $data['days'] ) AND (int) $data['days'] )
|
||||
{
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $data['days'] . 'D' ) );
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days'] . 'D' ) );
|
||||
|
||||
return "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 NULL;
|
||||
}
|
||||
@@ -107,9 +120,10 @@ class _Joined
|
||||
* @note This is only necessary if availableIn() includes group_promotions
|
||||
* @param \IPS\Member $member Member object to check
|
||||
* @param array $filters Previously defined filters
|
||||
* @param object|NULL $object Calling class
|
||||
* @return bool
|
||||
*/
|
||||
public function matches( \IPS\Member $member, $filters )
|
||||
public function matches( \IPS\Member $member, $filters, $object=NULL )
|
||||
{
|
||||
/* If we aren't filtering by this, then any member matches */
|
||||
if( ( !isset( $filters['range'] ) OR !$filters['range'] OR empty( $filters['range']['end'] ) ) AND ( !isset( $filters['days'] ) OR !$filters['days'] ) )
|
||||
@@ -130,9 +144,39 @@ class _Joined
|
||||
return (bool) ( $joinedDate->getTimestamp() > $start->getTimestamp() AND $joinedDate->getTimestamp() < $end->getTimestamp() );
|
||||
}
|
||||
}
|
||||
elseif( !empty( $filters['days'] ) )
|
||||
elseif( !empty( $filters['days'] ) AND (int) $filters['days'] )
|
||||
{
|
||||
return (bool) ( $joinedDate->add( new \DateInterval( 'P' . $filters['days'] . 'D' ) )->getTimestamp() < time() );
|
||||
return (bool) ( $joinedDate->add( new \DateInterval( 'P' . (int) $filters['days'] . 'D' ) )->getTimestamp() < time() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a lovely human description for this rule if used
|
||||
*
|
||||
* @param mixed $filters The array returned from the save() method
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function getDescription( $filters )
|
||||
{
|
||||
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;
|
||||
|
||||
if ( $start and $end )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_joined_range_desc', NULL, array( 'sprintf' => array( $start->localeDate(), $end->localeDate() ) ) );
|
||||
}
|
||||
}
|
||||
elseif( !empty( $filters['days'] ) AND (int) $filters['days'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_joined_days_desc', NULL, array( 'sprintf' => array( $filters['days'] ) ) );
|
||||
}
|
||||
elseif( !empty( $filters['days_lt'] ) AND (int) $filters['days_lt'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_joined_days_lt_desc', NULL, array( 'sprintf' => array( $filters['days_lt'] ) ) );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class _Lastpost
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
{
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions', 'automatic_moderation' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ class _Lastpost
|
||||
public function getSettingField( $criteria )
|
||||
{
|
||||
return array(
|
||||
new \IPS\Helpers\Form\Custom( 'mf_members_last_post', array( 0 => isset( $criteria['range'] ) ? $criteria['range'] : '', 1 => isset( $criteria['days'] ) ? $criteria['days'] : NULL ), FALSE, array(
|
||||
new \IPS\Helpers\Form\Custom( 'mf_members_last_post', array( 0 => isset( $criteria['range'] ) ? $criteria['range'] : '', 1 => isset( $criteria['days'] ) ? $criteria['days'] : NULL, 3 => isset( $criteria['days_lt'] ) ? $criteria['days_lt'] : NULL ), FALSE, array(
|
||||
'getHtml' => function( $element )
|
||||
{
|
||||
$dateRange = new \IPS\Helpers\Form\DateRange( "{$element->name}[0]", $element->value[0], FALSE );
|
||||
@@ -62,9 +62,16 @@ class _Lastpost
|
||||
*/
|
||||
public function save( $post )
|
||||
{
|
||||
if( isset( $post['mf_members_last_post'][2] ) AND $post['mf_members_last_post'][2] == 'days' )
|
||||
if ( isset( $post['mf_members_last_post'][2] ) )
|
||||
{
|
||||
return $post['mf_members_last_post'][1] ? array( 'days' => intval( $post['mf_members_last_post'][1] ) ) : FALSE;
|
||||
if ( $post['mf_members_last_post'][2] == 'days' )
|
||||
{
|
||||
return $post['mf_members_last_post'][1] ? array( 'days' => intval( $post['mf_members_last_post'][1] ) ) : FALSE;
|
||||
}
|
||||
else if ( $post['mf_members_last_post'][2] == 'days_lt' )
|
||||
{
|
||||
return $post['mf_members_last_post'][3] ? array( 'days_lt' => intval( $post['mf_members_last_post'][3] ) ) : FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -83,20 +90,27 @@ class _Lastpost
|
||||
{
|
||||
if( !empty($data['range']) AND !empty($data['range']['end']) )
|
||||
{
|
||||
$start = ( $data['range']['start']['date'] ) ? new \IPS\DateTime( $data['range']['start']['date'] ) : NULL;
|
||||
$end = ( $data['range']['end']['date'] ) ? new \IPS\DateTime( $data['range']['end']['date'] ) : NULL;
|
||||
$start = ( $data['range']['start'] ) ? new \IPS\DateTime( $data['range']['start'] ) : NULL;
|
||||
$end = ( $data['range']['end'] ) ? new \IPS\DateTime( $data['range']['end'] ) : NULL;
|
||||
|
||||
if( $start and $end )
|
||||
{
|
||||
return "core_members.member_last_post BETWEEN {$start} AND {$end}";
|
||||
return "core_members.member_last_post BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}";
|
||||
}
|
||||
}
|
||||
elseif( !empty($data['days']) )
|
||||
elseif( !empty( $data['days'] ) AND (int) $data['days'] )
|
||||
{
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $data['days'] . 'D' ) );
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days'] . 'D' ) );
|
||||
|
||||
return "core_members.member_last_post < {$date->getTimestamp()}";
|
||||
return "( 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 NULL;
|
||||
}
|
||||
@@ -107,9 +121,10 @@ class _Lastpost
|
||||
* @note This is only necessary if availableIn() includes group_promotions
|
||||
* @param \IPS\Member $member Member object to check
|
||||
* @param array $filters Previously defined filters
|
||||
* @param object|NULL $object Calling class
|
||||
* @return bool
|
||||
*/
|
||||
public function matches( \IPS\Member $member, $filters )
|
||||
public function matches( \IPS\Member $member, $filters, $object=NULL )
|
||||
{
|
||||
/* If we aren't filtering by this, then any member matches */
|
||||
if( ( !isset( $filters['range'] ) OR !$filters['range'] OR empty( $filters['range']['end'] ) ) AND ( !isset( $filters['days'] ) OR !$filters['days'] ) )
|
||||
@@ -117,6 +132,20 @@ class _Lastpost
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If the member hasn't posted anything yet, he has NULL as member_last_post */
|
||||
if ( !$member->member_last_post )
|
||||
{
|
||||
/* But if we want members who haven't posted in more than X days, return anyone who hasn't posted at all as well */
|
||||
if( !empty( $filters['days'] ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
$lastPost = \IPS\DateTime::ts( $member->member_last_post );
|
||||
|
||||
if( !empty( $filters['range'] ) AND !empty( $filters['range']['end'] ) )
|
||||
@@ -129,9 +158,39 @@ class _Lastpost
|
||||
return (bool) ( $lastPost->getTimestamp() > $start->getTimestamp() AND $lastPost->getTimestamp() < $end->getTimestamp() );
|
||||
}
|
||||
}
|
||||
elseif( !empty( $filters['days'] ) )
|
||||
elseif( !empty( $filters['days'] ) AND (int) $filters['days'] )
|
||||
{
|
||||
return (bool) ( $lastPost->add( new \DateInterval( 'P' . $filters['days'] . 'D' ) )->getTimestamp() < time() );
|
||||
return (bool) ( $lastPost->add( new \DateInterval( 'P' . (int) $filters['days'] . 'D' ) )->getTimestamp() < time() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a lovely human description for this rule if used
|
||||
*
|
||||
* @param mixed $filters The array returned from the save() method
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function getDescription( $filters )
|
||||
{
|
||||
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;
|
||||
|
||||
if ( $start and $end )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_lastpost_range_desc', NULL, array( 'sprintf' => array( $start->localeDate(), $end->localeDate() ) ) );
|
||||
}
|
||||
}
|
||||
elseif( !empty( $filters['days'] ) AND (int) $filters['days'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_lastpost_days_desc', NULL, array( 'sprintf' => array( $filters['days'] ) ) );
|
||||
}
|
||||
elseif( !empty( $filters['days_lt'] ) AND (int) $filters['days_lt'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_lastpost_days_lt_desc', NULL, array( 'sprintf' => array( $filters['days_lt'] ) ) );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class _Lastvisit
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
{
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions', 'automatic_moderation' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ class _Lastvisit
|
||||
public function getSettingField( $criteria )
|
||||
{
|
||||
return array(
|
||||
new \IPS\Helpers\Form\Custom( 'bmf_members_last_visit', array( 0 => isset( $criteria['range'] ) ? $criteria['range'] : '', 1 => isset( $criteria['days'] ) ? $criteria['days'] : NULL ), FALSE, array(
|
||||
new \IPS\Helpers\Form\Custom( 'bmf_members_last_visit', array( 0 => isset( $criteria['range'] ) ? $criteria['range'] : '', 1 => isset( $criteria['days'] ) ? $criteria['days'] : NULL, 3 => isset( $criteria['days_lt'] ) ? $criteria['days_lt'] : NULL ), FALSE, array(
|
||||
'getHtml' => function( $element )
|
||||
{
|
||||
$dateRange = new \IPS\Helpers\Form\DateRange( "{$element->name}[0]", $element->value[0], FALSE );
|
||||
@@ -62,9 +62,16 @@ class _Lastvisit
|
||||
*/
|
||||
public function save( $post )
|
||||
{
|
||||
if( isset( $post['bmf_members_last_visit'][2] ) AND $post['bmf_members_last_visit'][2] == 'days' )
|
||||
if ( isset( $post['bmf_members_last_visit'][2] ) )
|
||||
{
|
||||
return $post['bmf_members_last_visit'][1] ? array( 'days' => intval( $post['bmf_members_last_visit'][1] ) ) : FALSE;
|
||||
if ( $post['bmf_members_last_visit'][2] == 'days' )
|
||||
{
|
||||
return $post['bmf_members_last_visit'][1] ? array( 'days' => intval( $post['bmf_members_last_visit'][1] ) ) : FALSE;
|
||||
}
|
||||
else if ( $post['bmf_members_last_visit'][2] == 'days_lt' )
|
||||
{
|
||||
return $post['bmf_members_last_visit'][3] ? array( 'days_lt' => intval( $post['bmf_members_last_visit'][3] ) ) : FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -91,12 +98,18 @@ class _Lastvisit
|
||||
return "core_members.last_visit BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()}";
|
||||
}
|
||||
}
|
||||
elseif( !empty($data['days']) )
|
||||
elseif( !empty( $data['days'] ) AND (int) $data['days'] )
|
||||
{
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $data['days'] . 'D' ) );
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data['days'] . 'D' ) );
|
||||
|
||||
return "core_members.last_visit < {$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 NULL;
|
||||
}
|
||||
@@ -107,9 +120,10 @@ class _Lastvisit
|
||||
* @note This is only necessary if availableIn() includes group_promotions
|
||||
* @param \IPS\Member $member Member object to check
|
||||
* @param array $filters Previously defined filters
|
||||
* @param object|NULL $object Calling class
|
||||
* @return bool
|
||||
*/
|
||||
public function matches( \IPS\Member $member, $filters )
|
||||
public function matches( \IPS\Member $member, $filters, $object=NULL )
|
||||
{
|
||||
/* If we aren't filtering by this, then any member matches */
|
||||
if( ( !isset( $filters['range'] ) OR !$filters['range'] OR empty( $filters['range']['end'] ) ) AND ( !isset( $filters['days'] ) OR !$filters['days'] ) )
|
||||
@@ -129,9 +143,39 @@ class _Lastvisit
|
||||
return (bool) ( $lastVisit->getTimestamp() > $start->getTimestamp() AND $lastVisit->getTimestamp() < $end->getTimestamp() );
|
||||
}
|
||||
}
|
||||
elseif( !empty( $filters['days'] ) )
|
||||
elseif( !empty( $filters['days'] ) AND (int) $filters['days'] )
|
||||
{
|
||||
return (bool) ( $lastVisit->add( new \DateInterval( 'P' . $filters['days'] . 'D' ) )->getTimestamp() < time() );
|
||||
return (bool) ( $lastVisit->add( new \DateInterval( 'P' . (int) $filters['days'] . 'D' ) )->getTimestamp() < time() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a lovely human description for this rule if used
|
||||
*
|
||||
* @param mixed $filters The array returned from the save() method
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function getDescription( $filters )
|
||||
{
|
||||
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;
|
||||
|
||||
if ( $start and $end )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_lastvisit_range_desc', NULL, array( 'sprintf' => array( $start->localeDate(), $end->localeDate() ) ) );
|
||||
}
|
||||
}
|
||||
elseif( !empty( $filters['days'] ) AND (int) $filters['days'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_lastvisit_days_desc', NULL, array( 'sprintf' => array( $filters['days'] ) ) );
|
||||
}
|
||||
elseif( !empty( $filters['days_lt'] ) AND (int) $filters['days_lt'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_lastvisit_days_lt_desc', NULL, array( 'sprintf' => array( $filters['days_lt'] ) ) );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -83,9 +83,10 @@ class _Leaderboard
|
||||
* @note This is only necessary if availableIn() includes group_promotions
|
||||
* @param \IPS\Member $member Member object to check
|
||||
* @param array $filters Previously defined filters
|
||||
* @param object|NULL $object Calling class
|
||||
* @return bool
|
||||
*/
|
||||
public function matches( \IPS\Member $member, $filters )
|
||||
public function matches( \IPS\Member $member, $filters, $object=NULL )
|
||||
{
|
||||
/* If we aren't filtering by this, then any member matches */
|
||||
if( !isset( $filters['leaderboard'] ) OR !$filters['leaderboard'] )
|
||||
|
||||
@@ -1,114 +1,4 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Member filter extension: Linked accounts
|
||||
* @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 Mar 2017
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\MemberFilter;
|
||||
// Removed
|
||||
|
||||
/* 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: Member last visit date
|
||||
*/
|
||||
class _Linkedaccounts
|
||||
{
|
||||
/**
|
||||
* 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 )
|
||||
{
|
||||
$services = array();
|
||||
$options = array( 'any' => 'any', 'linked' => 'mf_profile_linked', 'unlinked' => 'mf_profile_unlinked' );
|
||||
foreach ( \IPS\core\ProfileSync\ProfileSyncAbstract::services() as $key => $class )
|
||||
{
|
||||
if( $class::memberFilterLinkedWhere() )
|
||||
{
|
||||
$services[] = new \IPS\Helpers\Form\Radio( 'profilesync__' . $key, isset( $criteria['profilesync__' . $key] ) ? $criteria['profilesync__' . $key] : 'any', FALSE, array( 'options' => $options ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = array();
|
||||
foreach ( \IPS\core\ProfileSync\ProfileSyncAbstract::services() as $key => $class )
|
||||
{
|
||||
if( isset( $post['profilesync__' . $key] ) and in_array( $post['profilesync__' . $key], array( 'linked', 'unlinked' ) ) )
|
||||
{
|
||||
$return['profilesync__' . $key] = $post['profilesync__' . $key];
|
||||
}
|
||||
}
|
||||
|
||||
return count( $return ) ? $return : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function getQueryWhereClause( $data )
|
||||
{
|
||||
$return = array();
|
||||
foreach ( \IPS\core\ProfileSync\ProfileSyncAbstract::services() as $key => $class )
|
||||
{
|
||||
if( !isset( $data['profilesync__' . $key] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch( $data['profilesync__' . $key] )
|
||||
{
|
||||
case 'linked':
|
||||
$where = $class::memberFilterLinkedWhere();
|
||||
break;
|
||||
case 'unlinked':
|
||||
$where = $class::memberFilterLinkedWhere( TRUE );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if( $where )
|
||||
{
|
||||
$return[] = $where;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class _Reputation
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
{
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions', 'automatic_moderation' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,9 +112,10 @@ class _Reputation
|
||||
* @note This is only necessary if availableIn() includes group_promotions
|
||||
* @param \IPS\Member $member Member object to check
|
||||
* @param array $filters Previously defined filters
|
||||
* @param object|NULL $object Calling class
|
||||
* @return bool
|
||||
*/
|
||||
public function matches( \IPS\Member $member, $filters )
|
||||
public function matches( \IPS\Member $member, $filters, $object=NULL )
|
||||
{
|
||||
/* If we aren't filtering by this, then any member matches */
|
||||
if( !isset( $filters['reputation_operator'] ) OR !$filters['reputation_operator'] OR !isset( $filters['reputation_score'] ) OR !$filters['reputation_score'] )
|
||||
@@ -138,4 +139,31 @@ class _Reputation
|
||||
/* If we are still here, then there wasn't an appropriate operator (maybe they selected 'any') so return true */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a lovely human description for this rule if used
|
||||
*
|
||||
* @param mixed $filters The array returned from the save() method
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function getDescription( $filters )
|
||||
{
|
||||
if ( ! empty( $filters['reputation_score'] ) and $filters['reputation_score'] > 0 )
|
||||
{
|
||||
switch ( $filters['reputation_operator'] )
|
||||
{
|
||||
case 'gt':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_reputation_gt_desc', NULL, array( 'sprintf' => array( $filters['reputation_score'] ) ) );
|
||||
break;
|
||||
case 'lt':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_reputation_lt_desc', NULL, array( 'sprintf' => array( $filters['reputation_score'] ) ) );
|
||||
break;
|
||||
case 'eq':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'member_filter_core_reputation_eq_desc', NULL, array( 'sprintf' => array( $filters['reputation_score'] ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,6 @@ class _Twofactor
|
||||
*/
|
||||
public function getSettingField( $criteria )
|
||||
{
|
||||
|
||||
$options = array( 'any' => 'any', 'active' => 'mf_two_factor_active', 'inactive' => 'mf_two_factor_inactive' );
|
||||
|
||||
return array(
|
||||
|
||||
@@ -8,250 +8,4 @@
|
||||
* @since 08 Apr 2013
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin CP Member Form
|
||||
*/
|
||||
class _BasicInformation
|
||||
{
|
||||
/**
|
||||
* Action Buttons
|
||||
*
|
||||
* @param \IPS\Member $member The Member
|
||||
* @return array
|
||||
*/
|
||||
public function actionButtons( $member )
|
||||
{
|
||||
$return = array();
|
||||
|
||||
/* If we can sign in as, flag as spammer, merge, ban or delete content */
|
||||
if ( ( \IPS\Member::loggedIn()->member_id != $member->member_id AND \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_login' ) AND !$member->isBanned() ) || ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_edit' ) and ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_edit_admin' ) or !$member->isAdmin() ) AND $member->member_id != \IPS\Member::loggedIn()->member_id ) || \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'members_merge' ) || ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_ban' ) and ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_ban_admin' ) or !$member->isAdmin() ) AND $member->member_id != \IPS\Member::loggedIn()->member_id ) || ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'membertools_delete' ) ) )
|
||||
{
|
||||
$return['actions'] = array(
|
||||
'title' => 'member_account_actions',
|
||||
'icon' => 'user',
|
||||
'primary' => TRUE,
|
||||
'link' => '#',
|
||||
'menu' => array()
|
||||
);
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id != $member->member_id AND \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_login' ) AND !$member->isBanned() )
|
||||
{
|
||||
$return['actions']['menu'][] = array(
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'login_as_x', FALSE, array( 'sprintf' => array( $member->name ) ) ),
|
||||
'icon' => 'key',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=login&id={$member->member_id}" ),
|
||||
'class' => '',
|
||||
'target' => '_blank'
|
||||
);
|
||||
}
|
||||
|
||||
/* Flag */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_edit' ) and ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_edit_admin' ) or !$member->isAdmin() ) AND $member->member_id != \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$return['actions']['menu'][] = array(
|
||||
'title' => $member->members_bitoptions['bw_is_spammer'] ? 'spam_unflag' : 'spam_flag',
|
||||
'icon' => 'flag',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=members&controller=members&do=spam&id=' )->setQueryString( array( 'id' => $member->member_id, 'status' => $member->members_bitoptions['bw_is_spammer'] ? 0 : 1 ) ),
|
||||
'class' => ''
|
||||
);
|
||||
}
|
||||
|
||||
/* Merge */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'members_merge' ) )
|
||||
{
|
||||
$return['actions']['menu'][] = array(
|
||||
'title' => 'merge',
|
||||
'icon' => 'level-up',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=merge&id={$member->member_id}" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('merge') )
|
||||
);
|
||||
}
|
||||
|
||||
/* Ban */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_ban' ) and ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_ban_admin' ) or !$member->isAdmin() ) AND $member->member_id != \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$return['actions']['menu'][] = array(
|
||||
'title' => $member->temp_ban ? 'adjust_ban' : 'ban',
|
||||
'icon' => 'times',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=ban&id={$member->member_id}" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => $member->temp_ban ? \IPS\Member::loggedIn()->language()->addToStack('adjust_ban') : \IPS\Member::loggedIn()->language()->addToStack('ban') )
|
||||
);
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'membertools_delete' ) )
|
||||
{
|
||||
$return['actions']['menu'][] = array(
|
||||
'title' => 'member_delete_content',
|
||||
'icon' => 'trash-o',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=deleteContent&id={$member->member_id}" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('member_delete_content') )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$return['view'] = array(
|
||||
'title' => 'profile_view_profile',
|
||||
'icon' => 'search',
|
||||
'link' => $member->url(),
|
||||
'class' => '',
|
||||
'target' => '_blank'
|
||||
);
|
||||
|
||||
if ( \IPS\Settings::i()->warn_on AND \IPS\Member::loggedIn()->modPermission('mod_see_warn') )
|
||||
{
|
||||
$return['warnings'] = array(
|
||||
'title' => 'modcp_view_warnings',
|
||||
'icon' => 'exclamation-triangle',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=system&controller=warnings&id=" . $member->member_id, 'front', 'warn_list', array( $member->members_seo_name ) ),
|
||||
'target' => '_blank'
|
||||
);
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_history' ) )
|
||||
{
|
||||
$return['history'] = array(
|
||||
'title' => 'member_history',
|
||||
'icon' => 'history',
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=history&id=" . $member->member_id )
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\Member $member Existing Member
|
||||
* @return void
|
||||
*/
|
||||
public function process( &$form, $member )
|
||||
{
|
||||
/* Username */
|
||||
$form->addHeader('member_basic_information');
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'ips_member_name', $member->name, TRUE, array( 'accountUsername' => $member ), NULL, NULL, '<a data-ipsDialog data-ipsDialog-title="' . \IPS\Member::loggedIn()->language()->addToStack( 'dname_history' ) . '" data-ipsDialog-url="' . \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=viewDnameHistory&id={$member->member_id}" ) . '" href="' . \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=viewDnameHistory&id={$member->member_id}" ) . '">' . \IPS\Member::loggedIn()->language()->addToStack( 'view_username_history' ) . '</a>' ) );
|
||||
|
||||
/* Password */
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'password', NULL, FALSE, array(
|
||||
'getHtml' => function( $element ) use ( $member )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('members')->changePassword( $element->name, $member->member_id );
|
||||
}
|
||||
) ) );
|
||||
|
||||
/* Email */
|
||||
$form->add( new \IPS\Helpers\Form\Email( 'ips_address_mail', $member->email, TRUE, array( 'accountEmail' => $member ) ) );
|
||||
|
||||
/* Group - if this member is an admin, we need the "Can move admins into other groups" restriction */
|
||||
if ( !$member->isAdmin() or \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_move_admin1' ) )
|
||||
{
|
||||
/* If we are editing ourselves, we can only move ourselves into a group with the same restrictions as what we have now... */
|
||||
if ( $member->member_id == \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
/* Get the row... */
|
||||
try
|
||||
{
|
||||
$currentRestrictions = \IPS\Db::i()->select( 'row_perm_cache', 'core_admin_permission_rows', array( 'row_id=? AND row_id_type=?', $member->member_group_id, 'group' ) )->first();
|
||||
$availableGroups = array();
|
||||
foreach( \IPS\Db::i()->select( 'row_id', 'core_admin_permission_rows', array( 'row_perm_cache=? AND row_id_type=?', $currentRestrictions, 'group' ) ) AS $groupId )
|
||||
{
|
||||
$availableGroups[ $groupId ] = \IPS\Member\Group::load( $groupId );
|
||||
}
|
||||
}
|
||||
/* If we don't have a row in core_admin_permission_rows, we're an admin as a member rather than apart of our group, so we can be moved anywhere and it won't matter because member-level restrictions override group-level */
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$availableGroups = \IPS\Member\Group::groups( TRUE, FALSE );
|
||||
}
|
||||
}
|
||||
/* Not editing ourselves - do we have the Can move members into admin groups"" restriction? */
|
||||
else
|
||||
{
|
||||
$availableGroups = \IPS\Member\Group::groups( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_move_admin2' ), FALSE );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'group', $member->member_group_id, TRUE, array( 'options' => $availableGroups, 'parse' => 'normal' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'secondary_groups', array_filter( explode( ',', $member->mgroup_others ) ), FALSE, array( 'options' => \IPS\Member\Group::groups( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_move_admin2' ), FALSE ), 'multiple' => TRUE, 'parse' => 'normal' ) ) );
|
||||
}
|
||||
|
||||
/* Counts */
|
||||
$confirmButtons = json_encode( array(
|
||||
'yes' => \IPS\Member::loggedIn()->language()->addToStack('yes'),
|
||||
'no' => \IPS\Member::loggedIn()->language()->addToStack('recount_all'),
|
||||
'cancel' => \IPS\Member::loggedIn()->language()->addToStack('cancel'),
|
||||
) );
|
||||
$form->addHeader('member_counts');
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'member_content_items', $member->member_posts, FALSE, array(), NULL, NULL, '<a data-confirm data-confirmType="verify" data-confirmButtons=\'' . $confirmButtons . '\' data-confirmSubMessage="' . \IPS\Member::loggedIn()->language()->addToStack('member_content_items_recount') . '" href="' . \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=recountContent&id={$member->member_id}") . '">' . \IPS\Member::loggedIn()->language()->addToStack('recount') . '</a>' ) );
|
||||
if ( \IPS\Settings::i()->reputation_enabled )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'member_reputation', $member->pp_reputation_points, FALSE, array( 'min' => NULL ), NULL, NULL, '<a data-confirm data-confirmType="verify" data-confirmButtons=\'' . $confirmButtons . '\' data-confirmSubMessage="' . \IPS\Member::loggedIn()->language()->addToStack('member_reputation_recount') . '" href="' . \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=recountReputation&id={$member->member_id}") . '">' . \IPS\Member::loggedIn()->language()->addToStack('recount') . '</a>' . ' · <a data-confirm href="' . \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=removeReputation&id={$member->member_id}&type=given") . '">' . \IPS\Member::loggedIn()->language()->addToStack('reputation_remove_given') . '</a>' . ' · <a data-confirm href="' . \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=removeReputation&id={$member->member_id}&type=received") . '">' . \IPS\Member::loggedIn()->language()->addToStack('reputation_remove_received') . '</a>' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\Member $member The member
|
||||
* @return void
|
||||
*/
|
||||
public function save( $values, &$member )
|
||||
{
|
||||
if ( $values['ips_member_name'] != $member->name )
|
||||
{
|
||||
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
|
||||
{
|
||||
try
|
||||
{
|
||||
$handler->changeUsername( $member, $member->name, $values['ips_member_name'] );
|
||||
}
|
||||
catch( \BadMethodCallException $e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $values['ips_address_mail'] != $member->email )
|
||||
{
|
||||
$oldEmail = $member->email;
|
||||
foreach ( \IPS\Login::handlers( TRUE ) as $handler )
|
||||
{
|
||||
try
|
||||
{
|
||||
$handler->changeEmail( $member, $oldEmail, $values['ips_address_mail'] );
|
||||
}
|
||||
catch( \BadMethodCallException $e ) {}
|
||||
}
|
||||
$member->invalidateSessionsAndLogins( TRUE, \IPS\Session::i()->id );
|
||||
}
|
||||
|
||||
if ( !$member->isAdmin() or \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_move_admin1' ) )
|
||||
{
|
||||
$member->member_group_id = $values['group'];
|
||||
$member->mgroup_others = implode( ',', $values['secondary_groups'] );
|
||||
}
|
||||
$member->member_posts = $values['member_content_items'];
|
||||
if ( \IPS\Settings::i()->reputation_enabled )
|
||||
{
|
||||
$member->pp_reputation_points = $values['member_reputation'];
|
||||
}
|
||||
|
||||
if ( $values['password'] )
|
||||
{
|
||||
$member->members_pass_salt = $member->generateSalt();
|
||||
$member->members_pass_hash = $member->encryptedPassword( $values['password'] );
|
||||
$member->invalidateSessionsAndLogins( TRUE, \IPS\Session::i()->id );
|
||||
}
|
||||
|
||||
/* Reset Profile Complete flag in case this was an optional step */
|
||||
$member->members_bitoptions['profile_completed'] = FALSE;
|
||||
}
|
||||
}
|
||||
// Removed
|
||||
@@ -64,7 +64,12 @@ class _Notifications
|
||||
*/
|
||||
public function save( $values, &$member )
|
||||
{
|
||||
if ( $member->allow_admin_mails != $values['allow_admin_mails'] )
|
||||
{
|
||||
$member->logHistory( 'core', 'admin_mails', array( 'enabled' => (bool) $values['allow_admin_mails'] ) );
|
||||
}
|
||||
$member->allow_admin_mails = (int) $values['allow_admin_mails'];
|
||||
|
||||
$member->auto_track = json_encode( array(
|
||||
'content' => ( is_array( $values['auto_track'] ) AND in_array( 'content', $values['auto_track'] ) ) ? 1 : 0,
|
||||
'comments' => ( is_array( $values['auto_track'] ) AND in_array( 'comments', $values['auto_track'] ) ) ? 1 : 0,
|
||||
|
||||
@@ -35,7 +35,7 @@ class _Preferences
|
||||
$form->addHeader('member_preferences_system');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'member_timezone_override',!$member->members_bitoptions['timezone_override'], FALSE, array( 'togglesOff' => array( 'timezone' ) ) ) );
|
||||
$timezones = array();
|
||||
foreach ( \DateTimeZone::listIdentifiers() as $tz )
|
||||
foreach ( \IPS\DateTime::getTimezoneIdentifiers() as $tz )
|
||||
{
|
||||
if ( $pos = mb_strpos( $tz, '/' ) )
|
||||
{
|
||||
@@ -78,6 +78,11 @@ class _Preferences
|
||||
/* Content */
|
||||
$form->addHeader('member_preferences_content');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'view_sigs', $member->members_bitoptions['view_sigs'], FALSE ) );
|
||||
|
||||
/* Profile */
|
||||
$form->addHeader('member_preferences_profile');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'pp_setting_count_visitors', $member->members_bitoptions['pp_setting_count_visitors'], FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'pp_setting_moderate_followers', !$member->members_bitoptions['pp_setting_moderate_followers'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,5 +112,7 @@ class _Preferences
|
||||
|
||||
/* Other */
|
||||
$member->members_bitoptions['view_sigs'] = $values['view_sigs'];
|
||||
$member->members_bitoptions['pp_setting_count_visitors'] = $values['pp_setting_count_visitors'];
|
||||
$member->members_bitoptions['pp_setting_moderate_followers'] = $values['pp_setting_moderate_followers'] ? FALSE : TRUE;
|
||||
}
|
||||
}
|
||||
@@ -8,146 +8,4 @@
|
||||
* @since 08 Apr 2013
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin CP Member Form
|
||||
*/
|
||||
class _Profile
|
||||
{
|
||||
/**
|
||||
* Process Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\Member $member Existing Member
|
||||
* @return void
|
||||
*/
|
||||
public function process( &$form, $member )
|
||||
{
|
||||
/* Profile Preferences */
|
||||
$form->addHeader('member_preferences_profile');
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'pp_cover_photo', $member->pp_cover_photo ? \IPS\File::get( 'core_Profile', $member->pp_cover_photo ) : NULL, FALSE, array( 'storageExtension' => 'core_Profile', 'image' => TRUE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'member_title', $member->member_title, FALSE, array( 'maxLength' => 64 ) ) );
|
||||
if ( \IPS\Settings::i()->profile_birthday_type !== 'none' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'bday', array( 'year' => $member->bday_year, 'month' => $member->bday_month, 'day' => $member->bday_day ), FALSE, array( 'getHtml' => function( $element )
|
||||
{
|
||||
return strtr( \IPS\Member::loggedIn()->language()->preferredDateFormat(), array(
|
||||
'DD' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_day( $element->name, $element->value, $element->error ),
|
||||
'MM' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_month( $element->name, $element->value, $element->error ),
|
||||
'YY' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_year( $element->name, $element->value, $element->error ),
|
||||
'YYYY' => \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->bdayForm_year( $element->name, $element->value, $element->error ),
|
||||
) );
|
||||
} ) ) );
|
||||
}
|
||||
|
||||
|
||||
if ( \IPS\Settings::i()->signatures_enabled )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'signature', $member->signature, FALSE, array( 'app' => 'core', 'key' => 'Signatures', 'autoSaveKey' => "sig-{$member->member_id}", 'attachIds' => array( $member->member_id ) ) ) );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'pp_setting_count_visitors', $member->members_bitoptions['pp_setting_count_visitors'], FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'pp_setting_moderate_followers', !$member->members_bitoptions['pp_setting_moderate_followers'] ) );
|
||||
|
||||
/* Profile Fields */
|
||||
try
|
||||
{
|
||||
$values = \IPS\Db::i()->select( '*', 'core_pfields_content', array( 'member_id=?', $member->member_id ) )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$values = array();
|
||||
}
|
||||
if( count( $values ) )
|
||||
{
|
||||
foreach ( \IPS\core\ProfileFields\Field::fields( $values, \IPS\core\ProfileFields\Field::STAFF ) as $group => $fields )
|
||||
{
|
||||
$form->addHeader( "core_pfieldgroups_{$group}" );
|
||||
foreach ( $fields as $field )
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\Member $member The member
|
||||
* @return void
|
||||
*/
|
||||
public function save( $values, &$member )
|
||||
{
|
||||
/* Profile Preferences */
|
||||
$member->member_title = $values['member_title'];
|
||||
|
||||
if ( $values['bday'] )
|
||||
{
|
||||
$member->bday_day = $values['bday']['day'];
|
||||
$member->bday_month = $values['bday']['month'];
|
||||
$member->bday_year = $values['bday']['year'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$member->bday_day = NULL;
|
||||
$member->bday_month = NULL;
|
||||
$member->bday_year = NULL;
|
||||
}
|
||||
|
||||
if ( \IPS\Settings::i()->signatures_enabled )
|
||||
{
|
||||
$member->signature = $values['signature'];
|
||||
}
|
||||
|
||||
$member->members_bitoptions['pp_setting_count_visitors'] = $values['pp_setting_count_visitors'];
|
||||
$member->members_bitoptions['pp_setting_moderate_followers'] = $values['pp_setting_moderate_followers'] ? FALSE : TRUE;
|
||||
|
||||
/* Cover photo */
|
||||
if ( $values['pp_cover_photo'] )
|
||||
{
|
||||
$member->pp_cover_photo = (string) $values['pp_cover_photo'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$member->pp_cover_photo = '';
|
||||
}
|
||||
|
||||
/* Profile Fields */
|
||||
try
|
||||
{
|
||||
$profileFields = \IPS\Db::i()->select( '*', 'core_pfields_content', array( 'member_id=?', $member->member_id ) )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$profileFields = array();
|
||||
}
|
||||
|
||||
/* If \IPS\Db::i()->select()->first() has only one column, then the contents of that column is returned. We do not want this here. */
|
||||
if ( !is_array( $profileFields ) )
|
||||
{
|
||||
$profileFields = array();
|
||||
}
|
||||
|
||||
$profileFields['member_id'] = $member->member_id;
|
||||
foreach ( \IPS\core\ProfileFields\Field::fields( $profileFields, \IPS\core\ProfileFields\Field::STAFF ) as $group => $fields )
|
||||
{
|
||||
foreach ( $fields as $id => $field )
|
||||
{
|
||||
$profileFields[ "field_{$id}" ] = $field::stringValue( !empty( $values[ $field->name ] ) ? $values[ $field->name ] : NULL );
|
||||
}
|
||||
}
|
||||
\IPS\Db::i()->replace( 'core_pfields_content', $profileFields );
|
||||
|
||||
$member->changedCustomFields = $profileFields;
|
||||
}
|
||||
}
|
||||
// Removed
|
||||
@@ -1,137 +1,3 @@
|
||||
<?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 15 Apr 2013
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin CP Member Form
|
||||
*/
|
||||
class _Restrictions
|
||||
{
|
||||
/**
|
||||
* Process Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\Member $member Existing Member
|
||||
* @return void
|
||||
*/
|
||||
public function process( &$form, $member )
|
||||
{
|
||||
/* Moderation */
|
||||
$form->addHeader( 'member_moderation' );
|
||||
if ( \IPS\Settings::i()->warn_on )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'member_warnings', $member->warn_level, FALSE ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Date( 'restrict_post', $member->restrict_post, FALSE, array( 'time' => TRUE, 'unlimited' => -1, 'unlimitedLang' => 'indefinitely' ), NULL, \IPS\Member::loggedIn()->language()->addToStack('until') ) );
|
||||
$form->add( new \IPS\Helpers\Form\Date( 'mod_posts', $member->mod_posts, FALSE, array( 'time' => TRUE, 'unlimited' => -1, 'unlimitedLang' => 'indefinitely' ), NULL, \IPS\Member::loggedIn()->language()->addToStack('until') ) );
|
||||
|
||||
/* Restrictions */
|
||||
$form->addHeader( 'member_restrictions' );
|
||||
if ( \IPS\Settings::i()->tags_enabled )
|
||||
{
|
||||
if ( !$member->group['gbw_disable_tagging'] )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'bw_disable_tagging', !$member->members_bitoptions['bw_disable_tagging'] ) );
|
||||
}
|
||||
if ( !$member->group['gbw_disable_prefixes'] )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'bw_disable_prefixes', !$member->members_bitoptions['bw_disable_prefixes'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $member->canAccessModule( \IPS\Application\Module::get( 'core', 'members' ) ) )
|
||||
{
|
||||
/* There are two columns for "can post status updates". The first is a user-level option (the user can turn status updates on and
|
||||
off in their account), and the second is an admin-level option (block user from posting status updates). Having two options is
|
||||
confusing so we merge both options into one select list which matches the PM dropdown below */
|
||||
$value = ( !$member->members_bitoptions['bw_no_status_update'] AND $member->pp_setting_count_comments ) ? 0 :
|
||||
( !$member->members_bitoptions['bw_no_status_update'] ? 1 : 2 );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'bw_no_status_update', $value, FALSE, array( 'options' => array(
|
||||
0 => 'members_disable_pm_on',
|
||||
1 => 'members_disable_pm_member_disable',
|
||||
2 => 'members_disable_pm_admin_disable',
|
||||
) ) ) );
|
||||
}
|
||||
|
||||
if ( $member->canAccessModule( \IPS\Application\Module::get( 'core', 'messaging', 'front' ) ) )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'members_disable_pm', $member->members_disable_pm, FALSE, array( 'options' => array(
|
||||
0 => 'members_disable_pm_on',
|
||||
1 => 'members_disable_pm_member_disable',
|
||||
2 => 'members_disable_pm_admin_disable',
|
||||
) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\Member $member The member
|
||||
* @return void
|
||||
*/
|
||||
public function save( $values, &$member )
|
||||
{
|
||||
if ( \IPS\Settings::i()->warn_on )
|
||||
{
|
||||
$member->warn_level = $values['member_warnings'];
|
||||
}
|
||||
$member->mod_posts = is_object( $values['mod_posts'] ) ? $values['mod_posts']->getTimestamp() : ( $values['mod_posts'] ?: 0 );
|
||||
$member->restrict_post = is_object( $values['restrict_post'] ) ? $values['restrict_post']->getTimestamp() : ( $values['restrict_post'] ?: 0 );
|
||||
|
||||
if ( \IPS\Settings::i()->tags_enabled )
|
||||
{
|
||||
if ( !$member->group['gbw_disable_tagging'] AND array_key_exists( 'bw_disable_tagging', $values ) )
|
||||
{
|
||||
$member->members_bitoptions['bw_disable_tagging'] = !$values['bw_disable_tagging'];
|
||||
}
|
||||
if ( !$member->group['gbw_disable_prefixes'] AND array_key_exists( 'bw_disable_prefixes', $values ) )
|
||||
{
|
||||
$member->members_bitoptions['bw_disable_prefixes'] = !$values['bw_disable_prefixes'];
|
||||
}
|
||||
}
|
||||
if ( $member->canAccessModule( \IPS\Application\Module::get( 'core', 'members' ) ) )
|
||||
{
|
||||
/* We may be adding a secondary group which DOES have access - we should just use the default in this instance */
|
||||
if ( array_key_exists( 'bw_no_status_update', $values ) )
|
||||
{
|
||||
/* 0 means 'yes can post', 1 means 'no, but user can enable' and 2 means 'no and user cannot re-enable'. */
|
||||
$member->members_bitoptions['bw_no_status_update'] = ( $values['bw_no_status_update'] == 2 ) ? 1 : 0;
|
||||
$member->pp_setting_count_comments = ( $values['bw_no_status_update'] == 0 ) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$member->members_bitoptions['bw_no_status_update'] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $member->canAccessModule( \IPS\Application\Module::get( 'core', 'messaging', 'front' ) ) )
|
||||
{
|
||||
/* We may be adding a secondary group which DOES have access - we should just use the default in this instance */
|
||||
if ( array_key_exists( 'members_disable_pm', $values ) )
|
||||
{
|
||||
$member->members_disable_pm = $values['members_disable_pm'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$member->members_disable_pm = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Removed
|
||||
@@ -8,128 +8,4 @@
|
||||
* @since 28 Sep 2016
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin CP Member Form: MFA
|
||||
*/
|
||||
class _SecurityAnswers // It's called this for backwards compatibility from when we just had security answers
|
||||
{
|
||||
/**
|
||||
* Process Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\Member $member Existing Member
|
||||
* @return void
|
||||
*/
|
||||
public function process( &$form, $member )
|
||||
{
|
||||
/* ACP restriction check */
|
||||
if ( !\IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_mfa' ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get all the fields we'll need */
|
||||
$fields = array();
|
||||
$optOutToggles = array();
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
if ( $handler->isEnabled() and $handler->memberCanUseHandler( $member ) )
|
||||
{
|
||||
foreach ( $handler->acpConfiguration( $member ) as $id => $field )
|
||||
{
|
||||
$fields[] = $field;
|
||||
}
|
||||
$optOutToggles[] = "mfa_{$key}_title";
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't have have any, we need don't to display this tab */
|
||||
if ( !count( $fields ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* We need the opt-out field if the user is in a group which can opt out */
|
||||
if ( \IPS\Settings::i()->mfa_required_groups != '*' and !$member->inGroup( explode( ',', \IPS\Settings::i()->mfa_required_groups ) ) )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'mfa_opt_out_admin', $member->members_bitoptions['security_questions_opt_out'], FALSE, array( 'togglesOff' => $optOutToggles ) ) );
|
||||
}
|
||||
|
||||
/* Now add all the other fields */
|
||||
foreach ( $fields as $id => $field )
|
||||
{
|
||||
if ( $field instanceof \IPS\Helpers\Form\Matrix )
|
||||
{
|
||||
$form->addMatrix( $field->id, $field );
|
||||
}
|
||||
else
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\Member $member The member
|
||||
* @return void
|
||||
*/
|
||||
public function save( $values, &$member )
|
||||
{
|
||||
/* ACP restriction check */
|
||||
if ( !\IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'members', 'member_mfa' ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset the failure count and unlock if necessary */
|
||||
$member->failed_mfa_attempts = 0;
|
||||
$mfaDetails = $member->mfa_details;
|
||||
if ( isset( $mfaDetails['_lockouttime'] ) )
|
||||
{
|
||||
unset( $mfaDetails['_lockouttime'] );
|
||||
$member->mfa_details = $mfaDetails;
|
||||
}
|
||||
|
||||
/* Did we opt out? */
|
||||
if ( isset( $values['mfa_opt_out_admin'] ) )
|
||||
{
|
||||
/* Opt-Out: Disable all handlers */
|
||||
if ( $values['mfa_opt_out_admin'] )
|
||||
{
|
||||
$member->members_bitoptions['security_questions_opt_out'] = TRUE;
|
||||
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
$handler->disableHandlerForMember( $member );
|
||||
}
|
||||
$member->save();
|
||||
}
|
||||
/* Opt-In */
|
||||
else
|
||||
{
|
||||
$member->members_bitoptions['security_questions_opt_out'] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save each of the handlers */
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
if ( $handler->isEnabled() and $handler->memberCanUseHandler( $member ) )
|
||||
{
|
||||
$handler->acpConfigurationSave( $member, $values );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Removed
|
||||
Loaded 100 of 1349 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user