Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief advertStats 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 03 Apr 2023
|
||||
*/
|
||||
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* advertStats Task
|
||||
*/
|
||||
class advertStats extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* If ran successfully, should return anything worth logging. Only log something
|
||||
* worth mentioning (don't log "task ran successfully"). Return NULL (actual NULL, not '' or 0) to not log (which will be most cases).
|
||||
* If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute() : mixed
|
||||
{
|
||||
$inserts = [];
|
||||
$time = time();
|
||||
|
||||
foreach( new ActiveRecordIterator( Db::i()->select( '*', 'core_advertisements' ), '\IPS\core\Advertisement' ) as $advert )
|
||||
{
|
||||
$inserts[] = [
|
||||
'type' => 'advert',
|
||||
'value_1' => $advert->id,
|
||||
'value_2' => $advert->daily_impressions,
|
||||
'value_3' => $advert->daily_clicks,
|
||||
'time' => $time
|
||||
];
|
||||
}
|
||||
|
||||
if( count( $inserts ) )
|
||||
{
|
||||
Db::i()->insert( 'core_statistics', $inserts );
|
||||
}
|
||||
|
||||
Db::i()->update( 'core_advertisements', [ 'ad_daily_impressions' => 0, 'ad_daily_clicks' => 0 ] );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup
|
||||
*
|
||||
* If your task takes longer than 15 minutes to run, this method
|
||||
* will be called before execute(). Use it to clean up anything which
|
||||
* may not have been done
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function cleanup() : void
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,16 +11,31 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Application;
|
||||
use IPS\Content\Comment;
|
||||
use IPS\core\Reports\Report;
|
||||
use IPS\core\Reports\Rules;
|
||||
use IPS\Db;
|
||||
use IPS\Member;
|
||||
use IPS\Notification;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use OutofRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* automaticmoderation Task
|
||||
*/
|
||||
class _automaticmoderation extends \IPS\Task
|
||||
class automaticmoderation extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,26 +46,26 @@ class _automaticmoderation extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
if ( ! \IPS\Settings::i()->automoderation_enabled )
|
||||
if ( ! Settings::i()->automoderation_enabled )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_automatic_moderation_pending', NULL, 'pending_added ASC', array( 0, 50 ) ) as $pending )
|
||||
foreach( Db::i()->select( '*', 'core_automatic_moderation_pending', NULL, 'pending_added ASC', array( 0, 50 ) ) as $pending )
|
||||
{
|
||||
/* Check report exists still */
|
||||
try
|
||||
{
|
||||
$report = \IPS\core\Reports\Report::load( $pending['pending_report_id'] );
|
||||
$report = Report::load( $pending['pending_report_id'] );
|
||||
}
|
||||
catch( \OutofRangeException $e )
|
||||
catch( OutofRangeException $e )
|
||||
{
|
||||
/* Report is missing */
|
||||
\IPS\Db::i()->delete( 'core_automatic_moderation_pending', array( 'pending_report_id=?', $pending['pending_report_id'] ) );
|
||||
Db::i()->delete( 'core_automatic_moderation_pending', array( 'pending_report_id=?', $pending['pending_report_id'] ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -61,22 +76,22 @@ class _automaticmoderation extends \IPS\Task
|
||||
{
|
||||
$object = $className::load( $pending['pending_object_id'] );
|
||||
}
|
||||
catch( \OutofRangeException $e )
|
||||
catch( OutofRangeException $e )
|
||||
{
|
||||
/* Object no longer exists */
|
||||
\IPS\Db::i()->delete( 'core_automatic_moderation_pending', array( 'pending_object_class=? and pending_object_id=?', $pending['pending_object_class'], $pending['pending_object_id'] ) );
|
||||
Db::i()->delete( 'core_automatic_moderation_pending', array( 'pending_object_class=? and pending_object_id=?', $pending['pending_object_class'], $pending['pending_object_id'] ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check rule exists still */
|
||||
try
|
||||
{
|
||||
$rule = \IPS\core\Reports\Rules::load( $pending['pending_rule_id'] );
|
||||
$rule = Rules::load( $pending['pending_rule_id'] );
|
||||
}
|
||||
catch( \OutofRangeException $e )
|
||||
catch( OutofRangeException $e )
|
||||
{
|
||||
/* Rule no longer exists */
|
||||
\IPS\Db::i()->delete( 'core_automatic_moderation_pending', array( 'pending_rule_id=?', $pending['pending_rule_id'] ) );
|
||||
Db::i()->delete( 'core_automatic_moderation_pending', array( 'pending_rule_id=?', $pending['pending_rule_id'] ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -84,30 +99,30 @@ class _automaticmoderation extends \IPS\Task
|
||||
$hidden = FALSE;
|
||||
try
|
||||
{
|
||||
if ( $object instanceof \IPS\Content\Comment )
|
||||
if ( $object instanceof Comment )
|
||||
{
|
||||
$item = $object->item();
|
||||
if ( $item and $item::$firstCommentRequired and $object->isFirst() )
|
||||
{
|
||||
/* Hide the item, not the object */
|
||||
$item->hide( FALSE, \IPS\core\Reports\Rules::getDefaultHideReason() );
|
||||
$item->hide( FALSE, Rules::getDefaultHideReason() );
|
||||
$hidden = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
catch( Exception $e ) { }
|
||||
|
||||
if ( $hidden === FALSE )
|
||||
{
|
||||
$object->hide( FALSE, \IPS\core\Reports\Rules::getDefaultHideReason() );
|
||||
$object->hide( FALSE, Rules::getDefaultHideReason() );
|
||||
}
|
||||
|
||||
/* Remove from the pending queue */
|
||||
\IPS\Db::i()->delete( 'core_automatic_moderation_pending', array( 'pending_object_class=? and pending_object_id=?', $pending['pending_object_class'], $pending['pending_object_id'] ) );
|
||||
Db::i()->delete( 'core_automatic_moderation_pending', array( 'pending_object_class=? and pending_object_id=?', $pending['pending_object_class'], $pending['pending_object_id'] ) );
|
||||
|
||||
/* Send notification to mods */
|
||||
$moderators = array( 'm' => array(), 'g' => array() );
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_moderators' ) as $mod )
|
||||
foreach ( Db::i()->select( '*', 'core_moderators' ) as $mod )
|
||||
{
|
||||
$canView = FALSE;
|
||||
if ( $mod['perms'] == '*' )
|
||||
@@ -131,16 +146,16 @@ class _automaticmoderation extends \IPS\Task
|
||||
|
||||
try
|
||||
{
|
||||
$latestReport = \IPS\Db::i()->select( '*', 'core_rc_reports', array( 'rid=?', $report->id ), 'date_reported DESC' )->first();
|
||||
$notification = new \IPS\Notification( \IPS\Application::load('core'), 'automatic_moderation', $report, array( $report, $latestReport, $object ) );
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_members', ( \count( $moderators['m'] ) ? \IPS\Db::i()->in( 'member_id', $moderators['m'] ) . ' OR ' : '' ) . \IPS\Db::i()->in( 'member_group_id', $moderators['g'] ) . ' OR ' . \IPS\Db::i()->findInSet( 'mgroup_others', $moderators['g'] ) ) as $member )
|
||||
$latestReport = Db::i()->select( '*', 'core_rc_reports', array( 'rid=?', $report->id ), 'date_reported DESC' )->first();
|
||||
$notification = new Notification( Application::load('core'), 'automatic_moderation', $report, array( $report, $latestReport, $object ) );
|
||||
foreach ( Db::i()->select( '*', 'core_members', ( count( $moderators['m'] ) ? Db::i()->in( 'member_id', $moderators['m'] ) . ' OR ' : '' ) . Db::i()->in( 'member_group_id', $moderators['g'] ) . ' OR ' . Db::i()->findInSet( 'mgroup_others', $moderators['g'] ) ) as $member )
|
||||
{
|
||||
$notification->recipients->attach( \IPS\Member::constructFromData( $member ) );
|
||||
$notification->recipients->attach( Member::constructFromData( $member ) );
|
||||
}
|
||||
|
||||
$notification->send();
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
catch( Exception $e ) { }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,16 +11,24 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DirectoryIterator;
|
||||
use IPS\File;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
use function is_dir;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* chunkcleanup Task
|
||||
*/
|
||||
class _chunkcleanup extends \IPS\Task
|
||||
class chunkcleanup extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,26 +39,26 @@ class _chunkcleanup extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$chunksCleanedUp = 0;
|
||||
|
||||
/* Loop over file storage configurations */
|
||||
foreach( \IPS\File::getStore() as $configuration )
|
||||
foreach( File::getStore() as $configuration )
|
||||
{
|
||||
/* If this is a filesystem config... */
|
||||
if( $configuration['method'] == 'FileSystem' )
|
||||
{
|
||||
/* Get the configuration object */
|
||||
$fileStorageObject = \IPS\File::getClass( $configuration['id'] );
|
||||
$fileStorageObject = File::getClass( $configuration['id'] );
|
||||
|
||||
/* If we have a chunks folder */
|
||||
if( \is_dir( $fileStorageObject->configuration['dir'] . '/chunks' ) )
|
||||
if( is_dir( $fileStorageObject->configuration['dir'] . '/chunks' ) )
|
||||
{
|
||||
/* Loop over all the files in the directory */
|
||||
$iterator = new \DirectoryIterator( $fileStorageObject->configuration['dir'] . '/chunks' );
|
||||
$iterator = new DirectoryIterator( $fileStorageObject->configuration['dir'] . '/chunks' );
|
||||
|
||||
foreach( $iterator as $file )
|
||||
{
|
||||
|
||||
+121
-110
@@ -10,45 +10,59 @@
|
||||
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
use IPS\Application;
|
||||
use function implode;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\Application;
|
||||
use IPS\Content;
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Member;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Widget;
|
||||
use OutOfRangeException;
|
||||
use RuntimeException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Daily Cleanup Task
|
||||
*/
|
||||
class _cleanup extends \IPS\Task
|
||||
class cleanup extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \RuntimeException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Delete old failed guest logins for accounts that do not exist */
|
||||
if( $maxCutoff = (int) \IPS\Settings::i()->bruteforce_global_period )
|
||||
if( $maxCutoff = (int) Settings::i()->bruteforce_global_period )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_login_failures', [
|
||||
Db::i()->delete( 'core_login_failures', [
|
||||
'login_date<? AND login_ip_address IS NOT NULL AND login_email IS NOT NULL',
|
||||
( new \IPS\DateTime )->sub( new \DateInterval( 'PT' . $maxCutoff . 'M' ) )->sub( new \DateInterval( 'PT24H' ) )->getTimestamp()
|
||||
( new DateTime )->sub( new DateInterval( 'PT' . $maxCutoff . 'M' ) )->sub( new DateInterval( 'PT24H' ) )->getTimestamp()
|
||||
] );
|
||||
}
|
||||
|
||||
/* Delete old password / security answer reset requests */
|
||||
\IPS\Db::i()->delete( 'core_validating', array( '( lost_pass=1 OR forgot_security=1 ) AND email_sent < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_validating', array( '( lost_pass=1 OR forgot_security=1 ) AND email_sent < ?', DateTime::create()->sub( new DateInterval( 'P1D' ) )->getTimestamp() ) );
|
||||
|
||||
/* If we are currently pruning any large tables via a bg task, find out so we don't try to prune them normally here as well. The bg task should finish first. */
|
||||
$currentlyPruning = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_queue', array( '`key`=?', 'PruneLargeTable' ) ) as $pruneTask )
|
||||
foreach( Db::i()->select( '*', 'core_queue', array( '`key`=?', 'PruneLargeTable' ) ) as $pruneTask )
|
||||
{
|
||||
$data = json_decode( $pruneTask['data'], true );
|
||||
|
||||
@@ -56,13 +70,13 @@ class _cleanup extends \IPS\Task
|
||||
}
|
||||
|
||||
/* Delete old validating members */
|
||||
if ( \IPS\Settings::i()->validate_day_prune )
|
||||
if ( Settings::i()->validate_day_prune )
|
||||
{
|
||||
$select = \IPS\Db::i()->select( 'core_validating.member_id, core_members.member_posts', 'core_validating', array( 'core_validating.new_reg=1 AND core_validating.coppa_user<>1 AND core_validating.entry_date<? AND core_validating.lost_pass<>1 AND core_validating.user_verified=0 AND !(core_members.members_bitoptions2 & 16384 ) AND core_members.member_posts < 1 AND core_validating.do_not_delete=0', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->validate_day_prune . 'D' ) )->getTimestamp() ) )->join( 'core_members', 'core_members.member_id=core_validating.member_id' );
|
||||
$select = Db::i()->select( 'core_validating.member_id, core_members.member_posts', 'core_validating', array( 'core_validating.new_reg=1 AND core_validating.coppa_user<>1 AND core_validating.entry_date<? AND core_validating.lost_pass<>1 AND core_validating.user_verified=0 AND !(core_members.members_bitoptions2 & 16384 ) AND core_members.member_posts < 1 AND core_validating.do_not_delete=0', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->validate_day_prune . 'D' ) )->getTimestamp() ) )->join( 'core_members', 'core_members.member_id=core_validating.member_id' );
|
||||
|
||||
foreach ( $select as $row )
|
||||
{
|
||||
$member = \IPS\Member::load( $row['member_id'] );
|
||||
$member = Member::load( $row['member_id'] );
|
||||
|
||||
if( $member->member_id )
|
||||
{
|
||||
@@ -70,189 +84,189 @@ class _cleanup extends \IPS\Task
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_validating', array( 'member_id=?', $row['member_id'] ) );
|
||||
Db::i()->delete( 'core_validating', array( 'member_id=?', $row['member_id'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete file system logs */
|
||||
if( \IPS\Settings::i()->file_log_pruning )
|
||||
if( Settings::i()->file_log_pruning )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_file_logs', array( 'log_date < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->file_log_pruning . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_file_logs', array( 'log_date < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->file_log_pruning . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* Delete edit history past prune date */
|
||||
if( \IPS\Settings::i()->edit_log_prune > 0 )
|
||||
if( Settings::i()->edit_log_prune > 0 )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_edit_history', array( 'time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->edit_log_prune . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_edit_history', array( 'time < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->edit_log_prune . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* Delete task logs older than the prune-since date */
|
||||
if( \IPS\Settings::i()->prune_log_tasks )
|
||||
if( Settings::i()->prune_log_tasks )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_tasks_log', array( 'time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_log_tasks . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_tasks_log', array( 'time < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_log_tasks . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* Delete email error logs older than the prune-since date */
|
||||
if( \IPS\Settings::i()->prune_log_email_error )
|
||||
if( Settings::i()->prune_log_email_error )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_mail_error_logs', array( 'mlog_date < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_log_email_error . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_mail_error_logs', array( 'mlog_date < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_log_email_error . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and admin logs */
|
||||
if( \IPS\Settings::i()->prune_log_admin )
|
||||
if( Settings::i()->prune_log_admin )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_admin_logs', array( 'ctime < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_log_admin . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_admin_logs', array( 'ctime < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_log_admin . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and moderators logs */
|
||||
if( \IPS\Settings::i()->prune_log_moderator )
|
||||
if( Settings::i()->prune_log_moderator )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_moderator_logs', array( 'ctime < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_log_moderator . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_moderator_logs', array( 'ctime < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_log_moderator . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and error logs */
|
||||
if( \IPS\Settings::i()->prune_log_error )
|
||||
if( Settings::i()->prune_log_error )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_error_logs', array( 'log_date < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_log_error . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_error_logs', array( 'log_date < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_log_error . 'D' ) )->getTimestamp() ) );
|
||||
|
||||
/* If we don't have any logs left, remove any notifications */
|
||||
if( \IPS\Db::i()->select( 'count(log_id)', 'core_error_logs' )->first() === 0 )
|
||||
if( Db::i()->select( 'count(log_id)', 'core_error_logs' )->first() === 0 )
|
||||
{
|
||||
\IPS\core\AdminNotification::remove( 'core', 'Error' );
|
||||
AdminNotification::remove( 'core', 'Error' );
|
||||
}
|
||||
}
|
||||
|
||||
/* ...and spam service logs */
|
||||
if( \IPS\Settings::i()->prune_log_spam )
|
||||
if( Settings::i()->prune_log_spam )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_spam_service_log', array( 'log_date < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_log_spam . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_spam_service_log', array( 'log_date < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_log_spam . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and admin login logs */
|
||||
if( \IPS\Settings::i()->prune_log_adminlogin )
|
||||
if( Settings::i()->prune_log_adminlogin )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_admin_login_logs', array( 'admin_time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_log_adminlogin . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_admin_login_logs', array( 'admin_time < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_log_adminlogin . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and statistics */
|
||||
if( \IPS\Settings::i()->stats_online_users_prune )
|
||||
if( Settings::i()->stats_online_users_prune )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_statistics', array( 'type=? AND time < ?', 'online_users', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->stats_online_users_prune . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_statistics', array( 'type=? AND time < ?', 'online_users', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->stats_online_users_prune . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
if( \IPS\Settings::i()->stats_keywords_prune )
|
||||
if( Settings::i()->stats_keywords_prune )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_statistics', array( 'type=? AND time < ?', 'keyword', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->stats_keywords_prune . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_statistics', array( 'type=? AND time < ?', 'keyword', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->stats_keywords_prune . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
if( \IPS\Settings::i()->stats_search_prune )
|
||||
if( Settings::i()->stats_search_prune )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_statistics', array( 'type=? AND time < ?', 'search', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->stats_search_prune . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_statistics', array( 'type=? AND time < ?', 'search', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->stats_search_prune . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
if( \IPS\Settings::i()->prune_log_emailstats > 0 )
|
||||
if( Settings::i()->prune_log_emailstats > 0 )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_statistics', array( "type IN('emails_sent','email_views','email_clicks') AND time < ?", \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_log_emailstats . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and guest details stored with reports */
|
||||
if( (int) \IPS\Settings::i()->report_guest_details_store_days > 0 )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_rc_reports', [ 'guest_name' => null, 'guest_email' => null ], array( 'date_reported < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->report_guest_details_store_days . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_statistics', array( "type IN('emails_sent','email_views','email_clicks') AND time < ?", DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_log_emailstats . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and geoip cache */
|
||||
\IPS\Db::i()->delete( 'core_geoip_cache', array( 'date < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P7D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_geoip_cache', array( 'date < ?', DateTime::create()->sub( new DateInterval( 'P7D' ) )->getTimestamp() ) );
|
||||
|
||||
/* ...and API logs */
|
||||
$successfulCodes = [ 200, 201, 202, 203, 204, 205, 206, 207, 208, 226 ];
|
||||
if( \IPS\Settings::i()->api_log_prune )
|
||||
if( Settings::i()->api_log_prune )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_api_logs', array( 'date < ? and response_code IN(' . implode( ',', $successfulCodes ) . ')', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->api_log_prune . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_api_logs', array( 'date < ? and response_code IN(' . implode( ',', $successfulCodes ) . ')', DateTime::create()->sub( new \DateInterval( 'P' . Settings::i()->api_log_prune . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
if( \IPS\Settings::i()->api_log_prune_failures )
|
||||
if( Settings::i()->api_log_prune_failures )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_api_logs', array( 'date < ? and response_code NOT IN(' . implode( ',', $successfulCodes ) . ')', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->api_log_prune_failures . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_api_logs', array( 'date < ? and response_code NOT IN(' . implode( ',', $successfulCodes ) . ')', DateTime::create()->sub( new \DateInterval( 'P' . Settings::i()->api_log_prune_failures . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and non-nexus member history */
|
||||
if( \IPS\Settings::i()->prune_member_history AND !\in_array( 'core_member_history', $currentlyPruning ) )
|
||||
/* ...and non-member history */
|
||||
if( Settings::i()->prune_member_history AND !in_array( 'core_member_history', $currentlyPruning ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_member_history', array( 'log_date < ? and log_app != ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_member_history . 'D' ) )->getTimestamp(), 'nexus' ) );
|
||||
Db::i()->delete( 'core_member_history', array( 'log_date < ? and log_app != ?', DateTime::create()->sub( new \DateInterval( 'P' . Settings::i()->prune_member_history . 'D' ) )->getTimestamp(), 'nexus' ) );
|
||||
}
|
||||
|
||||
/* ...and Nexus member history */
|
||||
if( Application::appIsEnabled('nexus') and \IPS\Settings::i()->nexus_prune_history AND !\in_array( 'core_member_history', $currentlyPruning ) )
|
||||
if( Application::appIsEnabled('nexus') and Settings::i()->nexus_prune_history AND !\in_array( 'core_member_history', $currentlyPruning ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_member_history', array( 'log_date < ? and log_app = ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->nexus_prune_history . 'D' ) )->getTimestamp(), 'nexus' ) );
|
||||
Db::i()->delete( 'core_member_history', array( 'log_date < ? and log_app = ?', DateTime::create()->sub( new \DateInterval( 'P' . Settings::i()->nexus_prune_history . 'D' ) )->getTimestamp(), 'nexus' ) );
|
||||
}
|
||||
|
||||
/* ...and promote response logs */
|
||||
\IPS\Db::i()->delete( 'core_social_promote_content', array( 'response_date < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P6M' ) )->getTimestamp() ) );
|
||||
|
||||
/* ...and webhook logs */
|
||||
if( \IPS\Settings::i()->webhook_logs_success )
|
||||
if( Settings::i()->webhook_logs_success )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_api_webhook_fires', array( "status='successful' AND time < ?", \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->webhook_logs_success . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_api_webhook_fires', array( "status='successful' AND time < ?", DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->webhook_logs_success . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
if( \IPS\Settings::i()->webhook_logs_fail )
|
||||
if( Settings::i()->webhook_logs_fail )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_api_webhook_fires', array( "status='failed' AND time < ?", \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->webhook_logs_fail . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_api_webhook_fires', array( "status='failed' AND time < ?", DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->webhook_logs_fail . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* ...and points log */
|
||||
if( \IPS\Settings::i()->prune_points_log )
|
||||
if( Settings::i()->prune_points_log )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_achievements_log', array( 'datetime < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_points_log . 'D' ) )->getTimestamp() ) );
|
||||
\IPS\Db::i()->delete( 'core_points_log', array( 'datetime < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_points_log . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_achievements_log', array( 'datetime < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_points_log . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_points_log', array( 'datetime < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_points_log . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* Delete old notifications */
|
||||
if ( \IPS\Settings::i()->prune_notifications )
|
||||
if ( Settings::i()->prune_notifications )
|
||||
{
|
||||
$memberIds = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '`member`', 'core_notifications', array( 'sent_time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_notifications . 'D' ) )->getTimestamp() ) ) as $member )
|
||||
foreach( Db::i()->select( '`member`', 'core_notifications', array( 'sent_time < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_notifications . 'D' ) )->getTimestamp() ) ) as $member )
|
||||
{
|
||||
$memberIds[ $member ] = $member;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_notifications', array( 'sent_time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_notifications . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_notifications', array( 'sent_time < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_notifications . 'D' ) )->getTimestamp() ) );
|
||||
|
||||
foreach( $memberIds as $member )
|
||||
{
|
||||
\IPS\Member::load( $member )->recountNotifications();
|
||||
Member::load( $member )->recountNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete old item markers */
|
||||
if ( \IPS\Settings::i()->prune_item_markers AND !\in_array( 'core_item_markers', $currentlyPruning ) )
|
||||
/* Delete old follows */
|
||||
if ( Settings::i()->prune_follows AND !in_array( 'core_follow', $currentlyPruning ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_item_markers', array( 'item_member_id IN(?)', \IPS\Db::i()->select( 'member_id', 'core_members', array( 'last_activity < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_item_markers . 'D' ) )->getTimestamp() ) ) ) );
|
||||
Db::i()->delete( 'core_follow', array( 'follow_app!=? AND follow_area!=? AND follow_member_id IN(?)', 'core', 'member', Db::i()->select( 'member_id', 'core_members', array( 'last_activity < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_follows . 'D' ) )->getTimestamp() ) ) ) );
|
||||
|
||||
/* And clear the cache so it can rebuild */
|
||||
Db::i()->delete( 'core_follow_count_cache' );
|
||||
}
|
||||
|
||||
/* Delete old item markers */
|
||||
if ( Settings::i()->prune_item_markers AND !in_array( 'core_item_markers', $currentlyPruning ) )
|
||||
{
|
||||
Db::i()->delete( 'core_item_markers', array( 'item_member_id IN(?)', Db::i()->select( 'member_id', 'core_members', array( 'last_activity < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_item_markers . 'D' ) )->getTimestamp() ) ) ) );
|
||||
}
|
||||
|
||||
/* Delete old seen IP addresses */
|
||||
if ( \IPS\Settings::i()->prune_known_ips AND !\in_array( 'core_members_known_ip_addresses', $currentlyPruning ) )
|
||||
if ( Settings::i()->prune_known_ips AND !in_array( 'core_members_known_ip_addresses', $currentlyPruning ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_members_known_ip_addresses', array( 'last_seen < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_known_ips . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_members_known_ip_addresses', array( 'last_seen < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_known_ips . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* Delete old seen devices */
|
||||
if ( \IPS\Settings::i()->prune_known_devices AND !\in_array( 'core_members_known_devices', $currentlyPruning ) )
|
||||
if ( Settings::i()->prune_known_devices AND !in_array( 'core_members_known_devices', $currentlyPruning ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_members_known_devices', array( 'last_seen < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_known_devices . 'D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_members_known_devices', array( 'last_seen < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_known_devices . 'D' ) )->getTimestamp() ) );
|
||||
}
|
||||
|
||||
/* Delete moved links */
|
||||
if ( \IPS\Settings::i()->topic_redirect_prune )
|
||||
if ( Settings::i()->topic_redirect_prune )
|
||||
{
|
||||
foreach ( \IPS\Content::routedClasses( FALSE, FALSE, TRUE ) as $class )
|
||||
foreach ( Content::routedClasses( FALSE, FALSE, TRUE ) as $class )
|
||||
{
|
||||
if ( isset( $class::$databaseColumnMap['moved_on'] ) )
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', $class::$databaseTable, array( $class::$databasePrefix . $class::$databaseColumnMap['moved_on'] . '>0 AND ' . $class::$databasePrefix . $class::$databaseColumnMap['moved_on'] . '<?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->topic_redirect_prune . 'D' ) )->getTimestamp() ), $class::$databasePrefix . $class::$databaseColumnId, 100 ), $class ) as $item )
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', $class::$databaseTable, array( $class::$databasePrefix . $class::$databaseColumnMap['moved_on'] . '>0 AND ' . $class::$databasePrefix . $class::$databaseColumnMap['moved_on'] . '<?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->topic_redirect_prune . 'D' ) )->getTimestamp() ), $class::$databasePrefix . $class::$databaseColumnId, 100 ), $class ) as $item )
|
||||
{
|
||||
$item->delete();
|
||||
}
|
||||
@@ -261,78 +275,78 @@ class _cleanup extends \IPS\Task
|
||||
}
|
||||
|
||||
/* Remove warnings points */
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_members_warn_logs', array( 'wl_expire_date>0 AND wl_expire_date<?', time() ), 'wl_date ASC', 25 ), 'IPS\core\Warnings\Warning' ) as $warning )
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', 'core_members_warn_logs', array( 'wl_expire_date>0 AND wl_expire_date<?', time() ), 'wl_date ASC', 25 ), 'IPS\core\Warnings\Warning' ) as $warning )
|
||||
{
|
||||
$member = \IPS\Member::load( $warning->member );
|
||||
$member = Member::load( $warning->member );
|
||||
$member->warn_level -= $warning->points;
|
||||
$member->save();
|
||||
|
||||
\IPS\Db::i()->update( 'core_members_warn_logs', array( 'wl_removed_on' => $warning->expire_date ), array( 'wl_id=?', $warning->id ) );
|
||||
Db::i()->update( 'core_members_warn_logs', array( 'wl_removed_on' => $warning->expire_date ), array( 'wl_id=?', $warning->id ) );
|
||||
|
||||
$warning->expire_date = 0;
|
||||
$warning->save();
|
||||
}
|
||||
|
||||
/* Remove widgets */
|
||||
if ( \IPS\Application::appIsEnabled('cms') )
|
||||
if ( Application::appIsEnabled('cms') )
|
||||
{
|
||||
\IPS\cms\Widget::emptyTrash();
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Widget::emptyTrash();
|
||||
Widget::emptyTrash();
|
||||
}
|
||||
|
||||
/* Reset expired "moderate content till.." timestamps */
|
||||
\IPS\Db::i()->update( 'core_members', array( 'mod_posts' => 0 ), array( 'mod_posts != -1 and mod_posts <?', time() ) );
|
||||
Db::i()->update( 'core_members', array( 'mod_posts' => 0 ), array( 'mod_posts != -1 and mod_posts <?', time() ) );
|
||||
|
||||
/* Set expired announcements inactive */
|
||||
\IPS\Db::i()->update( 'core_announcements', array( 'announce_active' => 0 ), array( 'announce_active = 1 and announce_end > 0 and announce_end <?', time() ) );
|
||||
Db::i()->update( 'core_announcements', array( 'announce_active' => 0 ), array( 'announce_active = 1 and announce_end > 0 and announce_end <?', time() ) );
|
||||
|
||||
/* Delete old Google Authenticator code uses */
|
||||
\IPS\Db::i()->delete( 'core_googleauth_used_codes', array( 'time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'PT1M' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_googleauth_used_codes', array( 'time < ?', DateTime::create()->sub( new DateInterval( 'PT1M' ) )->getTimestamp() ) );
|
||||
|
||||
/* Close open polls that need closing */
|
||||
\IPS\Db::i()->update( 'core_polls', array( 'poll_closed' => 1 ), array( 'poll_closed=? AND poll_close_date>? AND poll_close_date<?', 0, -1, time() ) );
|
||||
Db::i()->update( 'core_polls', array( 'poll_closed' => 1 ), array( 'poll_closed=? AND poll_close_date>? AND poll_close_date<?', 0, -1, time() ) );
|
||||
|
||||
/* Delete expired oAuth Authorization Codes */
|
||||
\IPS\Db::i()->delete( 'core_oauth_server_authorization_codes', array( 'expires<?', time() ) );
|
||||
\IPS\Db::i()->delete( 'core_oauth_server_access_tokens', array( 'refresh_token_expires<?', time() ) );
|
||||
\IPS\Db::i()->delete( 'core_oauth_authorize_prompts', array( 'timestamp<?', ( time() - 300 ) ) );
|
||||
Db::i()->delete( 'core_oauth_server_authorization_codes', array( 'expires<?', time() ) );
|
||||
Db::i()->delete( 'core_oauth_server_access_tokens', array( 'refresh_token_expires<?', time() ) );
|
||||
Db::i()->delete( 'core_oauth_authorize_prompts', array( 'timestamp<?', ( time() - 300 ) ) );
|
||||
|
||||
/* Delete any unfinished "Post before register" posts */
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_post_before_registering', array( "`member` IS NULL AND followup IS NOT NULL AND followup<" . ( time() - ( 86400 * 6 ) ) ), 'followup ASC' ) as $row )
|
||||
foreach ( Db::i()->select( '*', 'core_post_before_registering', array( "`member` IS NULL AND followup IS NOT NULL AND followup<" . ( time() - ( 86400 * 6 ) ) ), 'followup ASC' ) as $row )
|
||||
{
|
||||
$class = $row['class'];
|
||||
try
|
||||
{
|
||||
$class::load( $row['id'] )->delete();
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException $e ) { }
|
||||
|
||||
\IPS\Db::i()->delete( 'core_post_before_registering', array( 'class=? AND id=?', $row['class'], $row['id'] ) );
|
||||
Db::i()->delete( 'core_post_before_registering', array( 'class=? AND id=?', $row['class'], $row['id'] ) );
|
||||
}
|
||||
|
||||
/* Delete old core follow caches */
|
||||
\IPS\Db::i()->delete( 'core_follow_count_cache', array( 'added < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P30D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_follow_count_cache', array( 'added < ?', DateTime::create()->sub( new DateInterval( 'P30D' ) )->getTimestamp() ) );
|
||||
|
||||
/* Delete old core statistic caches */
|
||||
\IPS\Db::i()->delete( 'core_item_statistics_cache', array( 'cache_added < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_item_statistics_cache', array( 'cache_added < ?', DateTime::create()->sub( new DateInterval( 'P1D' ) )->getTimestamp() ) );
|
||||
|
||||
/* Delete alerts */
|
||||
\IPS\Db::i()->delete( 'core_alerts', array( 'alert_end > 0 and alert_end < ?', time() ) );
|
||||
Db::i()->delete( 'core_alerts', array( 'alert_end > 0 and alert_end < ?', time() ) );
|
||||
|
||||
/* Trigger queue item to prune old PMs with no replies in x days */
|
||||
if( \IPS\Settings::i()->prune_pms )
|
||||
if( Settings::i()->prune_pms )
|
||||
{
|
||||
/* Get count */
|
||||
$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');
|
||||
$rows = new ActiveRecordIterator( Db::i()->select( '*', 'core_message_topics', array( 'mt_last_post_time < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_pms . 'D' ) )->getTimestamp() ) ), '\IPS\core\Messenger\Conversation');
|
||||
|
||||
$count = $rows->count();
|
||||
if( $count > 5 )
|
||||
{
|
||||
/* Queue */
|
||||
\IPS\Task::queue( 'core', 'PrunePms', array(), 2 );
|
||||
Task::queue( 'core', 'PrunePms', array(), 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -345,11 +359,8 @@ class _cleanup extends \IPS\Task
|
||||
|
||||
}
|
||||
|
||||
/* Truncate the output caches table */
|
||||
\IPS\Output\Cache::i()->deleteExpired( TRUE );
|
||||
|
||||
/* Delete Contact Us Verifications older than a month */
|
||||
\IPS\Db::i()->delete( 'core_contact_verify', array( "verify_time<?", \IPS\DateTime::create()->sub( new \DateInterval( 'P30D' ) )->getTimestamp() ) );
|
||||
Db::i()->delete( 'core_contact_verify', array( "verify_time<?", DateTime::create()->sub( new DateInterval( 'P30D' ) )->getTimestamp() ) );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,23 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\File;
|
||||
use IPS\Task;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Task that removes attachments that were never claimed
|
||||
*/
|
||||
class _cleanupattachments extends \IPS\Task
|
||||
class cleanupattachments extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,23 +38,23 @@ class _cleanupattachments extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Cleanup - this is deliberately slightly different to the one in \IPS\Text\Parser as it will only delete attachments which have been "saved" (i.e. are not in the middle of being posted) */
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_attachments', array( array( 'attach_id NOT IN(?) AND attach_post_key=?', \IPS\Db::i()->select( 'DISTINCT attachment_id', 'core_attachments_map' ), '' ) ) ) as $attachment )
|
||||
foreach ( Db::i()->select( '*', 'core_attachments', array( array( 'attach_id NOT IN(?) AND attach_post_key=?', Db::i()->select( 'DISTINCT attachment_id', 'core_attachments_map' ), '' ) ) ) as $attachment )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
|
||||
\IPS\File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
|
||||
Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
|
||||
File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
|
||||
if ( $attachment['attach_thumb_location'] )
|
||||
{
|
||||
\IPS\File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
|
||||
File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception $e ) { }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,16 +11,25 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\File;
|
||||
use IPS\Task;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Task that removes files from core_files_temp that were never claimed
|
||||
*/
|
||||
class _cleanupfiles extends \IPS\Task
|
||||
class cleanupfiles extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,24 +40,24 @@ class _cleanupfiles extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_files_temp', array( 'time < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp() ) ) as $file )
|
||||
foreach ( Db::i()->select( '*', 'core_files_temp', array( 'time < ?', DateTime::create()->sub( new DateInterval( 'P1D' ) )->getTimestamp() ) ) as $file )
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_files_temp', array( '`id`=?', $file['id'] ) );
|
||||
Db::i()->delete( 'core_files_temp', array( '`id`=?', $file['id'] ) );
|
||||
|
||||
/* storage_extension was added in 4.1.14. If available, remove the file on disk too */
|
||||
if ( ! empty( $file['storage_extension'] ) )
|
||||
{
|
||||
\IPS\File::get( $file['storage_extension'], $file['contents'] )->delete();
|
||||
File::get( $file['storage_extension'], $file['contents'] )->delete();
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception $e ) { }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,16 +11,23 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
use const IPS\STORE_METHOD;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* clearcache Task
|
||||
*/
|
||||
class _clearcache extends \IPS\Task
|
||||
class clearcache extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,18 +38,17 @@ class _clearcache extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Note: We previously disabled the task if the caching method was disabled however this lead to people re-enabling through a constants edit which would not re-enabled the task */
|
||||
\IPS\Db::i()->delete( 'core_cache', array( 'cache_expire<?', time() ) );
|
||||
\IPS\Output\Cache::i()->deleteExpired();
|
||||
Db::i()->delete( 'core_cache', array( 'cache_expire<?', time() ) );
|
||||
|
||||
/* If we are using Redis, ensure that core_store is empty. We may have switched over to Redis from MySQL and if we switch back, we do not want stale data being used */
|
||||
if ( \IPS\STORE_METHOD !== 'Database' AND \IPS\Db::i()->select( 'count(*)', 'core_store' )->first() )
|
||||
if ( STORE_METHOD !== 'Database' AND Db::i()->select( 'count(*)', 'core_store' )->first() )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_store' );
|
||||
Db::i()->delete( 'core_store' );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,16 +11,23 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Content\Search\Index;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* clearelasticsearchtasks Task
|
||||
*/
|
||||
class _clearelasticsearchtasks extends \IPS\Task
|
||||
class clearelasticsearchtasks extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,16 +38,17 @@ class _clearelasticsearchtasks extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
if( \IPS\Settings::i()->search_method != 'elastic' )
|
||||
if( Settings::i()->search_method != 'elastic' )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
\IPS\Content\Search\Index::i()->clearTasks();
|
||||
Index::i()->clearTasks();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,16 +11,26 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Member;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* clearincompletemembers Task
|
||||
*/
|
||||
class _clearincompletemembers extends \IPS\Task
|
||||
class clearincompletemembers extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,14 +41,14 @@ class _clearincompletemembers extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Delete cancelled registration members */
|
||||
foreach( \IPS\Db::i()->select( 'member_id', 'core_validating', array( 'do_not_delete=0 and reg_cancelled > 0 and reg_cancelled < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'PT1H' ) )->getTimestamp() ) ) as $id )
|
||||
foreach( Db::i()->select( 'member_id', 'core_validating', array( 'do_not_delete=0 and reg_cancelled > 0 and reg_cancelled < ?', DateTime::create()->sub( new DateInterval( 'PT1H' ) )->getTimestamp() ) ) as $id )
|
||||
{
|
||||
$member = \IPS\Member::load( $id );
|
||||
$member = Member::load( $id );
|
||||
|
||||
if( $member->member_id )
|
||||
{
|
||||
@@ -46,12 +56,12 @@ class _clearincompletemembers extends \IPS\Task
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_validating', array( 'member_id=?', $id ) );
|
||||
Db::i()->delete( 'core_validating', array( 'member_id=?', $id ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete any incompleted accounts (for example, someone has clicked "Sign in with Twitter" and never provided a username or email */
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_members', array( array( '(name=? OR email=?)', '', '' ), array( '! (members_bitoptions2 & 16384 ) AND joined<? AND (last_visit=0 OR last_visit IS NULL)', \IPS\DateTime::create()->sub( new \DateInterval( 'PT1H' ) )->getTimestamp() ) ) ), 'IPS\Member' ) as $incompleteMember )
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', 'core_members', array( array( '(name=? OR email=?)', '', '' ), array( '! (members_bitoptions2 & 16384 ) AND joined<? AND (last_visit=0 OR last_visit IS NULL)', DateTime::create()->sub( new DateInterval( 'PT1H' ) )->getTimestamp() ) ) ), 'IPS\Member' ) as $incompleteMember )
|
||||
{
|
||||
$incompleteMember->delete();
|
||||
}
|
||||
|
||||
@@ -11,16 +11,24 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Session;
|
||||
use IPS\Session\Store;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* clearsessions Task
|
||||
*/
|
||||
class _clearsessions extends \IPS\Task
|
||||
class clearsessions extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,14 +39,14 @@ class _clearsessions extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$timeout = \IPS\Session::sessionLifetime();
|
||||
$timeout = Session::sessionLifetime();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_sys_cp_sessions', array( 'session_running_time<?', ( time() - $timeout ) ) );
|
||||
$class = \IPS\Session\Store::i();
|
||||
Db::i()->delete( 'core_sys_cp_sessions', array( 'session_running_time<?', ( time() - $timeout ) ) );
|
||||
$class = Store::i();
|
||||
$class::clearSessions( $timeout );
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Promote Task
|
||||
* @brief cleartagpins 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 28 Feb 2017
|
||||
{subpackage}
|
||||
* @since 13 May 2024
|
||||
*/
|
||||
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception as TaskException;
|
||||
use function defined;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote Task
|
||||
* cleartagpins Task
|
||||
*/
|
||||
class _promote extends \IPS\Task
|
||||
class cleartagpins extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,12 +37,11 @@ class _promote extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws TaskException
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
\IPS\core\Promote::processQueue();
|
||||
|
||||
Db::i()->delete( 'core_tags_pinned', [ 'pinned_end_date > ? and pinned_end_date < ?', 0, time() ] );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -49,7 +54,7 @@ class _promote extends \IPS\Task
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function cleanup()
|
||||
public function cleanup() : void
|
||||
{
|
||||
|
||||
}
|
||||
@@ -11,16 +11,25 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Member;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* clubrebuild Task
|
||||
*/
|
||||
class _clubrebuild extends \IPS\Task
|
||||
class clubrebuild extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,26 +40,26 @@ class _clubrebuild extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
if ( !\IPS\Settings::i()->clubs )
|
||||
if ( !Settings::i()->clubs )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 'clubrebuild' ) );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 'clubrebuild' ) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$this->runUntilTimeout( function()
|
||||
{
|
||||
$select = \IPS\Db::i()->select( '*', 'core_clubs', array( 'rebuilt is null or rebuilt<?', time() - 1200 ), 'rebuilt ASC', 10 );
|
||||
$select = Db::i()->select( '*', 'core_clubs', array( 'rebuilt is null or rebuilt<?', time() - 1200 ), 'rebuilt ASC', 10 );
|
||||
|
||||
if ( !$select->count() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( $select, 'IPS\Member\Club' ) as $club )
|
||||
foreach ( new ActiveRecordIterator( $select, 'IPS\Member\Club' ) as $club )
|
||||
{
|
||||
$club->content = 0;
|
||||
$club->last_activity = 0;
|
||||
@@ -62,14 +71,14 @@ class _clubrebuild extends \IPS\Task
|
||||
$nodeClass = $node['node_class'];
|
||||
$node = $nodeClass::load( $node['node_id'] );
|
||||
|
||||
if ( $lastCommentTime = $node->getLastCommentTime( new \IPS\Member ) and $lastCommentTime->getTimestamp() > $club->last_activity )
|
||||
if ( $lastCommentTime = $node->getLastCommentTime( new Member ) and $lastCommentTime->getTimestamp() > $club->last_activity )
|
||||
{
|
||||
$club->last_activity = $lastCommentTime->getTimestamp();
|
||||
}
|
||||
|
||||
$club->content += (int) $node->getContentItemCount();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception $e ) { }
|
||||
}
|
||||
|
||||
$club->rebuilt = time();
|
||||
@@ -78,6 +87,8 @@ class _clubrebuild extends \IPS\Task
|
||||
|
||||
return TRUE;
|
||||
} );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,16 +11,23 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Stream\Subscription;
|
||||
use IPS\Db;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* dailyStreamSubscriptions Task
|
||||
*/
|
||||
class _dailyStreamSubscriptions extends \IPS\Task
|
||||
class dailyStreamSubscriptions extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,12 +38,12 @@ class _dailyStreamSubscriptions extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Disable task if no subscriptions */
|
||||
$select = \IPS\Db::i()->select( '*', 'core_stream_subscriptions', array( 'frequency=?', 'daily' ));
|
||||
$select = Db::i()->select( '*', 'core_stream_subscriptions', array( 'frequency=?', 'daily' ));
|
||||
if( !$select->count() )
|
||||
{
|
||||
$this->enabled = FALSE;
|
||||
@@ -47,7 +54,7 @@ class _dailyStreamSubscriptions extends \IPS\Task
|
||||
|
||||
$this->runUntilTimeout( function()
|
||||
{
|
||||
return \IPS\core\Stream\Subscription::sendBatch( 'daily' );
|
||||
return Subscription::sendBatch( 'daily' );
|
||||
});
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,27 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* deletecontent Task
|
||||
*/
|
||||
class _deletecontent extends \IPS\Task
|
||||
class deletecontent extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,16 +42,16 @@ class _deletecontent extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$this->runUntilTimeout( function()
|
||||
{
|
||||
$timeago = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->dellog_retention_period . 'D' ) );
|
||||
$timeago = DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->dellog_retention_period . 'D' ) );
|
||||
$count = 0;
|
||||
|
||||
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_deletion_log', array( "dellog_deleted_date<?", $timeago->getTimestamp() ), 'dellog_deleted_date ASC', array( 0, 20 ) ), 'IPS\core\DeletionLog' ) AS $log )
|
||||
foreach( new ActiveRecordIterator( Db::i()->select( '*', 'core_deletion_log', array( "dellog_deleted_date<?", $timeago->getTimestamp() ), 'dellog_deleted_date ASC', array( 0, 20 ) ), 'IPS\core\DeletionLog' ) AS $log )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -52,20 +63,20 @@ class _deletecontent extends \IPS\Task
|
||||
/* Make sure that the content is flagged for deletion */
|
||||
if( $content->hidden() !== -2 )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$content->delete();
|
||||
}
|
||||
}
|
||||
/* If the content is gone already, don't let an uncaught exception bubble up...just remove the deletion log orphaned entry */
|
||||
catch( \OutOfRangeException $e ){}
|
||||
catch( OutOfRangeException $e ){}
|
||||
|
||||
$log->delete();
|
||||
$count++;
|
||||
}
|
||||
|
||||
return $count ? TRUE : FALSE;
|
||||
return (bool) $count;
|
||||
} );
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,16 +11,22 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Digest\Digest as DigestClass;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* digest Task
|
||||
*/
|
||||
class _digest extends \IPS\Task
|
||||
class digest extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,13 +37,13 @@ class _digest extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$this->runUntilTimeout( function()
|
||||
{
|
||||
return \IPS\core\Digest\Digest::sendDigestBatch( 'daily' );
|
||||
return DigestClass::sendDigestBatch( 'daily' );
|
||||
});
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,16 +11,26 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use DateTimeZone;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* leaderboard Task
|
||||
*/
|
||||
class _leaderboard extends \IPS\Task
|
||||
class leaderboard extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,39 +41,39 @@ class _leaderboard extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Get the most recent update */
|
||||
$date = \IPS\Db::i()->select( 'MAX(leader_date)', 'core_reputation_leaderboard_history' )->first();
|
||||
$timezone = new \DateTimeZone( \IPS\Settings::i()->reputation_timezone );
|
||||
$date = Db::i()->select( 'MAX(leader_date)', 'core_reputation_leaderboard_history' )->first();
|
||||
$timezone = new DateTimeZone( Settings::i()->reputation_timezone );
|
||||
|
||||
if ( $date )
|
||||
{
|
||||
/* Only go back 10 days max */
|
||||
if ( $date < ( time() - 864000 ) )
|
||||
{
|
||||
$startDate = \IPS\DateTime::ts( time(), true )->setTimezone( $timezone )->sub( new \DateInterval('P10D') )->setTime( 0, 0, 1 );
|
||||
$startDate = DateTime::ts( time(), true )->setTimezone( $timezone )->sub( new DateInterval('P10D') )->setTime( 0, 0, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
$startDate = \IPS\DateTime::ts( $date, true )->setTimezone( $timezone )->setTime( 0, 0, 1 );
|
||||
$startDate = DateTime::ts( $date, true )->setTimezone( $timezone )->setTime( 0, 0, 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$startDate = new \IPS\DateTime( 'yesterday midnight', $timezone );
|
||||
$startDate = new DateTime( 'yesterday midnight', $timezone );
|
||||
|
||||
/* Do we need to run this task at all? If we don't have any records in core_reputation_index we can skip this task */
|
||||
$existing = \IPS\Db::i()->select( 'count(*)', 'core_reputation_index' )->first();
|
||||
$existing = Db::i()->select( 'count(*)', 'core_reputation_index' )->first();
|
||||
if ( !$existing )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
$yesterdayEnd = new \IPS\DateTime( 'today midnight', $timezone );
|
||||
$yesterdayEnd = new DateTime( 'today midnight', $timezone );
|
||||
|
||||
$diff = $startDate->diff( $yesterdayEnd );
|
||||
$difference = $diff->days > 0 ? $diff->days + 1 : 1;
|
||||
@@ -75,20 +85,20 @@ class _leaderboard extends \IPS\Task
|
||||
|
||||
/* As this can run multiple times, and the unique constraint is member_id, position, it is possible to end up with multiple members with the same positon */
|
||||
$date = $startDate->setTime( 12, 0 )->getTimeStamp();
|
||||
\IPS\Db::i()->delete( 'core_reputation_leaderboard_history', array( 'leader_date BETWEEN ? and ?', $date - 4, $date ) );
|
||||
Db::i()->delete( 'core_reputation_leaderboard_history', array( 'leader_date BETWEEN ? and ?', $date - 4, $date ) );
|
||||
|
||||
$where = array();
|
||||
$where[] = array( 'member_received > 0 AND rep_date BETWEEN ? and ?', $startDate->setTime( 0, 0, 1 )->getTimeStamp(), $startDate->setTime( 23, 59, 59 )->getTimeStamp() );
|
||||
$where[] = \IPS\Db::i()->in( 'member_group_id', explode( ',', \IPS\Settings::i()->leaderboard_excluded_groups ), TRUE );
|
||||
$where[] = Db::i()->in( 'member_group_id', explode( ',', Settings::i()->leaderboard_excluded_groups ), TRUE );
|
||||
|
||||
foreach( \IPS\Db::i()->select( 'core_reputation_index.member_received as themember, SUM(rep_rating) as rep', 'core_reputation_index', $where, 'rep DESC, themember ASC', 4, 'themember' )->join( 'core_members', 'core_members.member_id=core_reputation_index.member_received' )->setKeyField('themember')->setValueField('rep') as $member => $rep )
|
||||
foreach( Db::i()->select( 'core_reputation_index.member_received as themember, SUM(rep_rating) as rep', 'core_reputation_index', $where, 'rep DESC, themember ASC', 4, 'themember' )->join( 'core_members', 'core_members.member_id=core_reputation_index.member_received' )->setKeyField('themember')->setValueField('rep') as $member => $rep )
|
||||
{
|
||||
if ( $member and $rep )
|
||||
{
|
||||
$date = $startDate->setTime( 12, 0 )->getTimeStamp();
|
||||
$position++;
|
||||
|
||||
\IPS\Db::i()->replace( 'core_reputation_leaderboard_history', array(
|
||||
Db::i()->replace( 'core_reputation_leaderboard_history', array(
|
||||
'leader_date' => $date,
|
||||
'leader_member_id' => $member,
|
||||
'leader_position' => $position,
|
||||
@@ -110,7 +120,7 @@ class _leaderboard extends \IPS\Task
|
||||
{
|
||||
$position++;
|
||||
|
||||
\IPS\Db::i()->replace( 'core_reputation_leaderboard_history', array(
|
||||
Db::i()->replace( 'core_reputation_leaderboard_history', array(
|
||||
'leader_date' => $date - $position,
|
||||
'leader_member_id' => 0,
|
||||
'leader_position' => $position,
|
||||
@@ -119,8 +129,10 @@ class _leaderboard extends \IPS\Task
|
||||
}
|
||||
}
|
||||
|
||||
$startDate = $startDate->add( new \DateInterval('P1D') )->setTime( 0, 0, 1 );
|
||||
$startDate = $startDate->add( new DateInterval('P1D') )->setTime( 0, 0, 1 );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,28 +5,35 @@
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 13 Sep 2024
|
||||
* @since 02 Oct 2024
|
||||
*/
|
||||
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Exception;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception as TaskException;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Redis;
|
||||
use OutOfRangeException;
|
||||
use RedisException;
|
||||
use function array_key_exists;
|
||||
use function is_array;
|
||||
use function defined;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* nodeRecounts Task
|
||||
*/
|
||||
class _nodeRecounts extends \IPS\Task
|
||||
class nodeRecounts extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -37,28 +44,28 @@ class _nodeRecounts extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws TaskException
|
||||
*/
|
||||
public function execute(): mixed
|
||||
public function execute() : mixed
|
||||
{
|
||||
$allKeys = [];
|
||||
try
|
||||
{
|
||||
if( ! Redis::isEnabled() )
|
||||
{
|
||||
throw new \BadMethodCallException;
|
||||
throw new BadMethodCallException;
|
||||
}
|
||||
|
||||
$allKeys = Redis::i()->hGetAll('nodeSyncTimes');
|
||||
}
|
||||
catch( \BadMethodCallException | \RedisException )
|
||||
catch( BadMethodCallException | RedisException )
|
||||
{
|
||||
try
|
||||
{
|
||||
$key = 'nodeSyncTimes';
|
||||
$allKeys = Store::i()->$key;
|
||||
}
|
||||
catch( \OutOfRangeException ){}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
|
||||
if ( ! is_array( $allKeys ) or ! count( $allKeys ))
|
||||
@@ -85,7 +92,7 @@ class _nodeRecounts extends \IPS\Task
|
||||
/* Recount items, comments, reviews and the last comment data */
|
||||
$node->runScheduledRebuild();
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -106,7 +113,7 @@ class _nodeRecounts extends \IPS\Task
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function cleanup()
|
||||
public function cleanup() : void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -11,16 +11,24 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Session\Store;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* onlineusers Task
|
||||
*/
|
||||
class _onlineusers extends \IPS\Task
|
||||
class onlineusers extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,9 +39,9 @@ class _onlineusers extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* We want the rows to have the same timestamp exactly */
|
||||
$time = time();
|
||||
@@ -43,19 +51,19 @@ class _onlineusers extends \IPS\Task
|
||||
|
||||
try
|
||||
{
|
||||
$onlineGuests = \IPS\Session\Store::i()->getOnlineUsers( \IPS\Session\Store::ONLINE_GUESTS | \IPS\Session\Store::ONLINE_COUNT_ONLY, 'desc', NULL, NULL, TRUE );
|
||||
$onlineMembers = \IPS\Session\Store::i()->getOnlineUsers( \IPS\Session\Store::ONLINE_MEMBERS | \IPS\Session\Store::ONLINE_COUNT_ONLY, 'desc', NULL, NULL, TRUE );
|
||||
$onlineGuests = Store::i()->getOnlineUsers( Store::ONLINE_GUESTS | Store::ONLINE_COUNT_ONLY, 'desc', NULL, NULL, TRUE );
|
||||
$onlineMembers = Store::i()->getOnlineUsers( Store::ONLINE_MEMBERS | Store::ONLINE_COUNT_ONLY, 'desc', NULL, NULL, TRUE );
|
||||
}
|
||||
catch( \UnderflowException $e) {}
|
||||
catch( UnderflowException $e) {}
|
||||
|
||||
\IPS\Db::i()->insert( 'core_statistics', array(
|
||||
Db::i()->insert( 'core_statistics', array(
|
||||
'type' => 'online_users',
|
||||
'time' => $time,
|
||||
'value_4' => 'guests',
|
||||
'value_1' => $onlineGuests
|
||||
) );
|
||||
|
||||
\IPS\Db::i()->insert( 'core_statistics', array(
|
||||
Db::i()->insert( 'core_statistics', array(
|
||||
'type' => 'online_users',
|
||||
'time' => $time,
|
||||
'value_4' => 'members',
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief POP3 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 16 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* POP3 Task
|
||||
*/
|
||||
class _pop extends \IPS\Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* If ran successfully, should return anything worth logging. Only log something
|
||||
* worth mentioning (don't log "task ran successfully"). Return NULL (actual NULL, not '' or 0) to not log (which will be most cases).
|
||||
* If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
/* If we haven't set up POP3, disable ourselves */
|
||||
if ( !\IPS\Settings::i()->pop3_server )
|
||||
{
|
||||
$this->enabled = FALSE;
|
||||
$this->save();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
try
|
||||
{
|
||||
/* Connect */
|
||||
$pop3 = new \IPS\Email\Incoming\PopImap( \IPS\Settings::i()->pop3_server, \IPS\Settings::i()->pop3_tls, \IPS\Settings::i()->pop3_port, \IPS\Settings::i()->pop3_user, \IPS\Settings::i()->pop3_password );
|
||||
|
||||
/* Fetch emails */
|
||||
if ( $emailsInInbox = $pop3->emailsInInbox() )
|
||||
{
|
||||
foreach ( range( 1, min( $emailsInInbox, 50 ) ) as $i )
|
||||
{
|
||||
try
|
||||
{
|
||||
$incomingEmail = new \IPS\Email\Incoming\Email( $pop3->getEmail( $i ) );
|
||||
$incomingEmail->route();
|
||||
$pop3->deleteEmail( $i );
|
||||
}
|
||||
catch ( \IPS\Email\Incoming\PopImapException $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'pop3' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disconnect */
|
||||
unset( $pop3 );
|
||||
}
|
||||
catch ( \Exception $exception )
|
||||
{
|
||||
\IPS\Log::log( $exception, 'pop3' );
|
||||
throw new \IPS\Task\Exception( $this, $exception->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup
|
||||
*
|
||||
* If your task takes longer than 15 minutes to run, this method
|
||||
* will be called before execute(). Use it to clean up anything which
|
||||
* may not have been done
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,16 +11,26 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Email;
|
||||
use IPS\Lang;
|
||||
use IPS\Task;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* postBeforeRegisterFollowup Task
|
||||
*/
|
||||
class _postBeforeRegisterFollowup extends \IPS\Task
|
||||
class postBeforeRegisterFollowup extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,21 +41,21 @@ class _postBeforeRegisterFollowup extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$this->runUntilTimeout( function()
|
||||
{
|
||||
/* Get the email */
|
||||
try
|
||||
{
|
||||
$userData = \IPS\Db::i()->select( array( 'email', 'language', 'secret' ), 'core_post_before_registering', array( "`member` IS NULL and followup IS NULL and timestamp<" . ( time() - ( 86400 * 2 ) ) ), 'timestamp ASC', 1 )->first();
|
||||
$userData = Db::i()->select( array( 'email', 'language', 'secret' ), 'core_post_before_registering', array( "`member` IS NULL and followup IS NULL and timestamp<" . ( time() - ( 86400 * 2 ) ) ), 'timestamp ASC', 1 )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
/* Disable the task if there is nothing at all left to process */
|
||||
if( \IPS\Db::i()->select( 'COUNT(*)', 'core_post_before_registering', array( "`member` IS NULL") )->first() === 0 )
|
||||
if( Db::i()->select( 'COUNT(*)', 'core_post_before_registering', array( "`member` IS NULL") )->first() === 0 )
|
||||
{
|
||||
$this->enabled = FALSE;
|
||||
$this->save();
|
||||
@@ -56,7 +66,7 @@ class _postBeforeRegisterFollowup extends \IPS\Task
|
||||
|
||||
/* Get the associated content */
|
||||
$content = array();
|
||||
foreach ( \IPS\Db::i()->select( array( 'class', 'id' ), 'core_post_before_registering', array( 'email=?', $userData['email'] ) ) as $contentRow )
|
||||
foreach ( Db::i()->select( array( 'class', 'id' ), 'core_post_before_registering', array( 'email=?', $userData['email'] ) ) as $contentRow )
|
||||
{
|
||||
$class = $contentRow['class'];
|
||||
try
|
||||
@@ -64,14 +74,14 @@ class _postBeforeRegisterFollowup extends \IPS\Task
|
||||
/* Remove any data if the content class doesn't exist any more */
|
||||
if ( !class_exists( $class ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$content[] = $class::load( $contentRow['id'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_post_before_registering', array( 'class=? AND id=?', $contentRow['class'], $contentRow['id'] ) );
|
||||
Db::i()->delete( 'core_post_before_registering', array( 'class=? AND id=?', $contentRow['class'], $contentRow['id'] ) );
|
||||
}
|
||||
}
|
||||
if ( !$content )
|
||||
@@ -82,23 +92,25 @@ class _postBeforeRegisterFollowup extends \IPS\Task
|
||||
/* Build the email */
|
||||
try
|
||||
{
|
||||
$language = \IPS\Lang::load( $userData['language'] );
|
||||
$language = Lang::load( $userData['language'] );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
$language = \IPS\Lang::load( \IPS\Lang::defaultLanguage() );
|
||||
$language = Lang::load( Lang::defaultLanguage() );
|
||||
}
|
||||
$email = \IPS\Email::buildFromTemplate( 'core', 'postBeforeRegisterFollowup', array( $content, $userData['secret'] ), \IPS\Email::TYPE_BULK );
|
||||
$email = Email::buildFromTemplate( 'core', 'postBeforeRegisterFollowup', array( $content, $userData['secret'] ), Email::TYPE_BULK );
|
||||
$email->language = $language;
|
||||
$email->setUnsubscribe( 'core', 'unsubscribeNotNeeded' );
|
||||
$email->send( $userData['email'] );
|
||||
|
||||
/* Update the row */
|
||||
\IPS\Db::i()->update( 'core_post_before_registering', array( 'followup' => time() ), array( 'email=?', $userData['email'] ) );
|
||||
Db::i()->update( 'core_post_before_registering', array( 'followup' => time() ), array( 'email=?', $userData['email'] ) );
|
||||
|
||||
/* Return */
|
||||
return TRUE;
|
||||
} );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,23 +11,34 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Login;
|
||||
use IPS\Member;
|
||||
use IPS\Task;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile-sync Task
|
||||
*/
|
||||
class _profilesync extends \IPS\Task
|
||||
class profilesync extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Do we have any login methods that even support syncing enabled? */
|
||||
if( !$this->canSync() )
|
||||
@@ -38,7 +49,7 @@ class _profilesync extends \IPS\Task
|
||||
$where = array( array( "temp_ban=?", 0 ), array( "profilesync_lastsync > ?", 0 ) );
|
||||
|
||||
/* Only check accounts that have visited in the last 6 months */
|
||||
$where[] = array( "GREATEST(last_activity, last_visit) > ?", \IPS\DateTime::create()->sub( new \DateInterval('P6M') )->getTimestamp() );
|
||||
$where[] = array( "GREATEST(last_activity, last_visit) > ?", DateTime::create()->sub( new DateInterval('P6M') )->getTimestamp() );
|
||||
|
||||
/* And only check accounts that are actually synchronizing, UNLESS the admin is also forcing synchronization for any login methods */
|
||||
if( !$this->hasForcedSync() )
|
||||
@@ -47,7 +58,7 @@ class _profilesync extends \IPS\Task
|
||||
}
|
||||
|
||||
|
||||
$totalToSync = \IPS\Db::i()->select( 'count(*)', 'core_members', $where )->first();
|
||||
$totalToSync = Db::i()->select( 'count(*)', 'core_members', $where )->first();
|
||||
|
||||
if( !$totalToSync )
|
||||
{
|
||||
@@ -67,14 +78,14 @@ class _profilesync extends \IPS\Task
|
||||
{
|
||||
try
|
||||
{
|
||||
$member = \IPS\Db::i()->select( '*', 'core_members', $where, 'profilesync_lastsync ASC', 1 )->first();
|
||||
$member = Db::i()->select( '*', 'core_members', $where, 'profilesync_lastsync ASC', 1 )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$member = \IPS\Member::constructFromData( $member );
|
||||
$member = Member::constructFromData( $member );
|
||||
$member->profileSync();
|
||||
|
||||
return TRUE;
|
||||
@@ -88,9 +99,9 @@ class _profilesync extends \IPS\Task
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function canSync()
|
||||
protected function canSync() : bool
|
||||
{
|
||||
foreach ( \IPS\Login::methods() as $method )
|
||||
foreach ( Login::methods() as $method )
|
||||
{
|
||||
if( $method->hasSyncOptions() )
|
||||
{
|
||||
@@ -106,11 +117,11 @@ class _profilesync extends \IPS\Task
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasForcedSync()
|
||||
protected function hasForcedSync() : bool
|
||||
{
|
||||
foreach ( \IPS\Login::methods() as $method )
|
||||
foreach ( Login::methods() as $method )
|
||||
{
|
||||
if( \count( $method->forceSync() ) )
|
||||
if( count( $method->forceSync() ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,23 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* pruneipaddresses Task
|
||||
*/
|
||||
class _pruneipaddresses extends \IPS\Task
|
||||
class pruneipaddresses extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,17 +38,18 @@ class _pruneipaddresses extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
if ( \IPS\Settings::i()->ip_address_prune < 1 )
|
||||
if ( Settings::i()->ip_address_prune < 1 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
$time = time() - ( 86400 * \IPS\Settings::i()->ip_address_prune );
|
||||
\IPS\Member::pruneAllLoggedIpAddresses( $time );
|
||||
|
||||
|
||||
$time = time() - ( 86400 * Settings::i()->ip_address_prune );
|
||||
Member::pruneAllLoggedIpAddresses( $time );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,16 +11,26 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\Content\Search\Index;
|
||||
use IPS\DateTime;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use UnexpectedValueException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* prunesearchindex Task
|
||||
*/
|
||||
class _prunesearchindex extends \IPS\Task
|
||||
class prunesearchindex extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,18 +41,18 @@ class _prunesearchindex extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Prune search index */
|
||||
if ( \IPS\Settings::i()->search_method == 'mysql' and \IPS\Settings::i()->search_index_timeframe )
|
||||
if ( Settings::i()->search_method == 'mysql' and Settings::i()->search_index_timeframe )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->prune( \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->search_index_timeframe . 'D' ) ) );
|
||||
Index::i()->prune( DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->search_index_timeframe . 'D' ) ) );
|
||||
}
|
||||
catch ( \UnexpectedValueException $e ) { }
|
||||
catch ( UnexpectedValueException $e ) { }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,16 +11,23 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Log;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* prunesystemlogs Task
|
||||
*/
|
||||
class _prunesystemlogs extends \IPS\Task
|
||||
class prunesystemlogs extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,13 +38,13 @@ class _prunesystemlogs extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
if( \IPS\Settings::i()->prune_log_system )
|
||||
if( Settings::i()->prune_log_system )
|
||||
{
|
||||
\IPS\Log::pruneLogs( \IPS\Settings::i()->prune_log_system );
|
||||
Log::pruneLogs( Settings::i()->prune_log_system );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,16 +11,25 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Content;
|
||||
use IPS\Db;
|
||||
use IPS\IPS;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0') . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* publish Task
|
||||
*/
|
||||
class _publish extends \IPS\Task
|
||||
class publish extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -30,32 +39,35 @@ class _publish extends \IPS\Task
|
||||
* If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @return string|null Message to log or NULL
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$types = array();
|
||||
|
||||
foreach ( \IPS\Content::routedClasses( FALSE, FALSE, TRUE ) as $class )
|
||||
foreach ( Content::routedClasses( FALSE, FALSE, TRUE ) as $class )
|
||||
{
|
||||
if( is_subclass_of( $class, 'IPS\Content\FuturePublishing' ) )
|
||||
if( IPS::classUsesTrait( $class, 'IPS\Content\FuturePublishing' ) )
|
||||
{
|
||||
$types[] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
if( \count( $types ) )
|
||||
if( count( $types ) )
|
||||
{
|
||||
foreach( $types as $class )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', $class::$databaseTable, array( $class::$databasePrefix . $class::$databaseColumnMap['is_future_entry'] . '=1 and ' . $class::$databasePrefix . $class::$databaseColumnMap['date'] . ' <= ' . time() ) ) as $row )
|
||||
/* @var $databaseColumnMap array */
|
||||
foreach( Db::i()->select( '*', $class::$databaseTable, array( $class::$databasePrefix . $class::$databaseColumnMap['is_future_entry'] . '=1 and ' . $class::$databasePrefix . $class::$databaseColumnMap['date'] . ' <= ' . time() ) ) as $row )
|
||||
{
|
||||
$obj = $class::constructFromData( $row );
|
||||
$obj->publish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,16 +11,24 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* pwaprune Task
|
||||
*/
|
||||
class _pwaprune extends \IPS\Task
|
||||
class pwaprune extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,13 +39,13 @@ class _pwaprune extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$expiration = \IPS\DateTime::ts( time() )->sub( new \DateInterval( 'P2D' ) )->getTimestamp();
|
||||
$expiration = DateTime::ts( time() )->sub( new DateInterval( 'P2D' ) )->getTimestamp();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_notifications_pwa_queue', array( 'expiration<?', $expiration ) );
|
||||
Db::i()->delete( 'core_notifications_pwa_queue', array( 'expiration<?', $expiration ) );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,22 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue Task
|
||||
*/
|
||||
class _queue extends \IPS\Task
|
||||
class queue extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,28 +37,30 @@ class _queue extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$this->runUntilTimeout( function(){
|
||||
/* Try and get a queue item */
|
||||
try
|
||||
{
|
||||
/* Run the next queue task, if any */
|
||||
\IPS\Task::runQueue();
|
||||
Task::runQueue();
|
||||
|
||||
/* Continue */
|
||||
return TRUE;
|
||||
}
|
||||
/* If there's no queue items left, disable this task and return */
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
$this->enabled = FALSE;
|
||||
$this->save();
|
||||
return FALSE;
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,16 +12,26 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\core\Rss\Import;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* rssimport Task
|
||||
*/
|
||||
class _rssimport extends \IPS\Task
|
||||
class rssimport extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -32,27 +42,27 @@ class _rssimport extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$timeCheck = new \IPS\DateTime;
|
||||
$timeCheck->sub( new \DateInterval( 'PT10M' ) );
|
||||
$timeCheck = new DateTime;
|
||||
$timeCheck->sub( new DateInterval( 'PT10M' ) );
|
||||
|
||||
$this->runUntilTimeout(function() use ( $timeCheck ) {
|
||||
try
|
||||
{
|
||||
$feed = \IPS\core\Rss\Import::constructFromData( \IPS\Db::i()->select( '*', 'core_rss_import', array( 'rss_import_enabled=1 AND rss_import_last_import<?', $timeCheck->getTimestamp() ), 'rss_import_last_import ASC', 1 )->first() );
|
||||
$feed = Import::constructFromData( Db::i()->select( '*', 'core_rss_import', array( 'rss_import_enabled=1 AND rss_import_last_import<?', $timeCheck->getTimestamp() ), 'rss_import_last_import ASC', 1 )->first() );
|
||||
$feed->run();
|
||||
}
|
||||
/* There's nothing more left to process */
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
/* Check to see if there are any feeds.. If no feed, we can disable the task */
|
||||
if( !\IPS\Db::i()->select( 'count(rss_import_id)', 'core_rss_import', array( 'rss_import_enabled=1' ), NULL, 1 )->first() )
|
||||
if( !Db::i()->select( 'count(rss_import_id)', 'core_rss_import', array( 'rss_import_enabled=1' ), NULL, 1 )->first() )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 'rssimport' ) );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 'rssimport' ) );
|
||||
}
|
||||
|
||||
/* No further processing needed */
|
||||
@@ -62,17 +72,19 @@ class _rssimport extends \IPS\Task
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
/* If there is an error, we need to log it but the error should not prevent other feeds from importing */
|
||||
if ( isset( $feed ) AND ( $feed instanceof \IPS\core\Rss\Import ) )
|
||||
if ( isset( $feed ) AND ( $feed instanceof Import ) )
|
||||
{
|
||||
$feed->last_import = time();
|
||||
$feed->save();
|
||||
}
|
||||
throw new \IPS\Task\Exception( $this, $e->getMessage() );
|
||||
throw new Exception( $this, $e->getMessage() );
|
||||
}
|
||||
|
||||
/* Run again to see if there's anything left */
|
||||
return TRUE;
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,16 +11,26 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\File;
|
||||
use IPS\File\Amazon;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* s3Delete Task
|
||||
* s3_delete Task
|
||||
*/
|
||||
class _s3Delete extends \IPS\Task
|
||||
class s3Delete extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,30 +41,30 @@ class _s3Delete extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
try
|
||||
{
|
||||
$s3 = \IPS\Db::i()->select( '*', 'core_s3_deletions' )->first();
|
||||
$s3 = Db::i()->select( '*', 'core_s3_deletions' )->first();
|
||||
|
||||
$obj = \IPS\File::getClass('core_Theme');
|
||||
$obj = File::getClass('core_Theme');
|
||||
|
||||
if ( !( $obj instanceof \IPS\File\Amazon ) )
|
||||
if ( !( $obj instanceof Amazon ) )
|
||||
{
|
||||
/* Class is not Amazon, so just stop here and truncate the table as there's nothing we can really do now. */
|
||||
\IPS\Db::i()->delete( 'core_s3_deletions' );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 's3Delete' ) );
|
||||
Db::i()->delete( 'core_s3_deletions' );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 's3Delete' ) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$keys = $obj->getContainerKeys( $s3['s3_container'], 101, '', $s3['s3_marker'] );
|
||||
$keys = $obj->getContainerKeys( $s3['s3_container'], 101, '', ( $s3['s3_marker'] ?? '' ) );
|
||||
|
||||
if ( \count( $keys ) )
|
||||
if ( count( $keys ) )
|
||||
{
|
||||
/* Get the 51st key, which will be the marker for the next iteration if we have 51 keys, otherwise, make marker null so it's removed in the next iteration */
|
||||
if ( \count( $keys ) < 101 )
|
||||
if ( count( $keys ) < 101 )
|
||||
{
|
||||
$marker = NULL;
|
||||
}
|
||||
@@ -70,31 +80,31 @@ class _s3Delete extends \IPS\Task
|
||||
{
|
||||
if ( $time <= $s3['s3_added'] )
|
||||
{
|
||||
\IPS\File::getClass('core_Theme')->deleteByKey( $key );
|
||||
File::getClass('core_Theme')->deleteByKey( $key );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $marker )
|
||||
{
|
||||
/* Update the marker, there may be more to go */
|
||||
\IPS\Db::i()->update( 'core_s3_deletions', array( 's3_marker' => $marker ), array( 's3_container=?', $s3['s3_container'] ) );
|
||||
Db::i()->update( 'core_s3_deletions', array( 's3_marker' => $marker ), array( 's3_container=?', $s3['s3_container'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Last batch, possible some keys not deleted if time didn't match */
|
||||
\IPS\Db::i()->delete( 'core_s3_deletions', array( 's3_container=?', $s3['s3_container'] ) );
|
||||
Db::i()->delete( 'core_s3_deletions', array( 's3_container=?', $s3['s3_container'] ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If no keys, delete container row from s3_deletions */
|
||||
\IPS\Db::i()->delete( 'core_s3_deletions', array( 's3_container=?', $s3['s3_container'] ) );
|
||||
Db::i()->delete( 'core_s3_deletions', array( 's3_container=?', $s3['s3_container'] ) );
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $ex )
|
||||
catch( UnderflowException $ex )
|
||||
{
|
||||
/* Nothing to do, so switch off the task */
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 's3Delete' ) );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 's3Delete' ) );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,25 +11,33 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Log;
|
||||
use IPS\Sitemap;
|
||||
use IPS\Task;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Task to generate sitemaps
|
||||
*/
|
||||
class _sitemapgenerator extends \IPS\Task
|
||||
class sitemapgenerator extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$generator = new \IPS\Sitemap;
|
||||
$generator = new Sitemap;
|
||||
|
||||
$this->runUntilTimeout( function() use( $generator )
|
||||
{
|
||||
@@ -38,15 +46,15 @@ class _sitemapgenerator extends \IPS\Task
|
||||
/* If it returns false, we're done for now */
|
||||
return $generator->buildNextSitemap();
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'sitemap_generator' );
|
||||
Log::log( $e, 'sitemap_generator' );
|
||||
$generator->log[] = $e->getMessage();
|
||||
return FALSE;
|
||||
}
|
||||
} );
|
||||
|
||||
if( \count( $generator->log ) )
|
||||
if( count( $generator->log ) )
|
||||
{
|
||||
return $generator->log;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,27 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock Members Task
|
||||
*/
|
||||
class _unlockmembers extends \IPS\Task
|
||||
class unlockmembers extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -30,22 +41,29 @@ class _unlockmembers extends \IPS\Task
|
||||
* If an error occurs which means the task could not finish running, throw an \IPS\Task\Exception - do not log an error as a normal log.
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws Exception|\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
if( !\IPS\Settings::i()->ipb_bruteforce_unlock or !\IPS\Settings::i()->ipb_bruteforce_period or !\IPS\Settings::i()->ipb_bruteforce_attempts )
|
||||
if( !Settings::i()->ipb_bruteforce_unlock or !Settings::i()->ipb_bruteforce_period or !Settings::i()->ipb_bruteforce_attempts )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Clear out old data */
|
||||
\IPS\Db::i()->delete( 'core_login_failures', [ 'login_date<? AND login_ip_address IS NOT NULL AND login_member_id IS NOT NULL', ( new \IPS\DateTime() )->sub( new \DateInterval( 'PT' . \IPS\Settings::i()->ipb_bruteforce_period . 'M' ) )->getTimestamp() ] );
|
||||
Db::i()->delete( 'core_login_failures', [ 'login_date<? AND login_ip_address IS NOT NULL AND login_member_id IS NOT NULL', ( new DateTime() )->sub( new DateInterval( 'PT' . Settings::i()->ipb_bruteforce_period . 'M' ) )->getTimestamp() ] );
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_members', array( 'failed_login_count >= ?', \IPS\Settings::i()->ipb_bruteforce_attempts ) ), 'IPS\Member') AS $member )
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', 'core_members', array( 'failed_login_count >= ?', Settings::i()->ipb_bruteforce_attempts ) ), 'IPS\Member') AS $member )
|
||||
{
|
||||
$member->recountFailedLogins();
|
||||
$where = [
|
||||
'login_date>=? AND login_ip_address IS NOT NULL AND login_member_id=?',
|
||||
( new DateTime )->sub( new DateInterval( 'PT' . Settings::i()->ipb_bruteforce_period . 'M' ) )->getTimestamp(),
|
||||
$this->member_id
|
||||
];
|
||||
$member->failed_login_count = max( iterator_to_array( Db::i()->select( 'count(login_ip_address)', 'core_login_failures', $where, NULL, NULL, 'login_ip_address' ) ) );
|
||||
|
||||
$member->save();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -11,37 +11,58 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Application;
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Lang;
|
||||
use IPS\Log;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
use UnderflowException;
|
||||
use UnexpectedValueException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use const IPS\IPS_ALPHA_BUILD;
|
||||
use const IPS\USE_DEVELOPMENT_BUILDS;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* updatecheck Task
|
||||
*/
|
||||
class _updatecheck extends \IPS\Task
|
||||
class updatecheck extends Task
|
||||
{
|
||||
/**
|
||||
* @brief Type to send to update server
|
||||
*/
|
||||
public $type = 'task';
|
||||
public string $type = 'task';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Refresh stored license data */
|
||||
\IPS\IPS::licenseKey( TRUE );
|
||||
IPS::licenseKey( TRUE );
|
||||
|
||||
$fails = array();
|
||||
|
||||
/* Do IPS apps */
|
||||
$versions = array();
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_applications', \IPS\Db::i()->in( 'app_directory', \IPS\IPS::$ipsApps ) ) as $app )
|
||||
foreach ( Db::i()->select( '*', 'core_applications', Db::i()->in( 'app_directory', IPS::$ipsApps ) ) as $app )
|
||||
{
|
||||
if ( $app['app_enabled'] )
|
||||
{
|
||||
@@ -49,12 +70,12 @@ class _updatecheck extends \IPS\Task
|
||||
}
|
||||
}
|
||||
$version = min( $versions );
|
||||
$url = \IPS\Http\Url::ips('updateCheck')->setQueryString( array( 'type' => $this->type, 'key' => \IPS\Settings::i()->ipb_reg_number ) );
|
||||
if ( \IPS\USE_DEVELOPMENT_BUILDS )
|
||||
$url = Url::ips('updateCheck5')->setQueryString( array( 'type' => $this->type, 'key' => Settings::i()->ipb_reg_number ) );
|
||||
if ( USE_DEVELOPMENT_BUILDS )
|
||||
{
|
||||
$url = $url->setQueryString( 'development', 1 );
|
||||
}
|
||||
if ( \IPS\IPS_ALPHA_BUILD )
|
||||
if ( IPS_ALPHA_BUILD )
|
||||
{
|
||||
$url = $url->setQueryString( 'alpha', 1 );
|
||||
}
|
||||
@@ -62,31 +83,31 @@ class _updatecheck extends \IPS\Task
|
||||
{
|
||||
$response = $url->setQueryString( 'version', $version )->request()->get()->decodeJson();
|
||||
|
||||
$coreApp = \IPS\Application::load('core');
|
||||
$coreApp = Application::load('core');
|
||||
$coreApp->update_version = json_encode( $response );
|
||||
$coreApp->update_last_check = time();
|
||||
$coreApp->save();
|
||||
|
||||
/* Send a notification if new version is available */
|
||||
if ( $updates = $coreApp->availableUpgrade() and \count( $updates ) )
|
||||
if ( $updates = $coreApp->availableUpgrade( TRUE ) and count( $updates ) )
|
||||
{
|
||||
\IPS\core\AdminNotification::send( 'core', 'NewVersion', NULL, FALSE );
|
||||
AdminNotification::send( 'core', 'NewVersion', NULL, FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\core\AdminNotification::remove( 'core', 'NewVersion' );
|
||||
AdminNotification::remove( 'core', 'NewVersion' );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception $e ) { }
|
||||
|
||||
/* Check for bulletins while we're here */
|
||||
try
|
||||
{
|
||||
$bulletins = \IPS\Http\Url::ips('bulletin')->request()->get()->decodeJson();
|
||||
$bulletins = Url::ips('bulletin')->request()->get()->decodeJson();
|
||||
|
||||
foreach ( $bulletins as $id => $bulletin )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_ips_bulletins', array(
|
||||
Db::i()->insert( 'core_ips_bulletins', array(
|
||||
|
||||
'id' => $id,
|
||||
'title' => $bulletin['title'],
|
||||
@@ -108,36 +129,36 @@ class _updatecheck extends \IPS\Task
|
||||
/* If the value is 0 for minVersion, there is no minimum version (a.k.a., display it). Same deal with maxVersion. */
|
||||
( $bulletin['minVersion'] == 0 AND $bulletin['maxVersion'] == 0 )
|
||||
/* If there's no minimum version, and the maximum Version is within range */
|
||||
OR ( $bulletin['minVersion'] == 0 AND \IPS\Application::load('core')->long_version < $bulletin['maxVersion'] )
|
||||
OR ( $bulletin['minVersion'] == 0 AND Application::load('core')->long_version < $bulletin['maxVersion'] )
|
||||
/* If there's no maximum version, and the minimum version is within range */
|
||||
OR ( $bulletin['maxVersion'] == 0 AND \IPS\Application::load('core')->long_version > $bulletin['minVersion'] )
|
||||
OR ( $bulletin['maxVersion'] == 0 AND Application::load('core')->long_version > $bulletin['minVersion'] )
|
||||
/* If both min and max versions are within range */
|
||||
OR ( \IPS\Application::load('core')->long_version >= $bulletin['minVersion'] AND \IPS\Application::load('core')->long_version <= $bulletin['maxVersion'] )
|
||||
OR ( Application::load('core')->long_version >= $bulletin['minVersion'] AND Application::load('core')->long_version <= $bulletin['maxVersion'] )
|
||||
)
|
||||
{
|
||||
if ( @eval( $bulletin['conditions'] ) )
|
||||
{
|
||||
\IPS\core\AdminNotification::send( 'core', 'Bulletin', (string) $id, FALSE );
|
||||
AdminNotification::send( 'core', 'Bulletin', (string) $id, FALSE );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
\IPS\core\AdminNotification::remove( 'core', 'Bulletin', (string) $id );
|
||||
AdminNotification::remove( 'core', 'Bulletin', (string) $id );
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
\IPS\core\AdminNotification::remove( 'core', 'Bulletin', (string) $id );
|
||||
AdminNotification::remove( 'core', 'Bulletin', (string) $id );
|
||||
}
|
||||
}
|
||||
catch ( \Throwable | \Exception $e )
|
||||
catch ( Throwable | Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'bulletin' );
|
||||
Log::log( $e, 'bulletin' );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \RuntimeException $e ){ }
|
||||
catch( RuntimeException $e ){ }
|
||||
|
||||
$updateChecked = [];
|
||||
$fails = [];
|
||||
@@ -146,18 +167,17 @@ class _updatecheck extends \IPS\Task
|
||||
$this->runUntilTimeout( function() use ( &$updateChecked, &$fails, $version, $fiveMinutesAgo ) {
|
||||
try
|
||||
{
|
||||
$row = \IPS\Db::i()->union(
|
||||
$row = Db::i()->union(
|
||||
array(
|
||||
\IPS\Db::i()->select( "'core_applications' AS `table`, app_directory AS `id`, app_update_check AS `url`, app_update_last_check AS `last`, app_long_version AS `current`", 'core_applications', "app_update_last_check<{$fiveMinutesAgo} AND ( app_update_check<>'' AND app_update_check IS NOT NULL )" ),
|
||||
\IPS\Db::i()->select( "'core_plugins' AS `table`, plugin_id AS id, plugin_update_check as url, plugin_update_check_last AS last, plugin_version_long AS `current`", 'core_plugins', "plugin_update_check_last<{$fiveMinutesAgo} AND ( plugin_update_check<>'' AND plugin_update_check IS NOT NULL )" ),
|
||||
\IPS\Db::i()->select( "'core_themes' AS `table`, set_id AS `id`, set_update_check AS `url`, set_update_last_check AS `last`, set_long_version AS `current`", 'core_themes', "set_update_last_check<{$fiveMinutesAgo} AND ( set_update_check<>'' AND set_update_check IS NOT NULL )" ),
|
||||
\IPS\Db::i()->select( "'core_sys_lang' AS `table`, lang_id AS `id`, `lang_update_url` AS `url`, `lang_update_check` AS `last`, `lang_version_long` AS `current`", "core_sys_lang", "lang_update_check<{$fiveMinutesAgo} AND ( lang_update_url<>'' AND lang_update_url IS NOT NULL )" )
|
||||
Db::i()->select( "'core_applications' AS `table`, app_directory AS `id`, app_update_check AS `url`, app_update_last_check AS `last`, app_long_version AS `current`", 'core_applications', "app_update_last_check<{$fiveMinutesAgo} AND ( app_update_check<>'' AND app_update_check IS NOT NULL )" ),
|
||||
Db::i()->select( "'core_themes' AS `table`, set_id AS `id`, set_update_check AS `url`, set_update_last_check AS `last`, set_long_version AS `current`", 'core_themes', "set_update_last_check<{$fiveMinutesAgo} AND (set_update_check<>'' AND set_update_check IS NOT NULL )" ),
|
||||
Db::i()->select( "'core_sys_lang' AS `table`, lang_id AS `id`, `lang_update_url` AS `url`, `lang_update_check` AS `last`, `lang_version_long` AS `current`", "core_sys_lang", "lang_update_check<{$fiveMinutesAgo} AND (lang_update_url<>'' AND lang_update_url IS NOT NULL )" )
|
||||
),
|
||||
'last ASC',
|
||||
1
|
||||
)->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
catch( UnderflowException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -174,28 +194,20 @@ class _updatecheck extends \IPS\Task
|
||||
try
|
||||
{
|
||||
$key = "__app_{$row['id']}";
|
||||
$source = \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( $key );
|
||||
$source = Lang::load( Lang::defaultLanguage() )->get( $key );
|
||||
}
|
||||
catch ( \UnderflowException | \UnexpectedValueException $e )
|
||||
catch ( UnderflowException | UnexpectedValueException $e )
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'core_plugins':
|
||||
$dataColumn = 'plugin_update_check_data';
|
||||
$timeColumn = 'plugin_update_check_last';
|
||||
$idColumn = 'plugin_id';
|
||||
$source = \IPS\Plugin::load( $row['id'] )->name;
|
||||
$updateChecked[] = 'plugins';
|
||||
break;
|
||||
|
||||
case 'core_themes':
|
||||
$dataColumn = 'set_update_data';
|
||||
$timeColumn = 'set_update_last_check';
|
||||
$idColumn = 'set_id';
|
||||
$key = "core_theme_set_title_{$row['id']}";
|
||||
$source = \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( $key );
|
||||
$source = Lang::load( Lang::defaultLanguage() )->get( $key );
|
||||
$updateChecked[] = 'themes';
|
||||
break;
|
||||
|
||||
@@ -203,14 +215,14 @@ class _updatecheck extends \IPS\Task
|
||||
$dataColumn = 'lang_update_data';
|
||||
$timeColumn = 'lang_update_check';
|
||||
$idColumn = 'lang_id';
|
||||
$source = \IPS\Lang::load( $row['id'] )->_title;
|
||||
$source = Lang::load( $row['id'] )->_title;
|
||||
$updateChecked[] = 'languages';
|
||||
break;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$url = \IPS\Http\Url::external( $row['url'] )->setQueryString( array( 'version' => $row['current'], 'ips_version' => $version ) );
|
||||
$url = Url::external( $row['url'] )->setQueryString( array( 'version' => $row['current'], 'ips_version' => $version ) );
|
||||
$response = $url->request()->get()->decodeJson();
|
||||
|
||||
/* Unset the object so it isn't present for next update check. */
|
||||
@@ -219,28 +231,28 @@ class _updatecheck extends \IPS\Task
|
||||
/* Did we get all the information we need? */
|
||||
if ( !isset( $response['version'], $response['longversion'], $response['released'], $response['updateurl'] ) )
|
||||
{
|
||||
throw new \RuntimeException( \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( 'update_check_missing' ) );
|
||||
throw new RuntimeException( Lang::load( Lang::defaultLanguage() )->get( 'update_check_missing' ) );
|
||||
}
|
||||
|
||||
/* Save the latest version data and move on to the next app */
|
||||
\IPS\Db::i()->update( $row['table'], array(
|
||||
Db::i()->update( $row['table'], array(
|
||||
$dataColumn => json_encode( array(
|
||||
'version' => $response['version'],
|
||||
'longversion' => $response['longversion'],
|
||||
'released' => $response['released'],
|
||||
'updateurl' => $response['updateurl'],
|
||||
'releasenotes' => isset( $response['releasenotes'] ) ? $response['releasenotes'] : NULL
|
||||
'releasenotes' => $response['releasenotes'] ?? NULL
|
||||
) ),
|
||||
$timeColumn => time()
|
||||
), array( "{$idColumn}=?", $row['id'] ) );
|
||||
}
|
||||
/* \RuntimeException catches BAD_JSON and \IPS\Http\Request\Exception both */
|
||||
catch ( \RuntimeException $e )
|
||||
catch ( RuntimeException $e )
|
||||
{
|
||||
$fails[] = $source . ": " . $e->getMessage();
|
||||
|
||||
/* Save the time so that the next time the task runs it can move on to other apps/plugins/themes */
|
||||
\IPS\Db::i()->update( $row['table'], array(
|
||||
Db::i()->update( $row['table'], array(
|
||||
$timeColumn => time()
|
||||
), array( "{$idColumn}=?", $row['id'] ) );
|
||||
}
|
||||
@@ -252,7 +264,7 @@ class _updatecheck extends \IPS\Task
|
||||
foreach( $updateChecked as $type )
|
||||
{
|
||||
$key = 'updatecount_' . $type;
|
||||
unset( \IPS\Data\Store::i()->$key, \IPS\Data\Store::i()->$type );
|
||||
unset( Store::i()->$key, Store::i()->$type );
|
||||
}
|
||||
|
||||
if ( !empty( $fails ) )
|
||||
|
||||
@@ -11,16 +11,37 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Application;
|
||||
use IPS\convert\App;
|
||||
use IPS\Db;
|
||||
use IPS\File;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Lang;
|
||||
use IPS\Login;
|
||||
use IPS\nexus\Gateway;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* usagereporting Task
|
||||
*/
|
||||
class _usagereporting extends \IPS\Task
|
||||
class usagereporting extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,19 +52,19 @@ class _usagereporting extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Check usage reporting is enabled */
|
||||
if ( !\IPS\Settings::i()->usage_reporting )
|
||||
if ( !Settings::i()->usage_reporting )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 'usagereporting' ) );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 'usagereporting' ) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check this isn't a test install */
|
||||
$licenseData = \IPS\IPS::licenseKey();
|
||||
$licenseData = IPS::licenseKey();
|
||||
if ( \IPS\IN_DEV or !$licenseData or mb_substr( $licenseData['key'], -12 ) === '-TESTINSTALL' )
|
||||
{
|
||||
return NULL;
|
||||
@@ -52,13 +73,13 @@ class _usagereporting extends \IPS\Task
|
||||
/* Send the report */
|
||||
try
|
||||
{
|
||||
$response = \IPS\Http\Url::external('https://invisionpowerdiagnostics.com/usage/')->request(2)->post( $this->buildReport() ); // Timeout is deliberately very low because we don't care if it times out (but not 0 because we still need to let the DNS resolve)
|
||||
$response = Url::external('https://invisionpowerdiagnostics.com/usage/')->request(2)->post( $this->buildReport() ); // Timeout is deliberately very low because we don't care if it times out (but not 0 because we still need to let the DNS resolve)
|
||||
|
||||
/* If the server has asked us to stop sending reports, then turn it off */
|
||||
if ( $response->httpResponseCode == 410 )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'usage_reporting' => 0 ) );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 'usagereporting' ) );
|
||||
Settings::i()->changeValues( array( 'usage_reporting' => 0 ) );
|
||||
Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( '`key`=?', 'usagereporting' ) );
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
@@ -74,33 +95,33 @@ class _usagereporting extends \IPS\Task
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final protected function buildReport()
|
||||
final protected function buildReport() : array
|
||||
{
|
||||
/* Identifier which allows us to keep separate reports from this community
|
||||
from other reports (so we can see how communities change things as they grow) but
|
||||
does NOT allow us to identify which community is sending the report */
|
||||
$report = array( 'anonymized_id' => md5( \IPS\Settings::i()->base_url . \IPS\Settings::i()->site_secret_key ) );
|
||||
$report = array( 'anonymized_id' => md5( Settings::i()->base_url . Settings::i()->site_secret_key ) );
|
||||
|
||||
/* Community data */
|
||||
$licenseData = \IPS\IPS::licenseKey(); // this is just to know if it is *active* and if it is CiC - we don't actually send the license key
|
||||
$licenseData = IPS::licenseKey(); // this is just to know if it is *active* and if it is CiC - we don't actually send the license key
|
||||
$report['community'] = array(
|
||||
'version' => \IPS\Application::load('core')->version,
|
||||
'installed' => date( 'Y-m-d', \IPS\Settings::i()->board_start ),
|
||||
'active_license'=> $licenseData ? ( (bool) $licenseData['active'] ) : FALSE,
|
||||
'cloud' => $licenseData ? ( (bool) $licenseData['cloud'] ) : FALSE,
|
||||
'version' => Application::load('core')->version,
|
||||
'installed' => date( 'Y-m-d', Settings::i()->board_start ),
|
||||
'active_license'=> $licenseData && $licenseData['active'],
|
||||
'cloud' => $licenseData && $licenseData['cloud'],
|
||||
);
|
||||
|
||||
/* Server Data */
|
||||
$report['server'] = array(
|
||||
'php_version' => PHP_VERSION_ID,
|
||||
'php_extensions' => get_loaded_extensions(),
|
||||
'mysql_version' => \IPS\Db::i()->server_version,
|
||||
'mysql_version' => Db::i()->server_version,
|
||||
'os' => PHP_OS,
|
||||
);
|
||||
|
||||
/* Apps */
|
||||
$report['apps'] = array();
|
||||
foreach ( \IPS\Application::applications() as $app )
|
||||
foreach ( Application::applications() as $app )
|
||||
{
|
||||
if ( $app->enabled )
|
||||
{
|
||||
@@ -108,41 +129,31 @@ class _usagereporting extends \IPS\Task
|
||||
}
|
||||
}
|
||||
|
||||
/* Plugins */
|
||||
$report['plugins'] = array();
|
||||
foreach ( \IPS\Plugin::plugins() as $plugin )
|
||||
{
|
||||
if ( $plugin->enabled )
|
||||
{
|
||||
$report['plugins'][ $plugin->location ] = $plugin->version_long;
|
||||
}
|
||||
}
|
||||
|
||||
/* Themes */
|
||||
$report['themes'] = array();
|
||||
foreach ( \IPS\Theme::themes() as $theme )
|
||||
foreach ( Theme::themes() as $theme )
|
||||
{
|
||||
$settings = array();
|
||||
foreach ( $theme->settings as $k => $v )
|
||||
{
|
||||
if ( \in_array( $k, array( 'responsive', 'rounded_photos', 'social_links', 'sidebar_position', 'sidebar_responsive', 'enable_fluid_width', 'fluid_width_size', 'js_incclude', 'ajax_pagination', 'cm_store_view', 'body_font', 'headline_font' ) ) )
|
||||
if ( in_array( $k, array( 'responsive', 'rounded_photos', 'social_links', 'sidebar_position', 'sidebar_responsive', 'enable_fluid_width', 'fluid_width_size', 'js_incclude', 'ajax_pagination', 'cm_store_view', 'body_font', 'headline_font' ) ) )
|
||||
{
|
||||
$settings[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
$report['themes'][] = array(
|
||||
'customised' => \IPS\Db::i()->select( 'COUNT(*)', 'core_theme_templates', array( 'template_set_id=?', $theme->id ) )->first(),
|
||||
'customised' => Db::i()->select( 'COUNT(*)', 'core_theme_templates', array( 'template_set_id=?', $theme->id ) )->first(),
|
||||
'settings' => $settings,
|
||||
);
|
||||
}
|
||||
|
||||
/* Languages */
|
||||
$report['languages'] = array();
|
||||
foreach ( \IPS\Lang::languages() as $lang )
|
||||
foreach ( Lang::languages() as $lang )
|
||||
{
|
||||
$localeDot = \strpos( $lang->short, '.' );
|
||||
$langKey = $localeDot ? \substr( $lang->short, 0, $localeDot ) : $lang->short;
|
||||
$localeDot = strpos( $lang->short, '.' );
|
||||
$langKey = $localeDot ? substr( $lang->short, 0, $localeDot ) : $lang->short;
|
||||
|
||||
if ( !isset( $report['languages'][ $langKey ] ) )
|
||||
{
|
||||
@@ -152,9 +163,9 @@ class _usagereporting extends \IPS\Task
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
foreach ( \IPS\Db::i()->select( array( 'conf_key', 'conf_value', 'conf_default', 'conf_app', 'conf_report' ), 'core_sys_conf_settings', 'conf_report IS NOT NULL' ) as $row )
|
||||
foreach ( Db::i()->select( array( 'conf_key', 'conf_value', 'conf_default', 'conf_app', 'conf_report' ), 'core_sys_conf_settings', 'conf_report IS NOT NULL' ) as $row )
|
||||
{
|
||||
if ( \in_array( $row['conf_app'], \IPS\IPS::$ipsApps ) and \IPS\Application::appIsEnabled( $row['conf_app'] ) )
|
||||
if ( in_array( $row['conf_app'], IPS::$ipsApps ) and Application::appIsEnabled( $row['conf_app'] ) )
|
||||
{
|
||||
if ( $row['conf_report'] == 'full' )
|
||||
{
|
||||
@@ -168,15 +179,15 @@ class _usagereporting extends \IPS\Task
|
||||
}
|
||||
|
||||
/* Database counts */
|
||||
foreach ( \IPS\IPS::$ipsApps as $app )
|
||||
foreach ( IPS::$ipsApps as $app )
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled( $app ) and file_exists( \IPS\ROOT_PATH . "/applications/{$app}/data/schema.json" ) )
|
||||
if ( Application::appIsEnabled( $app ) and file_exists( \IPS\ROOT_PATH . "/applications/{$app}/data/schema.json" ) )
|
||||
{
|
||||
foreach ( json_decode( file_get_contents( \IPS\ROOT_PATH . "/applications/{$app}/data/schema.json" ), TRUE ) as $table => $data )
|
||||
{
|
||||
if ( isset( $data['reporting'] ) and $data['reporting'] === 'count' )
|
||||
{
|
||||
$report['tables'][ $table ] = \IPS\Db::i()->select( 'COUNT(*)', $table )->first();
|
||||
$report['tables'][ $table ] = Db::i()->select( 'COUNT(*)', $table )->first();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,11 +195,11 @@ class _usagereporting extends \IPS\Task
|
||||
|
||||
/* File storage configurations */
|
||||
$report['files'] = array( 'amazon' => 0, 'database' => 0, 'filesystem' => 0, 'ftp' => 0, 'other' => 0 );
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'FileStorage', FALSE ) as $k => $v )
|
||||
foreach ( Application::allExtensions( 'core', 'FileStorage', FALSE ) as $k => $v )
|
||||
{
|
||||
try
|
||||
{
|
||||
$class = \strtolower( \substr( \get_class( \IPS\File::getClass( $k ) ), 9 ) );
|
||||
$class = strtolower( substr( get_class( File::getClass( $k ) ), 9 ) );
|
||||
|
||||
if ( isset( $report['files'][ $class ] ) )
|
||||
{
|
||||
@@ -199,7 +210,7 @@ class _usagereporting extends \IPS\Task
|
||||
$report['files']['other']++;
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception $e ) { }
|
||||
}
|
||||
|
||||
/* Login methods */
|
||||
@@ -221,9 +232,9 @@ class _usagereporting extends \IPS\Task
|
||||
$report['login'][ $v ] = 0;
|
||||
}
|
||||
$report['login']['other'] = 0;
|
||||
foreach ( \IPS\Login::methods() as $method )
|
||||
foreach ( Login::methods() as $method )
|
||||
{
|
||||
$class = \get_class( $method );
|
||||
$class = get_class( $method );
|
||||
if ( array_key_exists( $class, $loginMethods ) )
|
||||
{
|
||||
$report['login'][ $loginMethods[ $class ] ]++;
|
||||
@@ -236,19 +247,15 @@ class _usagereporting extends \IPS\Task
|
||||
|
||||
/* Payment methods */
|
||||
$report['paymethods'] = array();
|
||||
if ( \IPS\Application::appIsEnabled('nexus') )
|
||||
if ( Application::appIsEnabled('nexus') )
|
||||
{
|
||||
$report['paymethods'] = array( 'authorizenet_aim' => 0, 'authorizenet_dpm' => 0, 'manual' => 0, 'paypal_standard' => 0, 'paypal_pro' => 0, 'stripe_card' => 0, 'stripe_native' => 0, 'stripe_alipay' => 0, 'stripe_bancontact' => 0, 'stripe_giropay' => 0, 'stripe_ideal' => 0, 'stripe_sofort' => 0, 'test' => 0, 'twocheckout' => 0, 'other' => 0 );
|
||||
foreach ( \IPS\nexus\Gateway::roots() as $gateway )
|
||||
$report['paymethods'] = array( 'manual' => 0, 'paypal_standard' => 0, 'paypal_pro' => 0, 'stripe_card' => 0, 'stripe_native' => 0, 'stripe_alipay' => 0, 'stripe_bancontact' => 0, 'stripe_giropay' => 0, 'stripe_ideal' => 0, 'stripe_sofort' => 0, 'test' => 0, 'other' => 0 );
|
||||
foreach ( Gateway::roots() as $gateway )
|
||||
{
|
||||
$class = \strtolower( \substr( \get_class( $gateway ), 18 ) );
|
||||
$class = strtolower( substr( get_class( $gateway ), 18 ) );
|
||||
$settings = json_decode( $gateway->settings, TRUE );
|
||||
|
||||
if ( $class === 'authorizenet' )
|
||||
{
|
||||
$class = ( $settings['method'] === 'AIM' ) ? 'authorizenet_aim' : 'authorizenet_dpm';
|
||||
}
|
||||
elseif ( $class === 'paypal' )
|
||||
if ( $class === 'paypal' )
|
||||
{
|
||||
$class = ( $settings['type'] === 'paypal' ) ? 'paypal_standard' : 'paypal_pro';
|
||||
}
|
||||
@@ -271,12 +278,12 @@ class _usagereporting extends \IPS\Task
|
||||
|
||||
/* Converters */
|
||||
$report['converters'] = array();
|
||||
if ( \IPS\Application::appIsEnabled('convert') )
|
||||
if ( Application::appIsEnabled('convert') )
|
||||
{
|
||||
foreach( \IPS\convert\App::apps() as $app )
|
||||
foreach( App::apps() as $app )
|
||||
{
|
||||
/* Some legacy converters may not have the correct sw key */
|
||||
if( !\in_array( $app->sw, \IPS\IPS::$ipsApps ) OR !$app->finished )
|
||||
if( !in_array( $app->sw, IPS::$ipsApps ) OR !$app->finished )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,25 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Http\Useragent;
|
||||
use IPS\Session\Store;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* User agent statistics task
|
||||
*/
|
||||
class _userAgentStatistics extends \IPS\Task
|
||||
class userAgentStatistics extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,28 +40,28 @@ class _userAgentStatistics extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$desktops = 0;
|
||||
$tablets = 0;
|
||||
$mobiles = 0;
|
||||
$consoles = 0;
|
||||
|
||||
foreach( \IPS\Session\Store::i()->getOnlineUsers( \IPS\Session\Store::ONLINE_MEMBERS, 'desc', NULL, NULL, TRUE, TRUE ) as $row )
|
||||
foreach( Store::i()->getOnlineUsers( Store::ONLINE_MEMBERS, 'desc', NULL, NULL, TRUE, TRUE ) as $row )
|
||||
{
|
||||
$userAgent = \IPS\Http\Useragent::parse( $row['browser'] );
|
||||
$userAgent = Useragent::parse( $row['browser'] );
|
||||
|
||||
if( \in_array( $userAgent->platform, array( 'iPhone', 'Windows Phone OS', 'BlackBerry', 'Android', 'Tizen' ) ) )
|
||||
if( in_array( $userAgent->platform, array( 'iPhone', 'Windows Phone OS', 'BlackBerry', 'Android', 'Tizen' ) ) )
|
||||
{
|
||||
$mobiles++;
|
||||
}
|
||||
elseif( \in_array( $userAgent->platform, array( 'iPad / iPod Touch', 'Kindle', 'Kindle Fire', 'Playbook' ) ) )
|
||||
elseif( in_array( $userAgent->platform, array( 'iPad / iPod Touch', 'Kindle', 'Kindle Fire', 'Playbook' ) ) )
|
||||
{
|
||||
$tablets++;
|
||||
}
|
||||
elseif( \in_array( $userAgent->platform, array( 'Nintendo 3DS', 'New Nintendo 3DS', 'Nintendo Wii', 'Nintendo WiiU', 'PlayStation 3', 'PlayStation 4', 'PlayStation Vita', 'Xbox 360', 'Xbox One' ) ) )
|
||||
elseif( in_array( $userAgent->platform, array( 'Nintendo 3DS', 'New Nintendo 3DS', 'Nintendo Wii', 'Nintendo WiiU', 'PlayStation 3', 'PlayStation 4', 'PlayStation Vita', 'Xbox 360', 'Xbox One' ) ) )
|
||||
{
|
||||
$consoles++;
|
||||
}
|
||||
@@ -62,7 +71,7 @@ class _userAgentStatistics extends \IPS\Task
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->insert( 'core_statistics', array(
|
||||
Db::i()->insert( 'core_statistics', array(
|
||||
'type' => 'devices',
|
||||
'value_1' => $mobiles,
|
||||
'value_2' => $tablets,
|
||||
|
||||
@@ -11,17 +11,42 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\IPS;
|
||||
use IPS\Db;
|
||||
use IPS\Db\Exception;
|
||||
use IPS\Log;
|
||||
use IPS\Platform\Bridge;
|
||||
use IPS\Redis;
|
||||
use IPS\Task;
|
||||
use OutOfRangeException;
|
||||
use Throwable;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function intval;
|
||||
use function is_array;
|
||||
use const IPS\CACHE_CONFIG;
|
||||
use const IPS\CACHE_METHOD;
|
||||
use const IPS\REDIS_CONFIG;
|
||||
use const IPS\REDIS_ENABLED;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* view_updates Task
|
||||
*/
|
||||
class _viewupdates extends \IPS\Task
|
||||
class viewupdates extends Task
|
||||
{
|
||||
/**
|
||||
* @breif Stored data to send to Cloud in one go
|
||||
*/
|
||||
protected array $_sendToCloud = [];
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
@@ -31,17 +56,16 @@ class _viewupdates extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$this->runUntilTimeout(function(){
|
||||
$hasCount = FALSE;
|
||||
|
||||
try
|
||||
{
|
||||
/* @note SELECT_FROM_WRITE_SERVER added in 72724569ca77f6686f6be0861ce673f793a862e8 to avoid a race condition that caused high view counts */
|
||||
$database = \IPS\Db::i()->select( 'classname, id, count(*) AS count', 'core_view_updates', NULL, NULL, 20, array( 'classname', 'id' ), NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER );
|
||||
$database = Db::i()->select( 'classname, id, count(*) AS count', 'core_view_updates', NULL, NULL, 20, array( 'classname', 'id' ), NULL, Db::SELECT_FROM_WRITE_SERVER );
|
||||
|
||||
/* Database results first */
|
||||
foreach( $database as $row )
|
||||
@@ -52,39 +76,42 @@ class _viewupdates extends \IPS\Task
|
||||
{
|
||||
$this->update( $row['classname'], $row['id'], $row['count'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_view_updates', array( 'classname=?', $row['classname'] ) );
|
||||
Db::i()->delete( 'core_view_updates', array( 'classname=?', $row['classname'] ) );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_view_updates', array( 'classname=? AND id=?', $row['classname'], $row['id'] ) );
|
||||
Db::i()->delete( 'core_view_updates', array( 'classname=? AND id=?', $row['classname'], $row['id'] ) );
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
|
||||
catch ( UnderflowException $e ) { }
|
||||
|
||||
/* Now do cloud */
|
||||
Bridge::i()->viewTask( $this->_sendToCloud );
|
||||
|
||||
/* Now try redis */
|
||||
if ( \IPS\REDIS_ENABLED and \IPS\CACHE_METHOD == 'Redis' and ( \IPS\CACHE_CONFIG or \IPS\REDIS_CONFIG ) )
|
||||
if ( Redis::isEnabled() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$redis = \IPS\Redis::i()->zRevRangeByScore( 'topic_views', '+inf', '-inf', array('withscores' => TRUE, 'limit' => array( 0, 20 ) ) );
|
||||
$redis = Redis::i()->zRevRangeByScore( 'topic_views', '+inf', '-inf', array('withscores' => TRUE, 'limit' => array( 0, 20 ) ) );
|
||||
|
||||
if( \is_array( $redis ) AND \count( $redis ) )
|
||||
if( is_array( $redis ) and count( $redis ) )
|
||||
{
|
||||
foreach ( $redis as $data => $count )
|
||||
{
|
||||
$hasCount = TRUE;
|
||||
|
||||
list( $class, $id ) = explode( '__', $data );
|
||||
[ $class, $id ] = explode( '__', $data );
|
||||
|
||||
try
|
||||
{
|
||||
$this->update( $class, $id, \intval( $count ) );
|
||||
$this->update( $class, $id, intval( $count ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
catch ( OutOfRangeException $e ) {}
|
||||
}
|
||||
|
||||
\IPS\Redis::i()->zRem( 'topic_views', ...array_keys( $redis ) );
|
||||
Redis::i()->zRem( 'topic_views', ...array_keys( $redis ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
@@ -92,9 +119,9 @@ class _viewupdates extends \IPS\Task
|
||||
/* Now try advert impressions */
|
||||
try
|
||||
{
|
||||
$redis = \IPS\Redis::i()->zRevRangeByScore( 'advert_impressions', '+inf', '-inf', array('withscores' => TRUE, 'limit' => array( 0, 20 ) ) );
|
||||
$redis = Redis::i()->zRevRangeByScore( 'advert_impressions', '+inf', '-inf', array('withscores' => TRUE, 'limit' => array( 0, 20 ) ) );
|
||||
|
||||
if( \is_array( $redis ) )
|
||||
if( is_array( $redis ) )
|
||||
{
|
||||
$updates = [];
|
||||
foreach ( $redis as $id => $count )
|
||||
@@ -102,12 +129,12 @@ class _viewupdates extends \IPS\Task
|
||||
$hasCount = TRUE;
|
||||
$updates[ $count ][] = $id;
|
||||
|
||||
\IPS\Redis::i()->zRem( 'advert_impressions', $id );
|
||||
Redis::i()->zRem( 'advert_impressions', $id );
|
||||
}
|
||||
|
||||
foreach ( $updates as $incrementBy => $ids )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_advertisements', "ad_impressions=ad_impressions+" . $incrementBy, [ \IPS\Db::i()->in( 'ad_id', $ids ) ] );
|
||||
Db::i()->update( 'core_advertisements', "ad_impressions=ad_impressions+" . $incrementBy, [ Db::i()->in( 'ad_id', $ids ) ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,6 +151,8 @@ class _viewupdates extends \IPS\Task
|
||||
return FALSE;
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,26 +161,66 @@ class _viewupdates extends \IPS\Task
|
||||
* @param string $class Class to update
|
||||
* @param int $id ID of item
|
||||
* @param int $count Count to update
|
||||
* @throws \OutOfRangeException When table to update no longer exists
|
||||
* @throws OutOfRangeException When table to update no longer exists
|
||||
*/
|
||||
protected function update( $class, $id, $count )
|
||||
protected function update( string $class, int $id, int $count ) : void
|
||||
{
|
||||
if ( class_exists( $class ) and \IPS\IPS::classUsesTrait( $class, 'IPS\Content\ViewUpdates' ) AND isset( $class::$databaseColumnMap['views'] ) )
|
||||
|
||||
if ( class_exists( $class ) and IPS::classUsesTrait( $class, 'IPS\Content\ViewUpdates' ) AND isset( $class::$databaseColumnMap['views'] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->update(
|
||||
$item = $class::load( $id );
|
||||
$title = '';
|
||||
/* If we specify a title specifically for analytics, use that always. */
|
||||
if ( method_exists( $item, 'titleForAnalytics' ) )
|
||||
{
|
||||
$title = $item->titleForAnalytics();
|
||||
}
|
||||
/* Otherwise use titleForLog for Nodes */
|
||||
else if ( in_array( 'IPS\Node\Model', class_parents( $item ) ) )
|
||||
{
|
||||
$title = $item->titleForLog();
|
||||
}
|
||||
/* Or the defined title column for content items. */
|
||||
else if ( in_array( 'IPS\Content\Item', class_parents( $item ) ) )
|
||||
{
|
||||
$title = $item->mapped('title');
|
||||
}
|
||||
|
||||
$url = '';
|
||||
if ( method_exists( $item, 'url' ) )
|
||||
{
|
||||
$url = $item->url();
|
||||
}
|
||||
|
||||
$this->_sendToCloud[] = [
|
||||
'contentClass' => $class,
|
||||
'contentId' => $id,
|
||||
'views' => $count,
|
||||
'title' => $title,
|
||||
'url' => (string) $url
|
||||
];
|
||||
}
|
||||
catch( Throwable $e )
|
||||
{
|
||||
Log::log( $e, 'views' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Db::i()->update(
|
||||
$class::$databaseTable,
|
||||
"`{$class::$databasePrefix}{$class::$databaseColumnMap['views']}`=`{$class::$databasePrefix}{$class::$databaseColumnMap['views']}`+{$count}",
|
||||
array( "{$class::$databasePrefix}{$class::$databaseColumnId}=?", $id )
|
||||
);
|
||||
}
|
||||
catch( \IPS\Db\Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
/* Table to update no longer exists */
|
||||
if( $e->getCode() == 1146 )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
|
||||
@@ -11,16 +11,29 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use Exception;
|
||||
use IPS\Application;
|
||||
use IPS\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Output;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* webhooks Task
|
||||
*/
|
||||
class _webhooks extends \IPS\Task
|
||||
class webhooks extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,36 +44,35 @@ class _webhooks extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Task\Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Get our webhooks */
|
||||
$webhooks = iterator_to_array( \IPS\Db::i()->select( '*', 'core_api_webhooks', array('enabled=1') )->setKeyField('id') );
|
||||
$webhooks = iterator_to_array( Db::i()->select( '*', 'core_api_webhooks', array('enabled=1') )->setKeyField('id') );
|
||||
|
||||
/* Run through the queue */
|
||||
$this->runUntilTimeout( function() use ( $webhooks ) {
|
||||
/* Try and get a queue item */
|
||||
try
|
||||
{
|
||||
/* @note SELECT_FROM_WRITE_SERVER race condition in tasks */
|
||||
$fire = \IPS\Db::i()->select( '*', 'core_api_webhook_fires', array( "status='pending'" ), '`time` ASC', 1, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
$fire = Db::i()->select( '*', 'core_api_webhook_fires', array( "status='pending'" ), '`time` ASC', 1, NULL, NULL, Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
|
||||
try
|
||||
{
|
||||
if ( !isset( $webhooks[ $fire['webhook'] ] ) )
|
||||
{
|
||||
throw new \DomainException("Webhook Disabled");
|
||||
throw new DomainException("Webhook Disabled");
|
||||
}
|
||||
|
||||
\IPS\Output::i()->parseFileObjectUrls( $fire['data'] );
|
||||
$fire['data'] = \IPS\Output::i()->replaceEmojiWithImages( $fire['data'] );
|
||||
|
||||
$request = \IPS\Http\Url::external( $webhooks[ $fire['webhook'] ]['url'] )
|
||||
Output::i()->parseFileObjectUrls( $fire['data'] );
|
||||
$fire['data'] = Output::i()->replaceEmojiWithImages( $fire['data'] );
|
||||
|
||||
$request = Url::external( $webhooks[ $fire['webhook'] ]['url'] )
|
||||
->request()
|
||||
->setHeaders(
|
||||
[
|
||||
'User-Agent' => "InvisionCommunity/" . \IPS\Application::load('core')->long_version ,
|
||||
'User-Agent' => "InvisionCommunity/" . Application::load('core')->long_version ,
|
||||
'Webhook-Event' => $fire['event'],
|
||||
'Content-Type' => $webhooks[ $fire['webhook'] ]['content_type']
|
||||
]
|
||||
@@ -73,9 +85,9 @@ class _webhooks extends \IPS\Task
|
||||
|
||||
$response = $request->post( $fire['data'] );
|
||||
|
||||
if ( \IPS\Settings::i()->webhook_logs_success )
|
||||
if ( Settings::i()->webhook_logs_success )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_api_webhook_fires', [
|
||||
Db::i()->update( 'core_api_webhook_fires', [
|
||||
'status' => 'successful',
|
||||
'response_code' => $response->httpResponseCode,
|
||||
'response_body' => $response->content
|
||||
@@ -83,41 +95,43 @@ class _webhooks extends \IPS\Task
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_api_webhook_fires', [ 'id=?', $fire['id'] ] );
|
||||
Db::i()->delete( 'core_api_webhook_fires', [ 'id=?', $fire['id'] ] );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
$update = [
|
||||
'response_code' => NULL,
|
||||
'response_body' => \IPS\IPS::getExceptionDetails( $e ),
|
||||
'response_body' => IPS::getExceptionDetails( $e ),
|
||||
'fails' => $fire['fails'] + 1,
|
||||
];
|
||||
if ( $fire['fails'] >= ( \IPS\Settings::i()->webhooks_allowed_fails - 1 ) )
|
||||
if ( $fire['fails'] >= ( Settings::i()->webhooks_allowed_fails - 1 ) )
|
||||
{
|
||||
$update['status'] = 'failed';
|
||||
}
|
||||
|
||||
if ( isset( $update['status'] ) and $update['status'] === 'failed' and !\IPS\Settings::i()->webhook_logs_fail )
|
||||
if ( isset( $update['status'] ) and $update['status'] === 'failed' and !Settings::i()->webhook_logs_fail )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_api_webhook_fires', [ 'id=?', $fire['id'] ] );
|
||||
Db::i()->delete( 'core_api_webhook_fires', [ 'id=?', $fire['id'] ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_api_webhook_fires', $update, [ 'id=?', $fire['id'] ] );
|
||||
Db::i()->update( 'core_api_webhook_fires', $update, [ 'id=?', $fire['id'] ] );
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/* If there's no queue items left, disable this task and return */
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
$this->enabled = FALSE;
|
||||
$this->save();
|
||||
return FALSE;
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,16 +12,26 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* weeklyCleanup Task
|
||||
*/
|
||||
class _weeklyCleanup extends \IPS\Task
|
||||
class weeklyCleanup extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -32,14 +42,14 @@ class _weeklyCleanup extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* If we are currently pruning any large tables via a bg task, find out so we don't try to prune them normally here as well. The bg task should finish first. */
|
||||
$currentlyPruning = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_queue', array( '`key`=?', 'PruneLargeTable' ) ) as $pruneTask )
|
||||
foreach( Db::i()->select( '*', 'core_queue', array( '`key`=?', 'PruneLargeTable' ) ) as $pruneTask )
|
||||
{
|
||||
$data = json_decode( $pruneTask['data'], true );
|
||||
|
||||
@@ -47,13 +57,15 @@ class _weeklyCleanup extends \IPS\Task
|
||||
}
|
||||
|
||||
/* Delete old follows */
|
||||
if ( \IPS\Settings::i()->prune_follows AND !\in_array( 'core_follow', $currentlyPruning ) )
|
||||
if ( Settings::i()->prune_follows AND !in_array( 'core_follow', $currentlyPruning ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_follow', array( 'follow_app!=? AND follow_area!=? AND follow_member_id IN(?)', 'core', 'member', \IPS\Db::i()->select( 'member_id', 'core_members', array( 'last_activity < ?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . \IPS\Settings::i()->prune_follows . 'D' ) )->getTimestamp() ) ) ) );
|
||||
Db::i()->delete( 'core_follow', array( 'follow_app!=? AND follow_area!=? AND follow_member_id IN(?)', 'core', 'member', Db::i()->select( 'member_id', 'core_members', array( 'last_activity < ?', DateTime::create()->sub( new DateInterval( 'P' . Settings::i()->prune_follows . 'D' ) )->getTimestamp() ) ) ) );
|
||||
|
||||
/* And clear the cache so it can rebuild */
|
||||
\IPS\Db::i()->delete( 'core_follow_count_cache' );
|
||||
Db::i()->delete( 'core_follow_count_cache' );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,16 +11,23 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Stream\Subscription;
|
||||
use IPS\Db;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* weeklyStreamSubscriptions Task
|
||||
*/
|
||||
class _weeklyStreamSubscriptions extends \IPS\Task
|
||||
class weeklyStreamSubscriptions extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,12 +38,12 @@ class _weeklyStreamSubscriptions extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
/* Disable task if no subscriptions */
|
||||
$select = \IPS\Db::i()->select( '*', 'core_stream_subscriptions', array( 'frequency=?', 'weekly' ));
|
||||
$select = Db::i()->select( '*', 'core_stream_subscriptions', array( 'frequency=?', 'weekly' ));
|
||||
if( !$select->count() )
|
||||
{
|
||||
$this->enabled = FALSE;
|
||||
@@ -47,7 +54,7 @@ class _weeklyStreamSubscriptions extends \IPS\Task
|
||||
|
||||
$this->runUntilTimeout( function()
|
||||
{
|
||||
return \IPS\core\Stream\Subscription::sendBatch( 'weekly' );
|
||||
return Subscription::sendBatch( 'weekly' );
|
||||
});
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,22 @@
|
||||
namespace IPS\core\tasks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Digest\Digest;
|
||||
use IPS\Task;
|
||||
use IPS\Task\Exception;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* digest Task
|
||||
*/
|
||||
class _weeklydigest extends \IPS\Task
|
||||
class weeklydigest extends Task
|
||||
{
|
||||
/**
|
||||
* Execute
|
||||
@@ -31,13 +37,13 @@ class _weeklydigest extends \IPS\Task
|
||||
* Tasks should execute within the time of a normal HTTP request.
|
||||
*
|
||||
* @return mixed Message to log or NULL
|
||||
* @throws \IPS\Task\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : mixed
|
||||
{
|
||||
$this->runUntilTimeout( function()
|
||||
{
|
||||
return \IPS\core\Digest\Digest::sendDigestBatch( 'weekly' );
|
||||
return Digest::sendDigestBatch( 'weekly' );
|
||||
});
|
||||
|
||||
return NULL;
|
||||
|
||||
Reference in new issue
Block a user