Файловый менеджер - Редактировать - /home/tuudkjt/globeasy/wp-includes/ID3/Tasks.tar
Назад
DebugEventsCleanupTask.php 0000777 00000005733 15252001165 0011637 0 ustar 00 <?php namespace EasyWPSMTP\Tasks; use DateTime; use Exception; use EasyWPSMTP\Admin\DebugEvents\DebugEvents; use EasyWPSMTP\Options; use EasyWPSMTP\WP; /** * Class DebugEventsCleanupTask. * * @since 2.0.0 */ class DebugEventsCleanupTask extends Task { /** * Action name for this task. * * @since 2.0.0 */ const ACTION = 'easy_wp_smtp_process_debug_events_cleanup'; /** * Class constructor. * * @since 2.0.0 */ public function __construct() { parent::__construct( self::ACTION ); } /** * Initialize the task with all the proper checks. * * @since 2.0.0 */ public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks // Register the action handler. add_action( self::ACTION, [ $this, 'process' ] ); // Get the retention period value from the Debug Events settings. $retention_period = Options::init()->get( 'debug_events', 'retention_period' ); // Exit if the retention period is not defined (set to "forever") or this task is already scheduled. if ( empty( $retention_period ) || Tasks::is_scheduled( self::ACTION ) !== false ) { return; } // Schedule the task. $this->recurring( strtotime( 'tomorrow' ), $this->get_debug_events_cleanup_interval() ) ->params( $retention_period ) ->register(); } /** * Get the cleanup interval for the debug events. * * @since 2.0.0 * * @return int */ private function get_debug_events_cleanup_interval() { $day_in_seconds = DAY_IN_SECONDS; /** * Filter for the debug events cleanup interval. * * @since 2.0.0 * * @param int $day_in_seconds Debug events cleanup interval. */ return (int) apply_filters( 'easywpsmtp_tasks_get_debug_events_cleanup_interval', $day_in_seconds ); } /** * Perform the cleanup action: remove outdated debug events. * * @since 2.0.0 * * @param int $meta_id The Meta ID with the stored task parameters. * * @throws Exception Exception will be logged in the Action Scheduler logs table. */ public function process( $meta_id ) { $task_meta = new Meta(); $meta = $task_meta->get( (int) $meta_id ); // We should actually receive the passed parameter. if ( empty( $meta ) || empty( $meta->data ) || count( $meta->data ) !== 1 ) { return; } /** * Date in seconds (examples: 86400, 100500). * Debug Events older than this period will be deleted. * * @var int $retention_period */ $retention_period = (int) $meta->data[0]; if ( empty( $retention_period ) ) { return; } // Bail if DB tables was not created. if ( ! DebugEvents::is_valid_db() ) { return; } $wpdb = WP::wpdb(); $table = DebugEvents::get_table_name(); $date = ( new DateTime( "- $retention_period seconds" ) )->format( WP::datetime_mysql_format() ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->query( // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared $wpdb->prepare( "DELETE FROM `$table` WHERE created_at < %s", $date ) ); } } Tasks.php 0000777 00000017646 15252001165 0006364 0 ustar 00 <?php namespace EasyWPSMTP\Tasks; use ActionScheduler_Action; use ActionScheduler_DataController; use ActionScheduler_DBStore; use EasyWPSMTP\Tasks\Queue\CleanupQueueTask; use EasyWPSMTP\Tasks\Queue\ProcessQueueTask; use EasyWPSMTP\Tasks\Queue\SendEnqueuedEmailTask; use EasyWPSMTP\Tasks\Reports\SummaryEmailTask; /** * Class Tasks manages the tasks queue and provides API to work with it. * * @since 2.0.0 */ class Tasks { /** * Group that will be assigned to all actions. * * @since 2.0.0 */ const GROUP = 'easy_wp_smtp'; /** * Easy WP SMTP pending or in-progress actions. * * @since 2.0.0 * * @var array */ private static $active_actions = null; /** * Perform certain things on class init. * * @since 2.0.0 */ public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks // Hide the Action Scheduler admin menu item. add_action( 'admin_menu', [ $this, 'admin_hide_as_menu' ], PHP_INT_MAX ); // Skip tasks registration if Action Scheduler is not usable yet. if ( ! self::is_usable() ) { return; } // Register tasks. foreach ( $this->get_tasks() as $task ) { if ( ! is_subclass_of( $task, '\EasyWPSMTP\Tasks\Task' ) ) { continue; } $new_task = new $task(); // Run the init method, if a task has one defined. if ( method_exists( $new_task, 'init' ) ) { $new_task->init(); } } // Remove scheduled action meta after action execution. add_action( 'action_scheduler_after_execute', [ $this, 'clear_action_meta' ], PHP_INT_MAX, 2 ); // Cancel tasks on plugin deactivation. register_deactivation_hook( EasyWPSMTP_PLUGIN_FILE, [ $this, 'cancel_all' ] ); } /** * Get the list of default scheduled tasks. * Tasks, that are fired under certain specific circumstances * (like sending emails) are not listed here. * * @since 2.0.0 * * @return Task[] List of tasks classes. */ public function get_tasks() { $tasks = [ SummaryEmailTask::class, DebugEventsCleanupTask::class, ProcessQueueTask::class, CleanupQueueTask::class, SendEnqueuedEmailTask::class, NotificationsUpdateTask::class, ]; /** * Filters list of tasks classes. * * @since 2.0.0 * * @param Task[] $tasks List of tasks classes. */ return apply_filters( 'easy_wp_smtp_tasks_get_tasks', $tasks ); } /** * Hide Action Scheduler admin area when not in debug mode. * * @since 2.0.0 */ public function admin_hide_as_menu() { $plugin_exceptions = [ 'woocommerce/woocommerce.php', 'action-scheduler/action-scheduler.php', ]; /** * Filters the list of plugins for which * the Action Scheduler Tools ->Scheduled Actions menu item * should remain visible. * * @since 2.8.0 * * @param array $plugin_exceptions List of plugins exceptions. */ $plugin_exceptions = apply_filters( 'easy_wp_smtp_tasks_tasks_action_scheduler_tools_plugin_exceptions', $plugin_exceptions ); $hide_as_menu = empty( array_filter( $plugin_exceptions, 'is_plugin_active' ) ); // Filter to redefine that Easy WP SMTP hides Tools > Action Scheduler menu item. if ( apply_filters( 'easy_wp_smtp_tasks_admin_hide_as_menu', $hide_as_menu ) ) { remove_submenu_page( 'tools.php', 'action-scheduler' ); } } /** * Create a new task. * Used for "inline" tasks, that require additional information * from the plugin runtime before they can be scheduled. * * Example: * easy_wp_smtp()->get( 'tasks' ) * ->create( 'i_am_the_dude' ) * ->async() * ->params( 'The Big Lebowski', 1998 ) * ->register(); * * This `i_am_the_dude` action will be later processed as: * add_action( 'i_am_the_dude', 'thats_what_you_call_me' ); * * @since 2.0.0 * * @param string $action Action that will be used as a hook. * * @return Task */ public function create( $action ) { return new Task( $action ); } /** * Cancel all the AS actions for a group. * * @since 2.0.0 * * @param string $group Group to cancel all actions for. */ public function cancel_all( $group = '' ) { if ( empty( $group ) ) { $group = self::GROUP; } else { $group = sanitize_key( $group ); } if ( class_exists( 'ActionScheduler_DBStore' ) ) { ActionScheduler_DBStore::instance()->cancel_actions_by_group( $group ); } } /** * Remove all the AS actions for a group and remove group. * * @since 2.0.0 * * @param string $group Group to remove all actions for. */ public function remove_all( $group = '' ) { global $wpdb; if ( empty( $group ) ) { $group = self::GROUP; } else { $group = sanitize_key( $group ); } if ( class_exists( 'ActionScheduler_DBStore' ) && isset( $wpdb->actionscheduler_actions ) && isset( $wpdb->actionscheduler_groups ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching $group_id = $wpdb->get_var( $wpdb->prepare( "SELECT group_id FROM {$wpdb->actionscheduler_groups} WHERE slug=%s", $group ) ); if ( ! empty( $group_id ) ) { // Delete actions. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->delete( $wpdb->actionscheduler_actions, [ 'group_id' => (int) $group_id ], [ '%d' ] ); // Delete group. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->delete( $wpdb->actionscheduler_groups, [ 'slug' => $group ], [ '%s' ] ); } } } /** * Clear the meta after action complete. * Fired before an action is marked as completed. * * @since 2.0.0 * * @param integer $action_id Action ID. * @param ActionScheduler_Action $action Action name. */ public function clear_action_meta( $action_id, $action ) { $action_schedule = $action->get_schedule(); if ( $action_schedule === null || $action_schedule->is_recurring() || $action->get_group() !== self::GROUP ) { return; } $hook_args = $action->get_args(); if ( ! is_numeric( $hook_args[0] ) ) { return; } $meta = new Meta(); $meta->delete( $hook_args[0] ); } /** * Whether ActionScheduler thinks that it has migrated or not. * * @since 2.0.0 * * @return bool */ public static function is_usable() { // No tasks if ActionScheduler wasn't loaded. if ( ! class_exists( 'ActionScheduler_DataController' ) ) { return false; } return ActionScheduler_DataController::is_migration_complete(); } /** * Whether task has been scheduled and is pending. * * @since 2.0.0 * * @param string $hook Hook to check for. * * @return bool|null */ public static function is_scheduled( $hook ) { // If ActionScheduler wasn't loaded, then no tasks are scheduled. if ( ! function_exists( 'as_next_scheduled_action' ) ) { return null; } if ( is_null( self::$active_actions ) ) { self::$active_actions = self::get_active_actions(); } if ( in_array( $hook, self::$active_actions, true ) ) { return true; } // Action is not in the array, so it is not scheduled or belongs to another group. if ( function_exists( 'as_has_scheduled_action' ) ) { // This function more performant than `as_next_scheduled_action`, but it is available only since AS 3.3.0. return as_has_scheduled_action( $hook ); } else { return as_next_scheduled_action( $hook ) !== false; } } /** * Get all Easy WP SMTP pending or in-progress actions. * * @since 2.0.0 */ private static function get_active_actions() { global $wpdb; $group = self::GROUP; $sql = "SELECT a.hook FROM {$wpdb->prefix}actionscheduler_actions a JOIN {$wpdb->prefix}actionscheduler_groups g ON g.group_id = a.group_id WHERE g.slug = '$group' AND a.status IN ('in-progress', 'pending')"; // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared $results = $wpdb->get_results( $sql, 'ARRAY_N' ); // phpcs:enable WordPress.DB.DirectDatabaseQuery.NoCaching // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared return $results ? array_merge( ...$results ) : []; } } Reports/SummaryEmailTask.php 0000777 00000004350 15252001165 0012151 0 ustar 00 <?php namespace EasyWPSMTP\Tasks\Reports; use EasyWPSMTP\Tasks\Tasks; use EasyWPSMTP\WP; use EasyWPSMTP\Tasks\Task; use EasyWPSMTP\Reports\Emails\Summary as SummaryReportEmail; /** * Class SummaryEmailTask. * * @since 2.1.0 */ class SummaryEmailTask extends Task { /** * Action name for this task. * * @since 2.1.0 */ const ACTION = 'easy_wp_smtp_summary_report_email'; /** * Class constructor. * * @since 2.1.0 */ public function __construct() { parent::__construct( self::ACTION ); } /** * Initialize the task with all the proper checks. * * @since 2.1.0 */ public function init() { // Register the action handler. add_action( self::ACTION, array( $this, 'process' ) ); $is_disabled = SummaryReportEmail::is_disabled(); // Exit if summary report email is disabled or this task is already scheduled. if ( ! empty( $is_disabled ) || Tasks::is_scheduled( self::ACTION ) !== false ) { return; } $date = new \DateTime( 'next monday 2pm', WP::wp_timezone() ); // Schedule the task. $this ->recurring( $date->getTimestamp(), WEEK_IN_SECONDS ) ->unique() ->register(); } /** * Process summary report email send. * * @since 2.1.0 * * @param int $meta_id The Meta ID with the stored task parameters. */ public function process( $meta_id ) { // Prevent email sending if summary report email is disabled. if ( SummaryReportEmail::is_disabled() || ! $this->is_allowed() ) { return; } // Update the last sent week at the top to prevent multiple emails in case of task failure and retry. update_option( 'easy_wp_smtp_summary_report_email_last_sent_week', current_time( 'W' ) ); $reports = easy_wp_smtp()->get_reports(); $email = $reports->get_summary_report_email(); $email->send(); } /** * Check if the summary report email is allowed to be sent. * * The email is allowed to be sent if it was not sent in the current week. * * @since 2.4.0 * * @return bool */ private function is_allowed() { $last_sent_week = get_option( 'easy_wp_smtp_summary_report_email_last_sent_week' ); $current_week = current_time( 'W' ); if ( $last_sent_week === false || ( (int) $current_week !== (int) $last_sent_week ) ) { return true; } return false; } } NotificationsUpdateTask.php 0000777 00000002626 15252001165 0012066 0 ustar 00 <?php namespace EasyWPSMTP\Tasks; use Exception; /** * Class NotificationsUpdateTask. * * @since 2.8.0 */ class NotificationsUpdateTask extends Task { /** * Action name for this task. * * @since 2.8.0 */ const ACTION = 'easy_wp_smtp_admin_notifications_update'; /** * Class constructor. * * @since 2.8.0 */ public function __construct() { parent::__construct( self::ACTION ); } /** * Initialize the task with all the proper checks. * * @since 2.8.0 */ public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks // Register the action handler. add_action( self::ACTION, [ $this, 'process' ] ); // Exit if notifications are disabled // or this task is already scheduled. if ( ! easy_wp_smtp()->get_notifications()->is_enabled() || Tasks::is_scheduled( self::ACTION ) !== false ) { return; } // Schedule the task. $this->recurring( strtotime( '+1 minute' ), easy_wp_smtp()->get_notifications()->get_notification_update_task_interval() ) ->unique() ->register(); } /** * Update the notification feed. * * @since 2.8.0 */ public function process() { // Delete task duplicates. try { $this->remove_pending( 1000 ); } catch ( Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch // Do nothing. } easy_wp_smtp()->get_notifications()->update(); } } Task.php 0000777 00000017460 15252001165 0006173 0 ustar 00 <?php namespace EasyWPSMTP\Tasks; use ActionScheduler; /** * Class Task. * * @since 2.0.0 */ class Task { /** * This task is async (runs asap). * * @since 2.0.0 */ const TYPE_ASYNC = 'async'; /** * This task is a recurring. * * @since 2.0.0 */ const TYPE_RECURRING = 'scheduled'; /** * This task is run once. * * @since 2.0.0 */ const TYPE_ONCE = 'once'; /** * Type of the task. * * @since 2.0.0 * * @var string */ private $type; /** * Action that will be used as a hook. * * @since 2.0.0 * * @var string */ private $action; /** * Task meta ID. * * @since 2.0.0 * * @var int */ private $meta_id; /** * All the params that should be passed to the hook. * * @since 2.0.0 * * @var array */ private $params; /** * When the first instance of the job will run. * Used for ONCE ane RECURRING tasks. * * @since 2.0.0 * * @var int */ private $timestamp; /** * How long to wait between runs. * Used for RECURRING tasks. * * @since 2.0.0 * * @var int */ private $interval; /** * Whether this task is unique. * * @since 2.4.0 * * @var bool */ private $unique = false; /** * Task constructor. * * @since 2.0.0 * * @param string $action Action of the task. * * @throws \InvalidArgumentException When action is not a string. * @throws \UnexpectedValueException When action is empty. */ public function __construct( $action ) { if ( ! is_string( $action ) ) { throw new \InvalidArgumentException( 'Task action should be a string.' ); } $this->action = sanitize_key( $action ); if ( empty( $this->action ) ) { throw new \UnexpectedValueException( 'Task action cannot be empty.' ); } } /** * Define the type of the task as async. * * @since 2.0.0 * * @return Task */ public function async() { $this->type = self::TYPE_ASYNC; return $this; } /** * Define the type of the task as recurring. * * @since 2.0.0 * * @param int $timestamp When the first instance of the job will run. * @param int $interval How long to wait between runs. * * @return Task */ public function recurring( $timestamp, $interval ) { $this->type = self::TYPE_RECURRING; $this->timestamp = (int) $timestamp; $this->interval = (int) $interval; return $this; } /** * Define the type of the task as one-time. * * @since 2.0.0 * * @param int $timestamp When the first instance of the job will run. * * @return Task */ public function once( $timestamp ) { $this->type = self::TYPE_ONCE; $this->timestamp = (int) $timestamp; return $this; } /** * Set this task as unique. * * @since 2.4.0 * * @return Task */ public function unique() { $this->unique = true; return $this; } /** * Pass any number of params that should be saved to Meta table. * * @since 2.0.0 * * @return Task */ public function params() { $args = func_get_args(); if ( ! empty( $args ) ) { $this->params = $args; } return $this; } /** * Register the action. * Should be the final call in a chain. * * @since 2.0.0 * * @return null|string Action ID. */ public function register() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh $action_id = null; // No processing if ActionScheduler is not usable. if ( ! Tasks::is_usable() ) { return $action_id; } // Save data to tasks meta table. if ( ! is_null( $this->params ) ) { $task_meta = new Meta(); // No processing if meta table was not created. if ( ! $task_meta->table_exists() ) { return $action_id; } $this->meta_id = $task_meta->add( [ 'action' => $this->action, 'data' => isset( $this->params ) ? $this->params : [], ] ); if ( empty( $this->meta_id ) ) { return $action_id; } } // Prevent 500 errors when Action Scheduler tables don't exist. try { switch ( $this->type ) { case self::TYPE_ASYNC: $action_id = $this->register_async(); break; case self::TYPE_RECURRING: $action_id = $this->register_recurring(); break; case self::TYPE_ONCE: $action_id = $this->register_once(); break; } } catch ( \RuntimeException $exception ) { $action_id = null; } return $action_id; } /** * Register the async task. * * @since 2.0.0 * * @return null|string Action ID. */ protected function register_async() { if ( ! function_exists( 'as_enqueue_async_action' ) ) { return null; } return as_enqueue_async_action( $this->action, [ $this->meta_id ], Tasks::GROUP, $this->unique ); } /** * Register the recurring task. * * @since 2.0.0 * * @return null|string Action ID. */ protected function register_recurring() { if ( ! function_exists( 'as_schedule_recurring_action' ) ) { return null; } return as_schedule_recurring_action( $this->timestamp, $this->interval, $this->action, [ $this->meta_id ], Tasks::GROUP, $this->unique ); } /** * Register the one-time task. * * @since 2.0.0 * * @return null|string Action ID. */ protected function register_once() { if ( ! function_exists( 'as_schedule_single_action' ) ) { return null; } return as_schedule_single_action( $this->timestamp, $this->action, [ $this->meta_id ], Tasks::GROUP, $this->unique ); } /** * Cancel all occurrences of this task. * * @since 2.0.0 * * @return null|bool|string Null if no matching action found, * false if AS library is missing, * string of the scheduled action ID if a scheduled action was found and unscheduled. */ public function cancel() { // Exit if AS function does not exist. if ( ! function_exists( 'as_unschedule_all_actions' ) || ! Tasks::is_usable() ) { return false; } as_unschedule_all_actions( $this->action ); return true; } /** * Cancel all occurrences of this task, * preventing it from re-registering itself. * * @since 2.6.0 */ public function cancel_force() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks add_action( 'shutdown', [ $this, 'cancel' ], PHP_INT_MAX ); } /** * Remove completed occurrences of this task. * * @since 2.6.0 * * @param int $limit The amount of rows to remove. */ protected function remove_completed( $limit = 0 ) { global $wpdb; $limit = max( 0, intval( $limit ) ); $query = $wpdb->prepare( "DELETE FROM {$wpdb->prefix}actionscheduler_actions WHERE hook = %s AND status = %s", $this->action, 'complete' ); if ( $limit > 0 ) { $query .= $wpdb->prepare( ' LIMIT %d', $limit ); } // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared $wpdb->query( $query ); // phpcs:enable WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared } /** * Remove pending occurrences of this task. * * @since 2.8.0 * * @param int $limit The amount of rows to remove. */ protected function remove_pending( $limit = 0 ) { // Make sure that all used functions, classes, and methods exist. if ( ! function_exists( 'as_get_scheduled_actions' ) || ! class_exists( 'ActionScheduler' ) || ! method_exists( 'ActionScheduler', 'store' ) || ! class_exists( 'ActionScheduler_Store' ) || ! method_exists( 'ActionScheduler_Store', 'delete_action' ) ) { return; } $per_page = max( 0, intval( $limit ) ); // Get all pending license check actions. $action_ids = as_get_scheduled_actions( [ 'hook' => $this->action, 'status' => 'pending', 'per_page' => $per_page, ], 'ids' ); if ( empty( $action_ids ) ) { return; } // Delete all pending license check actions. foreach ( $action_ids as $action_id ) { ActionScheduler::store()->delete_action( $action_id ); } } } Meta.php 0000777 00000031343 15252001165 0006153 0 ustar 00 <?php namespace EasyWPSMTP\Tasks; /** * Class Meta helps to manage the tasks meta information * between Action Scheduler and Easy WP SMTP hooks arguments. * We can't pass arguments longer than >191 chars in JSON to AS, * so we need to store them somewhere (and clean from time to time). * * @since 2.0.0 */ class Meta { /** * Database table name. * * @since 2.0.0 * * @var string */ public $table_name; /** * Database version. * * @since 2.0.0 * * @var string */ public $version; /** * Primary key (unique field) for the database table. * * @since 2.0.0 * * @var string */ public $primary_key = 'id'; /** * Database type identifier. * * @since 2.0.0 * * @var string */ public $type = 'tasks_meta'; /** * Primary class constructor. * * @since 2.0.0 */ public function __construct() { $this->table_name = self::get_table_name(); } /** * Get the DB table name. * * @since 2.0.0 * * @return string */ public static function get_table_name() { global $wpdb; return $wpdb->prefix . 'easywpsmtp_tasks_meta'; } /** * Get table columns. * * @since 2.0.0 */ public function get_columns() { return array( 'id' => '%d', 'action' => '%s', 'data' => '%s', 'date' => '%s', ); } /** * Default column values. * * @since 2.0.0 * * @return array */ public function get_column_defaults() { return array( 'action' => '', 'data' => '', 'date' => gmdate( 'Y-m-d H:i:s' ), ); } /** * Retrieve a row from the database based on a given row ID. * * @since 2.0.0 * * @param int $row_id Row ID. * * @return null|object */ private function get_from_db( $row_id ) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$this->table_name} WHERE {$this->primary_key} = %s LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared $row_id ) ); } /** * Retrieve a row based on column and row ID. * * @since 2.0.0 * * @param string $column Column name. * @param int|string $row_id Row ID. * * @return object|null|bool Database query result, object or null on failure. */ public function get_by( $column, $row_id ) { global $wpdb; if ( empty( $row_id ) || ! array_key_exists( $column, $this->get_columns() ) ) { return false; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $column = '%s' LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder $row_id ) ); } /** * Retrieve a value based on column name and row ID. * * @since 2.0.0 * * @param string $column Column name. * @param int|string $row_id Row ID. * * @return string|null Database query result (as string), or null on failure. */ public function get_column( $column, $row_id ) { global $wpdb; if ( empty( $row_id ) || ! array_key_exists( $column, $this->get_columns() ) ) { return false; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching return $wpdb->get_var( $wpdb->prepare( "SELECT $column FROM $this->table_name WHERE $this->primary_key = '%s' LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedSimplePlaceholder $row_id ) ); } /** * Retrieve one column value based on another given column and matching value. * * @since 2.0.0 * * @param string $column Column name. * @param string $column_where Column to match against in the WHERE clause. * @param string $column_value Value to match to the column in the WHERE clause. * * @return string|null Database query result (as string), or null on failure. */ public function get_column_by( $column, $column_where, $column_value ) { global $wpdb; if ( empty( $column ) || empty( $column_where ) || empty( $column_value ) || ! array_key_exists( $column, $this->get_columns() ) ) { return false; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching return $wpdb->get_var( $wpdb->prepare( "SELECT $column FROM $this->table_name WHERE $column_where = %s LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared $column_value ) ); } /** * Insert a new record into the database. * * @since 2.0.0 * * @param array $data Column data. * @param string $type Optional. Data type context. * * @return int ID for the newly inserted record. 0 otherwise. */ private function add_to_db( $data, $type = '' ) { global $wpdb; // Set default values. $data = wp_parse_args( $data, $this->get_column_defaults() ); do_action( 'easy_wp_smtp_pre_insert_' . $type, $data ); // Initialise column format array. $column_formats = $this->get_columns(); // Force fields to lower case. $data = array_change_key_case( $data ); // White list columns. $data = array_intersect_key( $data, $column_formats ); // Reorder $column_formats to match the order of columns given in $data. $data_keys = array_keys( $data ); $column_formats = array_merge( array_flip( $data_keys ), $column_formats ); $wpdb->insert( $this->table_name, $data, $column_formats ); do_action( 'easy_wp_smtp_post_insert_' . $type, $wpdb->insert_id, $data ); return $wpdb->insert_id; } /** * Update an existing record in the database. * * @since 2.0.0 * * @param int|string $row_id Row ID for the record being updated. * @param array $data Optional. Array of columns and associated data to update. Default empty array. * @param string $where Optional. Column to match against in the WHERE clause. If empty, $primary_key * will be used. Default empty. * @param string $type Optional. Data type context, e.g. 'affiliate', 'creative', etc. Default empty. * * @return bool False if the record could not be updated, true otherwise. */ public function update( $row_id, $data = array(), $where = '', $type = '' ) { global $wpdb; // Row ID must be a positive integer. $row_id = absint( $row_id ); if ( empty( $row_id ) ) { return false; } if ( empty( $where ) ) { $where = $this->primary_key; } do_action( 'easy_wp_smtp_pre_update_' . $type, $data ); // Initialise column format array. $column_formats = $this->get_columns(); // Force fields to lower case. $data = array_change_key_case( $data ); // White list columns. $data = array_intersect_key( $data, $column_formats ); // Reorder $column_formats to match the order of columns given in $data. $data_keys = array_keys( $data ); $column_formats = array_merge( array_flip( $data_keys ), $column_formats ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching if ( false === $wpdb->update( $this->table_name, $data, array( $where => $row_id ), $column_formats ) ) { return false; } do_action( 'easy_wp_smtp_post_update_' . $type, $data ); return true; } /** * Delete a record from the database. * * @since 2.0.0 * * @param int|string $row_id Row ID. * * @return bool False if the record could not be deleted, true otherwise. */ public function delete( $row_id = 0 ) { global $wpdb; // Row ID must be positive integer. $row_id = absint( $row_id ); if ( empty( $row_id ) ) { return false; } do_action( 'easy_wp_smtp_pre_delete', $row_id ); do_action( 'easy_wp_smtp_pre_delete_' . $this->type, $row_id ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->table_name} WHERE {$this->primary_key} = %d", $row_id ) ) ) { return false; } do_action( 'easy_wp_smtp_post_delete', $row_id ); do_action( 'easy_wp_smtp_post_delete_' . $this->type, $row_id ); return true; } /** * Delete a record from the database by column. * * @since 2.0.0 * * @param string $column Column name. * @param int|string $column_value Column value. * * @return bool False if the record could not be deleted, true otherwise. */ public function delete_by( $column, $column_value ) { global $wpdb; if ( empty( $column ) || empty( $column_value ) || ! array_key_exists( $column, $this->get_columns() ) ) { return false; } do_action( 'easy_wp_smtp_pre_delete', $column_value ); do_action( 'easy_wp_smtp_pre_delete_' . $this->type, $column_value ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM {$this->table_name} WHERE $column = %s", $column_value ) ) ) { return false; } do_action( 'easy_wp_smtp_post_delete', $column_value ); do_action( 'easy_wp_smtp_post_delete_' . $this->type, $column_value ); return true; } /** * Check if the given table exists. * * @since 2.0.0 * * @param string $table The table name. Defaults to the child class table name. * * @return string|null If the table name exists. */ public function table_exists( $table = '' ) { global $wpdb; if ( ! empty( $table ) ) { $table = sanitize_text_field( $table ); } else { $table = $this->table_name; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching $db_result = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ); if ( is_null( $db_result ) ) { return false; } return strtolower( $db_result ) === strtolower( $table ); } /** * Create custom entry meta database table. * Used in migration. * * @since 2.0.0 */ public function create_table() { global $wpdb; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; $charset_collate = ''; if ( ! empty( $wpdb->charset ) ) { $charset_collate .= "DEFAULT CHARACTER SET {$wpdb->charset}"; } if ( ! empty( $wpdb->collate ) ) { $charset_collate .= " COLLATE {$wpdb->collate}"; } $sql = "CREATE TABLE {$this->table_name} ( id bigint(20) NOT NULL AUTO_INCREMENT, action varchar(255) NOT NULL, data longtext NOT NULL, date datetime NOT NULL, PRIMARY KEY (id) ) {$charset_collate};"; dbDelta( $sql ); } /** * Remove queue records for a defined period of time in the past. * Calling this method will remove queue records that are older than $period seconds. * * @since 2.0.0 * * @param string $action Action that should be cleaned up. * @param int $interval Number of seconds from now. * * @return int Number of removed tasks meta records. */ public function clean_by( $action, $interval ) { global $wpdb; if ( empty( $action ) || empty( $interval ) ) { return 0; } $table = self::get_table_name(); $action = sanitize_key( $action ); $date = gmdate( 'Y-m-d H:i:s', time() - (int) $interval ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching return (int) $wpdb->query( $wpdb->prepare( "DELETE FROM `$table` WHERE action = %s AND date < %s", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared $action, $date ) ); } /** * Inserts a new record into the database. * * @since 2.0.0 * * @param array $data Column data. * @param string $type Optional. Data type context. * * @return int ID for the newly inserted record. 0 otherwise. */ public function add( $data, $type = '' ) { if ( empty( $data['action'] ) || ! is_string( $data['action'] ) ) { return 0; } $data['action'] = sanitize_key( $data['action'] ); if ( isset( $data['data'] ) ) { $string = wp_json_encode( $data['data'] ); if ( $string === false ) { $string = ''; } /* * We are encoding the string representation of all the data * to make sure that nothing can harm the database. * This is not an encryption, and we need this data later as is, * so we are using one of the fastest way to do that. * This data is removed from DB on a daily basis. */ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode $data['data'] = base64_encode( $string ); } if ( empty( $type ) ) { $type = $this->type; } return $this->add_to_db( $data, $type ); } /** * Retrieve a row from the database based on a given row ID. * * @since 2.0.0 * * @param int $meta_id Meta ID. * * @return null|object */ public function get( $meta_id ) { $meta = $this->get_from_db( $meta_id ); if ( empty( $meta ) || empty( $meta->data ) ) { return $meta; } // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode $decoded = base64_decode( $meta->data ); if ( $decoded === false || ! is_string( $decoded ) ) { $meta->data = ''; } else { $meta->data = json_decode( $decoded, true ); } return $meta; } } Queue/CleanupQueueTask.php 0000777 00000003712 15252001165 0011567 0 ustar 00 <?php namespace EasyWPSMTP\Tasks\Queue; use DateTime; use DateTimeZone; use EasyWPSMTP\Queue\Attachments; use EasyWPSMTP\Tasks\Task; use EasyWPSMTP\Tasks\Tasks; /** * Class CleanupQueueTask. * * @since 2.6.0 */ class CleanupQueueTask extends Task { /** * Action name for this task. * * @since 2.6.0 */ const ACTION = 'easy_wp_smtp_queue_cleanup'; /** * Class constructor. * * @since 2.6.0 */ public function __construct() { parent::__construct( self::ACTION ); } /** * Initialize the task. * * @since 2.6.0 */ public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks // Register the action handler. add_action( self::ACTION, [ $this, 'process' ] ); // Exit if this task the queue is disabled, or it's already scheduled. if ( ! easy_wp_smtp()->get_queue()->is_enabled() || Tasks::is_scheduled( self::ACTION ) !== false ) { return; } // Schedule the task. $this->recurring( strtotime( 'now' ), DAY_IN_SECONDS ) ->unique() ->register(); } /** * Perform email sending. * * @since 2.6.0 */ public function process() { $queue = easy_wp_smtp()->get_queue(); $attachments = new Attachments(); // Cleanup processed emails. $queue->cleanup(); // Cleanup older-than-a-month attachments. $attachments->delete_attachments( null, new DateTime( '1 month ago', new DateTimeZone( 'UTC' ) ) ); if ( ! $queue->is_enabled() ) { // If the query has been disabled in the meanwhile, // and there aren't any emails left, // cancel the cleanup task. $queued_emails_count = $queue->count_queued_emails(); $processed_emails_count = $queue->count_processed_emails(); if ( $queued_emails_count === 0 && $processed_emails_count === 0 ) { // Cleanup any remaining, older-than-an-hour attachments. $attachments->delete_attachments( null, new DateTime( '1 hour ago', new DateTimeZone( 'UTC' ) ) ); $this->cancel_force(); } } } } Queue/SendEnqueuedEmailTask.php 0000777 00000003354 15252001165 0012532 0 ustar 00 <?php namespace EasyWPSMTP\Tasks\Queue; use EasyWPSMTP\Tasks\Meta; use EasyWPSMTP\Tasks\Task; /** * Class SendEnqueuedEmailTask. * * @since 2.6.0 */ class SendEnqueuedEmailTask extends Task { /** * Action name for this task. * * @since 2.6.0 */ const ACTION = 'easy_wp_smtp_send_enqueued_email'; /** * Class constructor. * * @since 2.6.0 */ public function __construct() { parent::__construct( self::ACTION ); } /** * Initialize the task. * * @since 2.6.0 */ public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks // Register the action handler. add_action( self::ACTION, [ $this, 'process' ] ); // Cleanup completed task occurrences. add_action( 'action_scheduler_after_process_queue', [ $this, 'cleanup' ] ); } /** * Schedule email sending. * * @since 2.6.0 * * @param int $email_id Email id. */ public function schedule( $email_id ) { // Exit if AS function does not exist. if ( ! function_exists( 'as_has_scheduled_action' ) ) { return; } // Schedule the task. $this->async() ->params( $email_id ) ->register(); } /** * Perform email sending. * * @since 2.6.0 * * @param int $meta_id The Meta ID with the stored task parameters. */ public function process( $meta_id ) { $task_meta = new Meta(); $meta = $task_meta->get( (int) $meta_id ); // We should actually receive the passed parameter. if ( empty( $meta ) || empty( $meta->data ) || count( $meta->data ) < 1 ) { return; } $email_id = $meta->data[0]; easy_wp_smtp()->get_queue()->send_email( $email_id ); } /** * Cleanup completed tasks. * * @since 2.6.0 */ public function cleanup() { $this->remove_completed( 10 ); } } Queue/ProcessQueueTask.php 0000777 00000002667 15252001165 0011626 0 ustar 00 <?php namespace EasyWPSMTP\Tasks\Queue; use EasyWPSMTP\Tasks\Task; use EasyWPSMTP\Tasks\Tasks; /** * Class ProcessQueueTask. * * @since 2.6.0 */ class ProcessQueueTask extends Task { /** * Action name for this task. * * @since 2.6.0 */ const ACTION = 'easy_wp_smtp_queue_process'; /** * Class constructor. * * @since 2.6.0 */ public function __construct() { parent::__construct( self::ACTION ); } /** * Initialize the task. * * @since 2.6.0 */ public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks // Register the action handler. add_action( self::ACTION, [ $this, 'process' ] ); // Cleanup completed task occurrences. add_action( 'action_scheduler_after_process_queue', [ $this, 'cleanup' ] ); // Exit if this task the queue is disabled, or it's already scheduled. if ( ! easy_wp_smtp()->get_queue()->is_enabled() || Tasks::is_scheduled( self::ACTION ) !== false ) { return; } // Schedule the task. $this->recurring( strtotime( 'now' ), MINUTE_IN_SECONDS ) ->unique() ->register(); } /** * Perform email sending. * * @since 2.6.0 */ public function process() { $queue = easy_wp_smtp()->get_queue(); $queue->process(); if ( ! $queue->is_enabled() ) { $this->cancel_force(); } } /** * Cleanup completed tasks. * * @since 2.6.0 */ public function cleanup() { $this->remove_completed( 10 ); } }
| ver. 1.6 |
Github
|
.
| PHP 8.1.34 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка