# wp-to-buffer/6.2.2/lib/social/includes/class-cron.php

Social Media Auto Poster – Schedule &amp; Publish to Buffer, version 6.2.2. 422 lines.

- Page: https://pluginprobe.com/plugins/wp-to-buffer/6.2.2/code/lib/social/includes/class-cron.php
- Raw: https://pluginprobe.com/plugins/wp-to-buffer/6.2.2/raw/lib/social/includes/class-cron.php
- Modified: 2026-08-19T11:19:16+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/wp-to-buffer/6.2.2/code/lib/social/includes/class-cron.php#L10-L20`.

```php
<?php
/**
 * Cron class.
 *
 * @package WPZinc\Social
 * @author WP Zinc
 */

namespace WPZinc\Social;

/**
 * Functions to schedule, reschedule and unschedule events with WordPress' Cron for
 * - Log Cleanup (old log entries that are no longer needed)
 * - Media Cleanup (images auto generated by the Plugin that are no longer needed)
 *
 * @package  WPZinc\Social
 * @author   WP Zinc
 * @version  3.7.2
 */
class Cron {

	/**
	 * Holds the base class object.
	 *
	 * @since   3.7.2
	 *
	 * @var     object
	 */
	public $base;

	/**
	 * Constructor
	 *
	 * @since   3.7.2
	 *
	 * @param   object $base    Base Plugin Class.
	 */
	public function __construct( $base ) {

		// Store base class.
		$this->base = $base;

	}

	/**
	 * Schedules the log cleanup event in the WordPress CRON on a daily basis
	 *
	 * @since   3.9.8
	 */
	public function schedule_log_cleanup_event() {

		// Bail if the preserve logs settings is indefinite.
		if ( ! $this->base->get_class( 'settings' )->get_setting( 'log', '[preserve_days]' ) ) {
			return;
		}

		// Bail if the scheduled event already exists.
		$scheduled_event = $this->get_log_cleanup_event();
		if ( $scheduled_event !== false ) {
			return;
		}

		// Schedule event.
		$scheduled_date_time = gmdate( 'Y-m-d', strtotime( '+1 day' ) ) . ' 00:00:00';
		wp_schedule_event( strtotime( $scheduled_date_time ), 'daily', $this->base->plugin->filter_name . '_log_cleanup_cron' );

	}

	/**
	 * Unschedules the log cleanup event in the WordPress CRON.
	 *
	 * @since   3.9.8
	 */
	public function unschedule_log_cleanup_event() {

		wp_clear_scheduled_hook( $this->base->plugin->filter_name . '_log_cleanup_cron' );

	}

	/**
	 * Reschedules the log cleanup event in the WordPress CRON, by unscheduling
	 * and scheduling it.
	 *
	 * @since   3.9.8
	 */
	public function reschedule_log_cleanup_event() {

		$this->unschedule_log_cleanup_event();
		$this->schedule_log_cleanup_event();

	}

	/**
	 * Returns the scheduled log cleanup event, if it exists
	 *
	 * @since   3.9.8
	 */
	public function get_log_cleanup_event() {

		return wp_get_schedule( $this->base->plugin->filter_name . '_log_cleanup_cron' );

	}

	/**
	 * Returns the scheduled log cleanup event's next date and time to run, if it exists
	 *
	 * @since   3.9.8
	 *
	 * @param   mixed $format     Format Timestamp (false | php date() compat. string).
	 */
	public function get_log_cleanup_event_next_scheduled( $format = false ) {

		// Get timestamp for when the event will next run.
		$scheduled = wp_next_scheduled( $this->base->plugin->filter_name . '_log_cleanup_cron' );

		// If no timestamp or we're not formatting the result, return it now.
		if ( ! $scheduled || ! $format ) {
			return $scheduled;
		}

		// Return formatted date/time.
		return gmdate( $format, $scheduled );
	}

	/**
	 * Runs the log cleanup CRON event
	 *
	 * @since   3.9.8
	 */
	public function log_cleanup() {

		// Bail if the preserve logs settings is indefinite.
		// We shouldn't ever call this function if this is the case, but it's a useful sanity check.
		$preserve_days = $this->base->get_class( 'settings' )->get_setting( 'log', '[preserve_days]' );
		if ( ! $preserve_days ) {
			return;
		}

		// Define the date cutoff.
		$date_time = gmdate( 'Y-m-d H:i:s', strtotime( '-' . $preserve_days . ' days' ) );
		// Delete log entries older than the date.
		$this->base->get_class( 'log' )->delete_by_request_sent_cutoff( $date_time );

	}

	/**
	 * Schedules the media cleanup event in the WordPress CRON on a daily basis
	 *
	 * @since   4.2.0
	 */
	public function schedule_media_cleanup_event() {

		// Bail if the scheduled event already exists.
		$scheduled_event = $this->get_media_cleanup_event();
		if ( $scheduled_event !== false ) {
			return;
		}

		// Schedule event.
		$scheduled_date_time = gmdate( 'Y-m-d', strtotime( '+1 day' ) ) . ' 01:00:00';
		wp_schedule_event( strtotime( $scheduled_date_time ), 'daily', $this->base->plugin->filter_name . '_media_cleanup_cron' );

	}

	/**
	 * Unschedules the media cleanup event in the WordPress CRON.
	 *
	 * @since   4.2.0
	 */
	public function unschedule_media_cleanup_event() {

		wp_clear_scheduled_hook( $this->base->plugin->filter_name . '_media_cleanup_cron' );

	}

	/**
	 * Reschedules the media cleanup event in the WordPress CRON, by unscheduling
	 * and scheduling it.
	 *
	 * @since   4.2.0
	 */
	public function reschedule_media_cleanup_event() {

		$this->unschedule_media_cleanup_event();
		$this->schedule_media_cleanup_event();

	}

	/**
	 * Returns the scheduled media cleanup event, if it exists
	 *
	 * @since   4.2.0
	 */
	public function get_media_cleanup_event() {

		return wp_get_schedule( $this->base->plugin->filter_name . '_media_cleanup_cron' );

	}

	/**
	 * Returns the scheduled media cleanup event's next date and time to run, if it exists
	 *
	 * @since   4.2.0
	 *
	 * @param   mixed $format     Format Timestamp (false | php date() compat. string).
	 */
	public function get_media_cleanup_event_next_scheduled( $format = false ) {

		// Get timestamp for when the event will next run.
		$scheduled = wp_next_scheduled( $this->base->plugin->filter_name . '_media_cleanup_cron' );

		// If no timestamp or we're not formatting the result, return it now.
		if ( ! $scheduled || ! $format ) {
			return $scheduled;
		}

		// Return formatted date/time.
		return gmdate( $format, $scheduled );
	}

	/**
	 * Schedules a single event in the WordPress CRON to refresh the access token(s)
	 * shortly before the earliest one expires.
	 *
	 * Access tokens are short lived and refresh tokens are single use, so refreshing
	 * proactively avoids requests failing with an authentication error, and avoids
	 * several requests attempting to refresh using the same refresh token at once.
	 *
	 * @since   6.2.0
	 */
	public function schedule_refresh_token_event() {

		// Clear any existing scheduled event.
		$this->unschedule_refresh_token_event();

		// Get the earliest expiry timestamp across all connected accounts.
		$token_expires = $this->get_earliest_token_expiry();

		// Bail only if no account has a refresh token.
		if ( $token_expires === false ) {
			return;
		}

		// The default number of seconds before an access token expires to refresh it.
		$seconds = 5 * MINUTE_IN_SECONDS;

		/**
		 * The number of seconds before an access token expires to refresh it.
		 *
		 * @since   6.2.0
		 *
		 * @param   int     $seconds    Seconds before expiry.
		 */
		$seconds = apply_filters( $this->base->plugin->filter_name . '_cron_refresh_token_seconds_before_expiry', $seconds );

		// Determine when to refresh.
		$refresh_at = $token_expires - $seconds;

		// If the refresh time is in the past, schedule the event for 1 minute from now.
		if ( $refresh_at <= time() ) {
			$refresh_at = time() + MINUTE_IN_SECONDS;
		}

		// Schedule event.
		wp_schedule_single_event( $refresh_at, $this->base->plugin->filter_name . '_refresh_token_cron' );

	}

	/**
	 * Unschedules the refresh token event in the WordPress CRON.
	 *
	 * @since   6.2.0
	 */
	public function unschedule_refresh_token_event() {

		wp_clear_scheduled_hook( $this->base->plugin->filter_name . '_refresh_token_cron' );

	}

	/**
	 * Reschedules the refresh token event in the WordPress CRON, based on the expiry
	 * of the stored access token(s).
	 *
	 * Called on upgrade, so that sites connected before this event existed get one
	 * scheduled without having to reconnect, and whenever a token is issued or
	 * refreshed, so that each token schedules the refresh of its successor.
	 *
	 * @since   6.2.0
	 */
	public function reschedule_refresh_token_event() {

		$this->schedule_refresh_token_event();

	}

	/**
	 * Returns the scheduled refresh token event, if it exists
	 *
	 * @since   6.2.0
	 *
	 * @return  mixed   bool | string
	 */
	public function get_refresh_token_event() {

		return wp_get_schedule( $this->base->plugin->filter_name . '_refresh_token_cron' );

	}

	/**
	 * Returns the scheduled refresh token event's next date and time to run, if it exists
	 *
	 * @since   6.2.0
	 *
	 * @param   mixed $format     Format Timestamp (false | php date() compat. string).
	 * @return  mixed               bool | int | string
	 */
	public function get_refresh_token_event_next_scheduled( $format = false ) {

		// Get timestamp for when the event will next run.
		$scheduled = wp_next_scheduled( $this->base->plugin->filter_name . '_refresh_token_cron' );

		// If no timestamp or we're not formatting the result, return it now.
		if ( ! $scheduled || ! $format ) {
			return $scheduled;
		}

		// Return formatted date/time.
		return gmdate( $format, $scheduled );

	}

	/**
	 * Returns the earliest access token expiry timestamp across all connected accounts.
	 *
	 * Accounts holding a refresh token but no expiry timestamp are treated as due now,
	 * returning zero, so that an event is still scheduled for them.
	 *
	 * @since   6.2.0
	 *
	 * @return  mixed   false | int    false if no account has a refresh token.
	 */
	private function get_earliest_token_expiry() {

		$earliest = false;

		foreach ( $this->base->get_class( 'settings' )->get_accounts() as $account ) {
			// Skip accounts with no refresh token, as there's nothing to refresh with.
			if ( empty( $account['refresh_token'] ) ) {
				continue;
			}

			// An account with no stored expiry is treated as due now, so that an
			// event is still scheduled for it.
			$token_expires = ( empty( $account['token_expires'] ) ? 0 : (int) $account['token_expires'] );

			// Compare against false explicitly, as a zero timestamp is a valid value
			// here and would otherwise be treated as "not yet set".
			if ( $earliest === false || $token_expires < $earliest ) {
				$earliest = $token_expires;
			}
		}

		return $earliest;

	}

	/**
	 * Runs the refresh token CRON event, exchanging each stored refresh token that is
	 * due to expire for a new access token.
	 *
	 * The API class fires an action on a successful refresh, which stores the new
	 * access token, refresh token and expiry against the account.
	 *
	 * @since   6.2.0
	 */
	public function refresh_token() {

		// Bail if the API class cannot refresh tokens, for example where the service
		// issues a token that does not expire.
		if ( ! method_exists( $this->base->get_class( 'api' ), 'refresh_token' ) ) {
			return;
		}

		// The default number of seconds before an access token expires to refresh it.
		$seconds = 5 * MINUTE_IN_SECONDS;

		/**
		 * The number of seconds before an access token expires to refresh it.
		 *
		 * @since   6.2.0
		 *
		 * @param   int     $seconds    Seconds before expiry.
		 */
		$seconds = apply_filters( $this->base->plugin->filter_name . '_cron_refresh_token_seconds_before_expiry', $seconds );

		// Iterate through accounts, refreshing any access token that is due to expire.
		foreach ( $this->base->get_class( 'settings' )->get_accounts() as $account ) {
			// Skip accounts with no refresh token, as there's nothing to refresh with.
			if ( empty( $account['refresh_token'] ) ) {
				continue;
			}

			// Skip accounts whose access token isn't due to expire yet.
			if ( ! empty( $account['token_expires'] ) && (int) $account['token_expires'] > ( time() + $seconds ) ) {
				continue;
			}

			// Refresh this account's access token.
			$this->base->get_class( 'api' )->set_tokens(
				$account['access_token'],
				$account['refresh_token'],
				$account['token_expires']
			);
			$this->base->get_class( 'api' )->refresh_token();
		}

		// Schedule the next event based on what is now stored.
		$this->schedule_refresh_token_event();

	}
}

```
