Version 4.7.6
This commit is contained in:
1 parent
8ba7d43898
commit
7b7404e741
1085 files changed
+30590
-7837
No files matched your search
@@ -182,7 +182,7 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
else
|
||||
{
|
||||
\IPS\core\AdminNotification::remove( 'core', 'ConfigurationError', 'failedMail' );
|
||||
\IPS\Db::i()->update( 'core_mail_error_logs', array( 'mlog_notification_sent' => TRUE ) );
|
||||
\IPS\Db::i()->update( 'core_mail_error_logs', [ 'mlog_notification_sent' => TRUE ], [ 'mlog_notification_sent=?', 0 ] );
|
||||
}
|
||||
|
||||
/* Username logins enabled */
|
||||
@@ -195,6 +195,7 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
{
|
||||
\IPS\core\AdminNotification::remove( 'core', 'ConfigurationError', 'usernameLoginEnabled' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -628,7 +629,13 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
return static::STYLE_INFORMATION;
|
||||
}
|
||||
}
|
||||
if ( mb_substr( $this->extra, 0, 12 ) === 'supportAdmin' or $this->extra === 'recommendations' or $this->extra === 'origTables' or $this->extra === 'marketplaceSetup' )
|
||||
|
||||
if( $this->extra === 'recommendations' )
|
||||
{
|
||||
return static::STYLE_ERROR;
|
||||
}
|
||||
|
||||
if ( mb_substr( $this->extra, 0, 12 ) === 'supportAdmin' or $this->extra === 'origTables' or $this->extra === 'marketplaceSetup' )
|
||||
{
|
||||
return static::STYLE_INFORMATION;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ class _License extends \IPS\core\AdminNotification
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('license_error');
|
||||
case 'expireSoon':
|
||||
$licenseKeyData = \IPS\IPS::licenseKey();
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'license_renewal_soon', FALSE, array( 'pluralize' => array( \intval( \IPS\DateTime::create()->diff( \IPS\DateTime::ts( strtotime( $licenseKeyData['expires'] ) ) )->format('%r%a') ) ) ) );
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'license_renewal_soon', FALSE, array( 'pluralize' => array( \intval( \IPS\DateTime::create()->diff( \IPS\DateTime::ts( strtotime( $licenseKeyData['expires'] ), TRUE ) )->format('%r%a') ) ) ) );
|
||||
case 'expired':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('license_expired');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Notification Extension
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
|
||||
* @since 25 Aug 2022
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\AdminNotifications;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Notification Extension
|
||||
*/
|
||||
class _ManualInterventionMessage extends \IPS\core\AdminNotification
|
||||
{
|
||||
/**
|
||||
* @brief Identifier for what to group this notification type with on the settings form
|
||||
*/
|
||||
public static $group = 'system';
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this group compared to others
|
||||
*/
|
||||
public static $groupPriority = 2;
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
|
||||
*/
|
||||
public static $itemPriority = 1;
|
||||
|
||||
/**
|
||||
* Title for settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function settingsTitle()
|
||||
{
|
||||
return 'acp_notification_ManualInterventionMessage';
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a member access this type of notification?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionCheck( \IPS\Member $member )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'applications', 'app_manage' ) OR \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'applications', 'plugins_view' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function mayBeOptional()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this type of notification might recur (controls what options will be available for the email setting)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayRecur()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Title (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'method_check_fail' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Body (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function body()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'advise_removal_of_php8_incompatible_code' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Severity
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function severity()
|
||||
{
|
||||
return static::SEVERITY_HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismissible?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dismissible()
|
||||
{
|
||||
return static::DISMISSIBLE_UNTIL_RECUR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function style()
|
||||
{
|
||||
return $this->severity() === static::SEVERITY_HIGH ? static::STYLE_ERROR : static::STYLE_WARNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick link from popup menu
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function link()
|
||||
{
|
||||
return \IPS\Http\Url::internal( 'app=core&module=support&controller=support&do=methodCheck' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
parent::delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this notification dismiss itself?
|
||||
*
|
||||
* @note This is checked every time the notification shows. Should be lightweight.
|
||||
* @return bool
|
||||
*/
|
||||
public function selfDismiss()
|
||||
{
|
||||
if( \IPS\Db::i()->select( 'count(*)', 'core_applications', [ 'app_requires_manual_intervention=?', 1 ] )->first()
|
||||
OR \IPS\Db::i()->select( 'count(*)', 'core_plugins', [ 'plugin_requires_manual_intervention=?', 1 ] )->first() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,8 @@ class _GoogleMaps
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'google_maps_enable_apis', 'continue' );
|
||||
$form->addHeader('google_maps_choose_features');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'googlemaps', isset( $data['googlemaps'] ) ? $data['googlemaps'] : \IPS\Settings::i()->googlemaps, FALSE, array( 'togglesOn' => array( 'googleApi_jsapi', 'googleApi_staticapi', 'googleApi_geocodeapi' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'googlemaps', isset( $data['googlemaps'] ) ? $data['googlemaps'] : \IPS\Settings::i()->googlemaps, FALSE, array( 'togglesOn' => array( 'googleApi_jsapi', 'googleApi_staticapi', 'googleApi_geocodeapi', 'google_maps_enable_apis_google_maps_static_use_embed' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'google_maps_static_use_embed', isset( $data['google_maps_static_use_embed'] ) ? $data['google_maps_static_use_embed'] : \IPS\Settings::i()->google_maps_static_use_embed, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'googleplacesautocomplete', isset( $data['googleplacesautocomplete'] ) ? $data['googleplacesautocomplete'] : \IPS\Settings::i()->googleplacesautocomplete, FALSE, array( 'togglesOn' => array( 'googleApi_places' ) ) ) );
|
||||
$form->addHeader('google_maps_enable_apis');
|
||||
$form->addMessage('google_maps_create_project_message');
|
||||
@@ -75,13 +76,13 @@ class _GoogleMaps
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( $values['googlemaps'] or $values['googleplacesautocomplete'] )
|
||||
if ( $values['googlemaps'] or $values['googleplacesautocomplete'] or $values['google_maps_static_use_embed'] )
|
||||
{
|
||||
return $values;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'googlemaps' => 0, 'googleplacesautocomplete' => 0 ) );
|
||||
\IPS\Settings::i()->changeValues( array( 'googlemaps' => 0, 'googleplacesautocomplete' => 0, 'google_maps_static_use_embed' => 0 ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=applications&controller=enhancements'), 'saved' );
|
||||
}
|
||||
}
|
||||
@@ -152,6 +153,7 @@ class _GoogleMaps
|
||||
$form->saveAsSettings( array(
|
||||
'googlemaps' => $data['googlemaps'],
|
||||
'googleplacesautocomplete' => $data['googleplacesautocomplete'],
|
||||
'google_maps_static_use_embed' => $data['google_maps_static_use_embed'],
|
||||
'google_maps_api_key' => $values['google_maps_api_key'],
|
||||
'google_maps_api_key_secret' => $data['googlemaps'] ? $values['google_maps_api_key_secret'] : ''
|
||||
) );
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Community Enhancements: Viglink 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 20 June 2013
|
||||
*/
|
||||
|
||||
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: Viglink
|
||||
*/
|
||||
class _Viglink
|
||||
{
|
||||
/**
|
||||
* @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 = "viglink.png";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->enabled = ( \IPS\Settings::i()->viglink_enabled );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
'help' => array(
|
||||
'title' => 'learn_more',
|
||||
'icon' => 'question-circle',
|
||||
'link' => \IPS\Http\Url::ips( 'docs/viglink' ),
|
||||
'target' => '_blank'
|
||||
)
|
||||
);
|
||||
|
||||
if ( \IPS\Settings::i()->viglink_api_key )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'viglink_enabled', \IPS\Settings::i()->viglink_enabled, FALSE, array( 'togglesOn' => array( 'viglink_api_key', 'viglink_subid', 'viglink_groups', 'viglink_norewrite' ) ) ) );
|
||||
|
||||
if ( !\IPS\Settings::i()->viglink_subid )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'viglink_api_key', \IPS\Settings::i()->viglink_api_key, FALSE, array(), NULL, NULL, NULL, 'viglink_api_key' ) );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'viglink_groups', ( \IPS\Settings::i()->viglink_groups == 'all' ) ? 'all' : explode( ',', \IPS\Settings::i()->viglink_groups ), FALSE, array( 'options' => \IPS\Member\Group::groups(), 'parse' => 'normal', 'multiple' => true, 'unlimited' => 'all', 'unlimitedLang' => 'all_groups', 'impliedUnlimited' => TRUE ), NULL, NULL, NULL, 'viglink_groups' ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'viglink_norewrite', explode( ',', \IPS\Settings::i()->viglink_norewrite ), FALSE, array( 'options' => \IPS\Member\Group::groups(), 'parse' => 'normal', 'multiple' => true ), NULL, NULL, NULL, 'viglink_norewrite' ) );
|
||||
|
||||
if ( $values = $form->values( TRUE ) )
|
||||
{
|
||||
if ( !$values['viglink_enabled'] )
|
||||
{
|
||||
$values['viglink_api_key'] = '';
|
||||
}
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplog__enhancements_edited', array( 'enhancements__core_Viglink' => TRUE ) );
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['actions']['signup'] = array(
|
||||
'title' => 'viglink_account_type',
|
||||
'icon' => 'external-link-square',
|
||||
'link' => \IPS\Http\Url::ips('docs/viglink_account'),
|
||||
'target' => '_blank'
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'enhancements__core_Viglink', $form );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'viglink_api_key', NULL, FALSE, array(), function( $val ){
|
||||
if( !$val && \IPS\Request::i()->viglink_account_type == 'existing' )
|
||||
{
|
||||
throw new \InvalidArgumentException("required");
|
||||
}
|
||||
}, NULL, NULL, 'viglink_api_key' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$values['viglink_subid'] = '';
|
||||
$values['viglink_enabled'] = TRUE;
|
||||
unset( $values['viglink_account_type'] );
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplog__enhancements_edited', array( 'enhancements__core_Viglink' => TRUE ) );
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
}
|
||||
|
||||
\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\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\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
|
||||
{
|
||||
throw new \DomainException;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,21 +26,27 @@ class _Zapier
|
||||
/**
|
||||
* Get the permissions needed for the Zapier API key
|
||||
*
|
||||
* Since 4.7.1 we don't need to call any other methods while the upgrade, just adjust the permission here, everything else will be handled automatically.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function apiKeyPermissions()
|
||||
{
|
||||
$return = array(
|
||||
'core/clubs/GETindex' => array( 'access' => TRUE ),
|
||||
'core/clubs/GETitem' => array( 'access' => TRUE ),
|
||||
'core/groups/GETindex' => array( 'access' => TRUE ),
|
||||
'core/hello/GETindex' => array( 'access' => TRUE ),
|
||||
'core/members/GETindex' => array( 'access' => TRUE ),
|
||||
'core/members/GETitem' => array( 'access' => TRUE ),
|
||||
'core/members/POSTindex' => array( 'access' => TRUE ),
|
||||
'core/members/POSTitem' => array( 'access' => TRUE ),
|
||||
'core/webhooks/POSTindex' => array( 'access' => TRUE ),
|
||||
'core/webhooks/DELETEitem' => array( 'access' => TRUE ),
|
||||
'core/clubs/GETindex' => array( 'access' => TRUE ),
|
||||
'core/clubs/GETitem' => array( 'access' => TRUE ),
|
||||
'core/groups/GETindex' => array( 'access' => TRUE ),
|
||||
'core/hello/GETindex' => array( 'access' => TRUE ),
|
||||
'core/members/GETindex' => array( 'access' => TRUE ),
|
||||
'core/members/GETitem' => array( 'access' => TRUE ),
|
||||
'core/members/POSTindex' => array( 'access' => TRUE ),
|
||||
'core/members/POSTitem_secgroup' => array( 'access' => TRUE ),
|
||||
'core/members/DELETEitem_secgroup' => array( 'access' => TRUE ),
|
||||
'core/members/POSTitem' => array( 'access' => TRUE ),
|
||||
'core/webhooks/POSTindex' => array( 'access' => TRUE ),
|
||||
'core/webhooks/DELETEitem' => array( 'access' => TRUE ),
|
||||
'core/promotions/GETindex' => array( 'access' => TRUE ),
|
||||
'core/promotions/GETitem' => array( 'access' => TRUE ),
|
||||
);
|
||||
|
||||
if ( \IPS\Application::appIsEnabled('forums') )
|
||||
@@ -309,4 +315,32 @@ class _Zapier
|
||||
throw new \DomainException( 'zapier_error_api' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the Zapier REST Key all required permissions.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function rebuildRESTApiPermissions()
|
||||
{
|
||||
/* Rebuild Zapier REST API Key Permissions */
|
||||
if( \IPS\Settings::i()->zapier_api_key )
|
||||
{
|
||||
try
|
||||
{
|
||||
$apiKey = \IPS\Api\Key::load( \IPS\Settings::i()->zapier_api_key );
|
||||
|
||||
$correctPermissions = json_encode( static::apiKeyPermissions() );
|
||||
if ( $apiKey->permissions != $correctPermissions )
|
||||
{
|
||||
$apiKey->permissions = $correctPermissions;
|
||||
$apiKey->save();
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,11 @@ class _Clubs
|
||||
*/
|
||||
public $classes = array();
|
||||
|
||||
/**
|
||||
* @brief Can be shown in similar content
|
||||
*/
|
||||
public $similarContent = FALSE;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
||||
@@ -28,6 +28,11 @@ class _Status
|
||||
*/
|
||||
public $classes = array();
|
||||
|
||||
/**
|
||||
* @brief Can be shown in similar content
|
||||
*/
|
||||
public $similarContent = FALSE;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
||||
@@ -136,22 +136,24 @@ class _Attachment
|
||||
|
||||
if ( isset( static::$loadedExtensions[ $map['location_key'] ] ) )
|
||||
{
|
||||
try
|
||||
|
||||
if( method_exists( static::$loadedExtensions[$map['location_key']], 'attachmentLookup'))
|
||||
{
|
||||
$url = static::$loadedExtensions[ $map['location_key'] ]->attachmentLookup( $map['id1'], $map['id2'], $map['id3'] );
|
||||
try {
|
||||
$url = static::$loadedExtensions[$map['location_key']]->attachmentLookup($map['id1'], $map['id2'], $map['id3']);
|
||||
|
||||
/* Test url() method to prevent BadMethodCallException from the template below - an attachment may be
|
||||
located within a Node class that doesn't support urls, such as CMS Blocks. */
|
||||
/* Test url() method to prevent BadMethodCallException from the template below - an attachment may be
|
||||
located within a Node class that doesn't support urls, such as CMS Blocks. */
|
||||
|
||||
if( $url instanceof \IPS\Content or $url instanceof \IPS\Node\Model )
|
||||
{
|
||||
$url->url();
|
||||
if ($url instanceof \IPS\Content or $url instanceof \IPS\Node\Model){
|
||||
$url->url();
|
||||
}
|
||||
|
||||
static::$locations[$attachId][] = $url;
|
||||
} catch (\LogicException $e) {
|
||||
} catch (\BadMethodCallException $e) {
|
||||
}
|
||||
|
||||
static::$locations[ $attachId ][] = $url;
|
||||
}
|
||||
catch ( \LogicException $e ) { }
|
||||
catch ( \BadMethodCallException $e ){ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,50 +71,60 @@ class _Achievements
|
||||
/* If all *available* options are selected, we want to choose 'all' for consistency on create vs edit */
|
||||
$_options = array_keys( $ranks['options'] );
|
||||
|
||||
return array(
|
||||
$return = array(
|
||||
new \IPS\Helpers\Form\Custom( 'mf_points', array( 0 => isset( $criteria['achievement_points_operator'] ) ? $criteria['achievement_points_operator'] : NULL, 1 => isset( $criteria['achievement_points_value'] ) ? $criteria['achievement_points_value'] : NULL ), FALSE, array(
|
||||
'getHtml' => function( $element )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'forms', 'core' )->select( "{$element->name}[0]", $element->value[0], $element->required, array(
|
||||
'any' => \IPS\Member::loggedIn()->language()->addToStack('any'),
|
||||
'gt' => \IPS\Member::loggedIn()->language()->addToStack('gt'),
|
||||
'lt' => \IPS\Member::loggedIn()->language()->addToStack('lt'),
|
||||
'eq' => \IPS\Member::loggedIn()->language()->addToStack('exactly'),
|
||||
),
|
||||
FALSE,
|
||||
NULL,
|
||||
FALSE,
|
||||
array(
|
||||
'any' => array(),
|
||||
'gt' => array( 'elNumber_' . $element->name . '-qty' ),
|
||||
'lt' => array( 'elNumber_' . $element->name . '-qty' ),
|
||||
'eq' => array( 'elNumber_' . $element->name . '-qty' ),
|
||||
) )
|
||||
. ' '
|
||||
. \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->number( "{$element->name}[1]", $element->value[1], $element->required, NULL, FALSE, NULL, NULL, NULL, 0, NULL, FALSE, NULL, array(), array(), array(), $element->name . '-qty' );
|
||||
'any' => \IPS\Member::loggedIn()->language()->addToStack('any'),
|
||||
'gt' => \IPS\Member::loggedIn()->language()->addToStack('gt'),
|
||||
'lt' => \IPS\Member::loggedIn()->language()->addToStack('lt'),
|
||||
'eq' => \IPS\Member::loggedIn()->language()->addToStack('exactly'),
|
||||
),
|
||||
FALSE,
|
||||
NULL,
|
||||
FALSE,
|
||||
array(
|
||||
'any' => array(),
|
||||
'gt' => array( 'elNumber_' . $element->name . '-qty' ),
|
||||
'lt' => array( 'elNumber_' . $element->name . '-qty' ),
|
||||
'eq' => array( 'elNumber_' . $element->name . '-qty' ),
|
||||
) )
|
||||
. ' '
|
||||
. \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->number( "{$element->name}[1]", $element->value[1], $element->required, NULL, FALSE, NULL, NULL, NULL, 0, NULL, FALSE, NULL, array(), array(), array(), $element->name . '-qty' );
|
||||
}
|
||||
), NULL, NULL, NULL, 'mp_points' ),
|
||||
new \IPS\Helpers\Form\YesNo( 'mf_badges_choose', ( isset( $criteria['achievement_badges'] ) AND $criteria['achievement_badges'] != 'ignore' ), FALSE, array(
|
||||
), NULL, NULL, NULL, 'mp_points' )
|
||||
);
|
||||
|
||||
if( \count( $badges['options'] ) )
|
||||
{
|
||||
$return[] = new \IPS\Helpers\Form\YesNo( 'mf_badges_choose', ( !empty( $criteria['achievement_badges'] ) AND $criteria['achievement_badges'] !== 'ignore' ), FALSE, array(
|
||||
'togglesOn' => [ 'mf_badges' ]
|
||||
), NULL, NULL, NULL, 'mf_badges_choose' ),
|
||||
new \IPS\Helpers\Form\CheckboxSet( 'mf_badges', ( isset( $criteria['achievement_badges'] ) AND $criteria['achievement_badges'] != 'ignore' ) ? explode( ',', $criteria['achievement_badges'] ) : [], FALSE, array(
|
||||
), NULL, NULL, NULL, 'mf_badges_choose' );
|
||||
$return[] = new \IPS\Helpers\Form\CheckboxSet( 'mf_badges', ( isset( $criteria['achievement_badges'] ) AND $criteria['achievement_badges'] != 'ignore' ) ? ( $criteria['achievement_badges'] === 'all' ? 'all' : explode( ',', $criteria['achievement_badges'] ) ) : [], FALSE, array(
|
||||
'options' => $badges['options'],
|
||||
'multiple' => TRUE,
|
||||
'unlimited' => 'all',
|
||||
'unlimitedLang' => 'mf_achievements_all_badges',
|
||||
'impliedUnlimited' => TRUE
|
||||
), NULL, NULL, NULL, 'mf_badges' ),
|
||||
new \IPS\Helpers\Form\YesNo( 'mf_ranks_choose', ( isset( $criteria['achievement_ranks'] ) AND $criteria['achievement_ranks'] != 'ignore' ), FALSE, array(
|
||||
), NULL, NULL, NULL, 'mf_badges' );
|
||||
}
|
||||
|
||||
if( \count( $ranks['options'] ) )
|
||||
{
|
||||
$return[] = new \IPS\Helpers\Form\YesNo( 'mf_ranks_choose', ( !empty( $criteria['achievement_ranks'] ) AND $criteria['achievement_ranks'] !== 'ignore' ), FALSE, array(
|
||||
'togglesOn' => [ 'mf_ranks' ]
|
||||
), NULL, NULL, NULL, 'mf_ranks_choose' ),
|
||||
new \IPS\Helpers\Form\CheckboxSet( 'mf_ranks', ( isset( $criteria['achievement_ranks'] ) AND $criteria['achievement_ranks'] != 'ignore' ) ? explode( ',', $criteria['achievement_ranks'] ) : [], FALSE, array(
|
||||
), NULL, NULL, NULL, 'mf_ranks_choose' );
|
||||
$return[] = new \IPS\Helpers\Form\CheckboxSet( 'mf_ranks', ( isset( $criteria['achievement_ranks'] ) AND $criteria['achievement_ranks'] !== 'ignore' ) ? ( $criteria['achievement_ranks'] === 'all' ? 'all' : explode( ',', $criteria['achievement_ranks'] ) ) : [], FALSE, array(
|
||||
'options' => $ranks['options'],
|
||||
'multiple' => TRUE,
|
||||
'unlimited' => 'all',
|
||||
'unlimitedLang' => 'mf_achievements_all_ranks',
|
||||
'impliedUnlimited' => TRUE
|
||||
), NULL, NULL, NULL, 'mf_ranks' )
|
||||
);
|
||||
), NULL, NULL, NULL, 'mf_ranks' );
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,8 +139,8 @@ class _Achievements
|
||||
return array(
|
||||
'achievement_points_operator' => $post['mf_points'][0],
|
||||
'achievement_points_value' => $post['mf_points'][1],
|
||||
'achievement_badges' => ( $post['mf_badges_choose'] ) ? implode( ',', $post['mf_badges'] ) : 'ignore',
|
||||
'achievement_ranks' => ( $post['mf_ranks_choose'] ) ? implode( ',', $post['mf_ranks'] ) : 'ignore'
|
||||
'achievement_badges' => ( !empty( $post['mf_badges_choose'] ) ) ? ( $post['mf_badges'] == 'all' ? 'all' : implode( ',', $post['mf_badges'] ) ) : 'ignore',
|
||||
'achievement_ranks' => ( !empty( $post['mf_ranks_choose'] ) ) ? ( $post['mf_ranks'] == 'all' ? 'all' : implode( ',', $post['mf_ranks'] ) ) : 'ignore',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -161,7 +171,16 @@ class _Achievements
|
||||
|
||||
if ( $data['achievement_badges'] != 'ignore' )
|
||||
{
|
||||
$badgeSelect = \IPS\Db::i()->select( 'member', 'core_member_badges', \IPS\Db::i()->in( 'badge', explode( ',', $data['achievement_badges'] ) ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_DISTINCT );
|
||||
if( $data['achievement_ranks'] == 'all' )
|
||||
{
|
||||
$badgeWhere = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$badgeWhere = \IPS\Db::i()->in( 'badge', explode( ',', $data['achievement_badges'] ) );
|
||||
}
|
||||
|
||||
$badgeSelect = \IPS\Db::i()->select( 'member', 'core_member_badges', $badgeWhere, NULL, NULL, NULL, NULL, \IPS\Db::SELECT_DISTINCT );
|
||||
$where[] = 'core_members.member_id IN(' . $badgeSelect . ')';
|
||||
}
|
||||
|
||||
@@ -170,7 +189,16 @@ class _Achievements
|
||||
$ranks = \IPS\core\Achievements\Rank::getStore();
|
||||
$rankWhere = [];
|
||||
|
||||
foreach( explode( ',', $data['achievement_ranks'] ) as $val )
|
||||
if( $data['achievement_ranks'] == 'all' )
|
||||
{
|
||||
$rankIds = array_keys( $ranks );
|
||||
}
|
||||
else
|
||||
{
|
||||
$rankIds = explode( ',', $data['achievement_ranks'] );
|
||||
}
|
||||
|
||||
foreach( $rankIds as $val )
|
||||
{
|
||||
$minPoints = 0;
|
||||
$maxPoints = 0;
|
||||
@@ -263,7 +291,16 @@ class _Achievements
|
||||
$ranks = \IPS\core\Achievements\Rank::getStore();
|
||||
$pass = FALSE;
|
||||
|
||||
foreach( explode( ',', $filters['achievement_ranks'] ) as $val )
|
||||
if( $filters['achievement_ranks'] == 'all' )
|
||||
{
|
||||
$rankIds = array_keys( $ranks );
|
||||
}
|
||||
else
|
||||
{
|
||||
$rankIds = explode( ',', $filters['achievement_ranks'] );
|
||||
}
|
||||
|
||||
foreach( $rankIds as $val )
|
||||
{
|
||||
$minPoints = 0;
|
||||
$maxPoints = 0;
|
||||
|
||||
@@ -90,8 +90,25 @@ class _ProfileFields
|
||||
}
|
||||
) );
|
||||
break;
|
||||
case 'IPS\Helpers\Form\Checkbox':
|
||||
$options = array(
|
||||
'' => 'any_value',
|
||||
1 => 'checked',
|
||||
0 => 'unchecked'
|
||||
);
|
||||
$helper = new \IPS\Helpers\Form\Select( $langKey, $criteria[ $langKey ] ?? NULL, FALSE, array( 'options' => $options ) );
|
||||
break;
|
||||
case 'IPS\Helpers\Form\YesNo':
|
||||
$options = array(
|
||||
'' => 'any_value',
|
||||
1 => 'yes',
|
||||
0 => 'no'
|
||||
);
|
||||
$helper = new \IPS\Helpers\Form\Select( $langKey, $criteria[ $langKey ] ?? NULL, FALSE, array( 'options' => $options ) );
|
||||
break;
|
||||
case 'IPS\Helpers\Form\Select':
|
||||
case 'IPS\Helpers\Form\Radio':
|
||||
case 'IPS\Helpers\Form\CheckboxSet':
|
||||
if( $field['pf_multiple'] )
|
||||
{
|
||||
$options = array();
|
||||
@@ -174,7 +191,7 @@ class _ProfileFields
|
||||
$helper = NULL;
|
||||
$langKey = "core_pfield_{$id}";
|
||||
|
||||
if( !isset( $data[ $langKey ] ) OR !$data[ $langKey ] )
|
||||
if( empty( $data[ $langKey ] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -217,8 +234,13 @@ class _ProfileFields
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'IPS\Helpers\Form\Checkbox':
|
||||
case 'IPS\Helpers\Form\YesNo':
|
||||
$where[] = "field_{$id}='" . $data[ $langKey ] . "'";
|
||||
break;
|
||||
case 'IPS\Helpers\Form\Select':
|
||||
case 'IPS\Helpers\Form\Radio':
|
||||
case 'IPS\Helpers\Form\CheckboxSet':
|
||||
if ( isset( $field['pf_multiple'] ) AND $field['pf_multiple'] == TRUE )
|
||||
{
|
||||
$where[] = \IPS\Db::i()->findInSet( 'field_' . $id, $data[ $langKey ] );
|
||||
|
||||
@@ -30,7 +30,12 @@ class _System
|
||||
*/
|
||||
public function onCreateAccount( $member )
|
||||
{
|
||||
\IPS\Api\Webhook::fire( 'member_create', $member );
|
||||
\IPS\Api\Webhook::fire( 'member_create', $member, $member->webhookFilters() );
|
||||
|
||||
if( $member->id AND $member->completed )
|
||||
{
|
||||
\IPS\Api\Webhook::fire( 'member_registration_complete', $member, $member->webhookFilters() );
|
||||
}
|
||||
|
||||
if ( \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation === 'front' and isset( \IPS\Request::i()->cookie[ 'referred_by' ] ) )
|
||||
{
|
||||
@@ -149,7 +154,6 @@ class _System
|
||||
|
||||
/* Delete duplicate stuff */
|
||||
\IPS\Db::i()->delete( 'core_item_markers', array( 'item_member_id=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->delete( 'core_members_feature_seen', array( 'member_id=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->delete( 'core_security_answers', array( 'answer_member_id=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->delete( 'core_sessions', array( 'member_id=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->delete( 'core_sys_cp_sessions', array( 'session_member_id=?', $member2->member_id ) );
|
||||
@@ -241,6 +245,8 @@ class _System
|
||||
|
||||
/* Rebuild permission array */
|
||||
$member->rebuildPermissionArray();
|
||||
|
||||
\IPS\Api\Webhook::fire( 'member_merged', ['kept' => $member->apiOutput(), 'removed' => $member2->apiOutput()] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,7 +314,6 @@ class _System
|
||||
array( 'core_member_status_updates', 'status_author_id' ),
|
||||
array( 'core_member_status_replies', 'reply_member_id' ),
|
||||
array( 'core_login_links', 'token_member' ),
|
||||
array( 'core_members_feature_seen', 'member_id' ),
|
||||
array( 'core_saved_charts', 'chart_member' ),
|
||||
array( 'core_members_known_devices', 'member_id' ),
|
||||
array( 'core_members_known_ip_addresses', 'member_id' ),
|
||||
@@ -368,7 +373,7 @@ class _System
|
||||
$member->deletePhoto();
|
||||
$member->coverPhoto()->delete();
|
||||
|
||||
\IPS\Api\Webhook::fire( 'member_delete', $member );
|
||||
\IPS\Api\Webhook::fire( 'member_delete', $member, $member->webhookFilters() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -407,6 +412,14 @@ class _System
|
||||
$member->members_bitoptions['profile_completed'] = 0;
|
||||
}
|
||||
|
||||
foreach( $member::$changesToSkipForMemberEditWebhooks as $fieldToRemove )
|
||||
{
|
||||
if( \in_array($fieldToRemove, $changes ) )
|
||||
{
|
||||
unset( $changes[$fieldToRemove] );
|
||||
}
|
||||
}
|
||||
|
||||
if( \count( $changes ) )
|
||||
{
|
||||
$params = [
|
||||
@@ -414,7 +427,7 @@ class _System
|
||||
'changes' => $changes
|
||||
];
|
||||
|
||||
\IPS\Api\Webhook::fire( 'member_edited', $params );
|
||||
\IPS\Api\Webhook::fire( 'member_edited', $params, $member->webhookFilters() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,17 +169,36 @@ class _FeaturedComments
|
||||
'note' => isset( $comment['note'] ) ? $comment['note'] : '',
|
||||
);
|
||||
$commentIds[] = $comment['comment'];
|
||||
|
||||
|
||||
$memberIds[ $comment['featured_by'] ][] = $comment['comment'];
|
||||
}
|
||||
|
||||
$commentClass = $item::$commentClass;
|
||||
$commentIdField = $commentClass::$databaseColumnId;
|
||||
|
||||
if ( isset( $commentClass::$databaseColumnMap['hidden'] ) )
|
||||
{
|
||||
$col = $commentClass::$databaseColumnMap['hidden'];
|
||||
}
|
||||
else if ( isset( $commentClass::$databaseColumnMap['approved'] ) )
|
||||
{
|
||||
$col = $commentClass::$databaseColumnMap['approved'];
|
||||
}
|
||||
|
||||
$softDeleted = [];
|
||||
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', $commentClass::$databaseTable, array( \IPS\Db::i()->in( $commentClass::$databasePrefix . $commentIdField, $commentIds ) ), $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['date'] . " DESC" ), $commentClass ) AS $row )
|
||||
{
|
||||
$comments[ $row->$commentIdField ]['comment'] = $row;
|
||||
if( $row->$col < 0 )
|
||||
{
|
||||
unset( $comments[$row->$commentIdField] );
|
||||
$softDeleted[] = $row->$commentIdField;
|
||||
}
|
||||
else
|
||||
{
|
||||
$comments[ $row->$commentIdField ]['comment'] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* And finally, who featured them */
|
||||
if ( \count( $memberIds ) )
|
||||
{
|
||||
@@ -187,11 +206,16 @@ class _FeaturedComments
|
||||
{
|
||||
foreach( $memberIds[ $m->member_id ] AS $attach )
|
||||
{
|
||||
if( \in_array( $attach, $softDeleted ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$comments[ $attach ]['featured_by'] = $m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* And off we go! */
|
||||
return $comments;
|
||||
}
|
||||
@@ -228,4 +252,4 @@ class _FeaturedComments
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class _Alerts
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$alert = \IPS\Core\Alerts\Alert::_createFromForm( $values, $current );
|
||||
$alert = \IPS\core\Alerts\Alert::_createFromForm( $values, $current );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=core&module=modcp&tab=alerts", 'front', 'modcp_alerts' ) );
|
||||
}
|
||||
|
||||
@@ -72,47 +72,16 @@ class _Reports extends \IPS\Content\Controller
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
{
|
||||
$where = [];
|
||||
|
||||
{
|
||||
/* Make sure we're only loading reports where we have permission to view the content */
|
||||
$classWhere = [];
|
||||
$classBinds = [];
|
||||
$viewPermIds = iterator_to_array( \IPS\Db::i()->select( 'perm_id', 'core_permission_index', \IPS\Db::i()->findInSet( 'perm_view', \IPS\Member::loggedIn()->permissionArray() ) . " OR perm_view='*'" ) );
|
||||
$permIds = [];
|
||||
foreach ( array_merge( [ 'IPS\core\Messenger\Conversation', 'IPS\core\Messenger\Message' ], array_values( \IPS\Content::routedClasses( FALSE, TRUE ) ) ) as $class )
|
||||
{
|
||||
$workingClass = $class;
|
||||
if ( isset( $workingClass::$itemClass ) )
|
||||
{
|
||||
$workingClass = $workingClass::$itemClass;
|
||||
}
|
||||
if ( isset( $workingClass::$containerNodeClass ) )
|
||||
{
|
||||
$workingClass = $workingClass::$containerNodeClass;
|
||||
}
|
||||
if ( isset( $workingClass::$permissionMap ) and isset( $workingClass::$permissionMap['read'] ) and $workingClass::$permissionMap['read'] !== 'view' )
|
||||
{
|
||||
if ( !isset( $permIds[ $workingClass::$permissionMap['read'] ] ) )
|
||||
{
|
||||
$permIds[ $workingClass::$permissionMap['read'] ] = iterator_to_array( \IPS\Db::i()->select( 'perm_id', 'core_permission_index', \IPS\Db::i()->findInSet( 'perm_' . $workingClass::$permissionMap['read'], \IPS\Member::loggedIn()->permissionArray() ) . " OR perm_" . $workingClass::$permissionMap['read'] . "='*'" ) );
|
||||
}
|
||||
|
||||
$classWhere[] = "( class='" . str_replace( '\\', '\\\\', $class ) . "' AND ( perm_id IN(" . implode( ',', array_intersect( $viewPermIds, $permIds[ $workingClass::$permissionMap['read'] ] ) ) . ") ) OR perm_id IS NULL )";
|
||||
}
|
||||
else
|
||||
{
|
||||
$classWhere[] = "( class='" . str_replace( '\\', '\\\\', $class ) . "' AND ( perm_id IN(" . implode( ',', $viewPermIds ) . ") ) OR perm_id IS NULL )";
|
||||
}
|
||||
}
|
||||
$where[] = array( '(' . implode( ' OR ', $classWhere ) . ')' );
|
||||
|
||||
$where = [ \IPS\core\Reports\Report::where() ];
|
||||
|
||||
/* Make sure we're loading the correct statuses */
|
||||
if( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->overview ) )
|
||||
{
|
||||
$where[] = array( "status IN( 1,2 )" );
|
||||
}
|
||||
|
||||
|
||||
/* Create table */
|
||||
$table = new \IPS\Helpers\Table\Content( '\IPS\core\Reports\Report', \IPS\Http\Url::internal( 'app=core&module=modcp&controller=modcp&tab=reports', NULL, 'modcp_reports' ), $where );
|
||||
$table->sortBy = $table->sortBy ?: 'first_report_date';
|
||||
@@ -121,8 +90,38 @@ class _Reports extends \IPS\Content\Controller
|
||||
/* Title is a special case in the Report center class that isn't available in the core_rc_index table so attempting to sort on it throws an error and does nothing */
|
||||
unset( $table->sortOptions['title'] );
|
||||
|
||||
$table->filters = array( 'report_status_1' => array( 'status=1' ), 'report_status_2' => array( 'status=2' ), 'report_status_3' => array( 'status=3' ) );
|
||||
|
||||
$table->filters = [
|
||||
'filter_report_status_1' => array( 'status=1' )
|
||||
];
|
||||
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter') as $app => $classes )
|
||||
{
|
||||
$appKey = explode('_', $app)[0];
|
||||
$apps[ $appKey ] = $classes;
|
||||
}
|
||||
|
||||
foreach( $apps as $appKey => $data )
|
||||
{
|
||||
$classes = $data->classes;
|
||||
foreach( $classes as $class )
|
||||
{
|
||||
if ( is_subclass_of( $class, "IPS\Content\Item" ) )
|
||||
{
|
||||
$classes[] = $class::$commentClass;
|
||||
|
||||
if ( isset( $class::$reviewClass ) )
|
||||
{
|
||||
$classes[] = $class::$reviewClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$table->filters['filter_report_status_1_' . $appKey ] = [ 'status=1 and ' . \IPS\Db::i()->in( 'class', $classes ) ];
|
||||
\IPS\Member::loggedIn()->language()->words[ 'filter_report_status_1_' . $appKey ] = \IPS\Member::loggedIn()->language()->addToStack( 'filter_report_status_1_app', NULL, [ 'sprintf' => [ \IPS\Application::applications()[ $appKey ]->_title ] ] );
|
||||
}
|
||||
|
||||
$table->filters['filter_report_status_2'] = [ 'status=2' ];
|
||||
$table->filters['filter_report_status_3'] = [ 'status=3' ];
|
||||
$table->title = \IPS\Member::loggedIn()->language()->addToStack( 'report_center_header' );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->overview ) )
|
||||
@@ -137,7 +136,7 @@ class _Reports extends \IPS\Content\Controller
|
||||
return \IPS\Theme::i()->getTemplate( 'modcp' )->reportList( (string) $table );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* View a report
|
||||
*
|
||||
|
||||
@@ -311,7 +311,82 @@ class _MyStuff
|
||||
'author' => ( \IPS\Member::loggedIn()->group['gbw_view_reps'] ) ? \IPS\Member::load( $first['member_id'] ) : new \IPS\Member
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse notification: parse_rest_new_likes
|
||||
*
|
||||
* @param \IPS\Notification\Inline $notification The notification
|
||||
* @param bool $htmlEscape TRUE to escape HTML in title
|
||||
* @return array|NULL
|
||||
* @code
|
||||
return array(
|
||||
'title' => "Mark has replied to A Topic", // The notification title
|
||||
'url' => \IPS\Http\Url::internal( ... ), // The URL the notification should link to
|
||||
'content' => "Lorem ipsum dolar sit", // [Optional] Any appropriate content. Do not format this like an email where the text
|
||||
// explains what the notification is about - just include any appropriate content.
|
||||
// For example, if the notification is about a post, set this as the body of the post.
|
||||
'author' => \IPS\Member::load( 1 ), // [Optional] The user whose photo should be displayed for this notification
|
||||
);
|
||||
* @endcode
|
||||
*/
|
||||
public function parse_rest_new_likes( $notification, $htmlEscape=TRUE )
|
||||
{
|
||||
$comment = $notification->item;
|
||||
|
||||
if ( !$comment )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
$item = ( $comment instanceof \IPS\Content\Item ) ? $comment : $comment->item();
|
||||
$idColumn = $comment::$databaseColumnId;
|
||||
|
||||
$between = time();
|
||||
try
|
||||
{
|
||||
/* Is there a newer notification for this item? */
|
||||
$between = \IPS\Db::i()->select( 'sent_time', 'core_notifications', array( '`member`=? AND item_id=? AND item_class=? AND sent_time>? AND notification_key=?', \IPS\Member::loggedIn()->member_id, $comment->$idColumn, \get_class( $comment ), $notification->sent_time->getTimestamp(), $notification->notification_key ) )->first();
|
||||
}
|
||||
catch( \UnderflowException $e ) {}
|
||||
|
||||
$likers = \IPS\Db::i()->select( 'DISTINCT member_id, rep_date', 'core_reputation_index', array( 'app=? AND type=? AND rep_date>=? AND rep_date<? AND type_id=?', $comment::$application, $comment::reactionType(), $notification->sent_time->getTimestamp(), $between, $comment->$idColumn ), 'rep_date desc' );
|
||||
|
||||
$names = array();
|
||||
$first = array();
|
||||
foreach( $likers AS $member )
|
||||
{
|
||||
if( empty( $first ) )
|
||||
{
|
||||
$first = $member;
|
||||
}
|
||||
|
||||
if ( \count( $names ) > 2 )
|
||||
{
|
||||
$names[] = \IPS\Member::loggedIn()->language()->addToStack( 'x_others', FALSE, array( 'pluralize' => array( \count( $likers ) - 3 ) ) );
|
||||
break;
|
||||
}
|
||||
$names[] = \IPS\Member::load( $member['member_id'] )->name;
|
||||
}
|
||||
|
||||
if( empty( $first ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
return array(
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack( \IPS\Content\Reaction::isLikeMode() ? 'notification__new_likes' : 'notification__new_react', FALSE, array(
|
||||
'pluralize' => array( \count( $likers ) ),
|
||||
( $htmlEscape ? 'sprintf' : 'htmlsprintf' ) => array(
|
||||
\IPS\Member::loggedIn()->language()->formatList( $names ),
|
||||
mb_strtolower( $comment->indefiniteArticle() )
|
||||
)
|
||||
) ) . ' ' . $item->mapped('title'),
|
||||
'url' => ( $comment instanceof \IPS\Content\Comment ) ? $comment->url('find') : $comment->url(),
|
||||
'content' => $comment->truncated(),
|
||||
'author' => \IPS\Member::load( $first['member_id'] )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse notification for mobile: new_likes
|
||||
*
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Template Plugin
|
||||
* @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 01 Sep 2022
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\OutputPlugins;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template Plugin
|
||||
*/
|
||||
class _GraphQl
|
||||
{
|
||||
/**
|
||||
* @brief Can be used when compiling CSS
|
||||
*/
|
||||
public static $canBeUsedInCss = FALSE;
|
||||
|
||||
/**
|
||||
* Run the plug-in
|
||||
*
|
||||
* @param string $data The initial data from the tag
|
||||
* @param array $options Array of options
|
||||
* @return string Code to eval
|
||||
*/
|
||||
public static function runPlugin( $data, $options )
|
||||
{
|
||||
if( !isset( $options['variables']))
|
||||
{
|
||||
$options['variables'] = [];
|
||||
}
|
||||
|
||||
$response = \IPS\Api\GraphQL::execute($data, $options['variables']);
|
||||
|
||||
if( isset( $response['data']))
|
||||
{
|
||||
return "'" . json_encode($response['data'] ) . "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,18 +107,30 @@ class _ProfileFields
|
||||
/* Init Chart */
|
||||
$pieBarData = array();
|
||||
$results = array();
|
||||
$limit = 15;
|
||||
|
||||
/* Add Rows */
|
||||
$select = \IPS\Db::i()->select( 'COUNT(*) as total, field_' . $field['pf_id'], 'core_pfields_content', NULL, NULL, NULL, 'field_' . $field['pf_id'] );
|
||||
$select = \IPS\Db::i()->select( 'COUNT(*) as total, field_' . $field['pf_id'], 'core_pfields_content', NULL, 'total DESC', NULL, 'field_' . $field['pf_id'] );
|
||||
$total = 0;
|
||||
|
||||
$i = 0;
|
||||
foreach( $select as $row )
|
||||
{
|
||||
if( $row['field_' . $field['pf_id'] ] !== NULL )
|
||||
{
|
||||
$total += $row['total'];
|
||||
|
||||
$results[ $row['field_' . $field['pf_id'] ] ] = $row;
|
||||
if( $i <= $limit )
|
||||
{
|
||||
$results[ $row['field_' . $field['pf_id'] ] ] = $row;
|
||||
}
|
||||
else
|
||||
{
|
||||
$otherKey = \IPS\Member::loggedIn()->language()->addToStack('stats_overview_others');
|
||||
$results[$otherKey] = [ 'total' => 5 ];
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +177,7 @@ class _ProfileFields
|
||||
elseif( $field['pf_content'] )
|
||||
{
|
||||
$options = json_decode( $field['pf_content'], TRUE );
|
||||
$options = array_keys( $results);
|
||||
|
||||
foreach( $options as $k => $v )
|
||||
{
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Background Task
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
|
||||
* @since 27 Jun 2022
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _BuildTimeToRank
|
||||
{
|
||||
/**
|
||||
* @brief Number of topics to build per cycle
|
||||
*/
|
||||
public $perCycle = \IPS\REBUILD_QUICK;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
try
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'core_points_log', array( 'new_rank IS NOT NULL') )->first();
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Background Task
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( $data, $offset )
|
||||
{
|
||||
$count = 0;
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_points_log', array( 'new_rank IS NOT NULL'), 'id ASC', array( $offset, $this->perCycle ) )->join( 'core_members', 'core_members.member_id = core_points_log.member' ) as $log )
|
||||
{
|
||||
$count++;
|
||||
\IPS\Db::i()->update( 'core_points_log', array( 'time_to_new_rank' => $log['datetime'] - $log['joined'] ), array( 'id=?', $log['id'] ) );
|
||||
|
||||
$offset = $log['id'];
|
||||
}
|
||||
|
||||
if( !$count )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
return ( $offset );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Progress
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
|
||||
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('rankprogression_rebuild'), 'complete' => round( 100 / $data['count'] * $offset, 2 ) );
|
||||
}
|
||||
}
|
||||
@@ -63,10 +63,10 @@ class _Follow
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
/* Check soft delete */
|
||||
if( $item->hidden() == -2 )
|
||||
/* Only send notifications for approved items */
|
||||
if( $item->hidden() !== 0 )
|
||||
{
|
||||
/* Item is pending deletion, do not sent notifications */
|
||||
/* Item is pending deletion or hidden, do not send notifications */
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Background Task
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
|
||||
* @since 27 Sep 2022
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _PrunePms
|
||||
{
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
$rows = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_message_topics', array( 'mt_last_post_time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_pms . 'D' ) )->getTimestamp() ) ), '\IPS\core\Messenger\Conversation');
|
||||
$data['count'] = $rows->count();
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Background Task
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( &$data, $offset )
|
||||
{
|
||||
$rows = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_message_topics', array( 'mt_last_post_time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_pms . 'D' ) )->getTimestamp() ), 'mt_last_post_time ASC', 100 ), '\IPS\core\Messenger\Conversation');
|
||||
|
||||
if ( !$rows->count() )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
foreach( $rows AS $conversation )
|
||||
{
|
||||
$conversation->delete();
|
||||
|
||||
$offset++;
|
||||
}
|
||||
|
||||
return $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Progress
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
|
||||
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
{
|
||||
$text = \IPS\Member::loggedIn()->language()->addToStack('pruning_pms', FALSE, array() );
|
||||
|
||||
return array( 'text' => $text, 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $offset, 2 ) ) : 100 );
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ class _RebuildAchievements
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
return null;
|
||||
}
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
@@ -104,7 +104,15 @@ class _RebuildAchievements
|
||||
}
|
||||
|
||||
list( $app, $extension ) = explode( '_', $data['extension'] );
|
||||
$extensionObject = \IPS\Application::load( $app )->extensions( 'core', 'AchievementAction' )[ $extension ];
|
||||
try
|
||||
{
|
||||
$extensionObject = \IPS\Application::load( $app )->extensions( 'core', 'AchievementAction' )[ $extension ];
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Log::debug("App {$app} deleted. Nothing to do.", "achievements");
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
$where = $process['where'];
|
||||
if ( \stristr( $process['pkey'], '(' ) )
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Background Task: Rebuild Report Index Data
|
||||
* @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 16 Sept 2022
|
||||
*/
|
||||
|
||||
namespace IPS\core\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task: Rebuild Item Counts (comments, etc)
|
||||
*/
|
||||
class _RebuildReportIndexData
|
||||
{
|
||||
/**
|
||||
* @brief Number of content items to index per cycle
|
||||
*/
|
||||
public $index = \IPS\REBUILD_QUICK;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
try
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'MAX(id)', 'core_rc_index' )->first();
|
||||
$data['realCount'] = \IPS\Db::i()->select( 'COUNT(*)', 'core_rc_index' )->first();
|
||||
}
|
||||
catch( \IPS\Db\Exception $ex )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$data['indexed'] = 0;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Background Task
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( &$data, $offset )
|
||||
{
|
||||
$last = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_rc_index', array( 'id > ?', $offset ), 'id ASC', array( 0, $this->index ) ) as $report )
|
||||
{
|
||||
$last = $report['id'];
|
||||
$classname = $report['class'];
|
||||
$exploded = explode( '\\', $classname );
|
||||
if ( ! class_exists( $classname ) or ! \IPS\Application::appIsEnabled( $exploded[1] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$content = $classname::load( $report['content_id'] );
|
||||
$itemId = 0;
|
||||
$nodeId = 0;
|
||||
$item = null;
|
||||
|
||||
if ( $content instanceof \IPS\Content\Item )
|
||||
{
|
||||
$item = $content;
|
||||
}
|
||||
else
|
||||
{
|
||||
$item = $content->item();
|
||||
}
|
||||
|
||||
$idColumn = $item::$databaseColumnId;
|
||||
$itemId = $item->$idColumn;
|
||||
if ( $node = $item->containerWrapper() )
|
||||
{
|
||||
$nodeId = $node->_id;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'core_rc_index', [
|
||||
'item_id' => $itemId,
|
||||
'node_id' => $nodeId
|
||||
],
|
||||
[
|
||||
'id=?', $report['id']
|
||||
] );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
if( $last === NULL )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
return $last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Progress
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('rebuilding_report_index_data'), 'complete' => $data['realCount'] ? ( round( 100 / $data['realCount'] * $data['indexed'], 2 ) ) : 100 );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -169,6 +169,11 @@ class _RebuildSearchIndex
|
||||
$indexer->index($item);
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
/* This can happen if there are older, orphaned posts/comments. Just do nothing here,
|
||||
don't even log it, because we end up with pages and pages of logs. */
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
/* There was an issue indexing the item - skip and log it */
|
||||
|
||||
Reference in new issue
Block a user