: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
namespace TwitterFeed\Admin;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
* Custom Twitter Feed Cache.
* CTF_Cache constructor. Set the feed id, cache key, legacy
public function __construct( $feed_id, $page = 1, $cache_time = 0 ) {
$this->cache_time = (int) $cache_time;
$this->is_legacy = strpos( $feed_id, '*' ) !== 0;
if ( $this->page === 1 ) {
$this->suffix = '_' . $this->page;
$this->feed_id = str_replace( '*', '', $feed_id );
$this->feed_id .= $this->maybe_customizer_suffix();
* Set all caches based on available data.
public function retrieve_and_set() {
$existing_caches = $this->query_ctf_feed_caches();
foreach ( $existing_caches as $cache ) {
switch ( $cache['cache_key'] ) {
$this->posts = $cache['cache_value'];
if ( strtotime( $cache['last_updated'] ) > time() - $this->cache_time ) {
if ( empty( $cache['cache_value'] ) ) {
case 'posts' . $this->suffix:
$this->posts_page = $cache['cache_value'];
$this->header = $cache['cache_value'];
case 'resized_images' . $this->suffix:
$this->resized_images = $cache['cache_value'];
case 'meta' . $this->suffix:
$this->meta = $cache['cache_value'];
case 'posts_backup' . $this->suffix:
$this->posts_backup = $cache['cache_value'];
case 'header_backup' . $this->suffix:
$this->header_backup = $cache['cache_value'];
$this->is_expired = $expired;
if ( $this->cache_time < 1 ) {
$this->is_expired = true;
* Whether or not the cache needs to be refreshed
* @param string $cache_type
public function is_expired( $cache_type = 'posts' ) {
if ( $cache_type !== 'posts' ) {
$cache = $this->get( $cache_type );
return ( empty( $cache ) || $this->is_expired );
if ( $this->page === 1 ) {
return $this->is_expired;
if ( $this->is_expired ) {
if ( empty( $this->posts_page ) ) {
* Get data currently stored in the database for the type
public function get( $type ) {
case 'posts' . $this->suffix:
$return = $this->posts_page;
$return = $this->resized_images;
$return = $this->posts_backup;
$return = $this->header_backup;
* @param array $cache_value
public function set( $type, $cache_value ) {
$this->posts = $cache_value;
case 'posts' . $this->suffix:
$this->posts_page = $cache_value;
$this->header = $cache_value;
$this->resized_images = $cache_value;
$this->meta = $cache_value;
$this->posts_backup = $cache_value;
$this->header_backup = $cache_value;
* Update a single cache with new data. Try to accept any data and convert it
* @param string $cache_type
* @param array|object|string $cache_value
* @param bool $include_backup
* @param bool $cron_update
public function update_or_insert( $cache_type, $cache_value, $include_backup = true, $cron_update = true ) {
if ( $this->page > 1 || ( $cache_type !== 'posts' && $cache_type !== 'header' ) ) {
if ( strpos( $this->feed_id, '_CUSTOMIZER' ) !== false ) {
$cache_key = $cache_type . $this->suffix;
$this->set( $cache_key, $cache_value );
if ( is_array( $cache_value ) || is_object( $cache_value ) ) {
$cache_value = ctf_json_encode( $cache_value );
$cache_table_name = $wpdb->prefix . 'ctf_feed_caches';
SELECT * FROM $cache_table_name
$existing = $wpdb->get_results( $sql, ARRAY_A );
$data['cache_value'] = $cache_value;
$data['last_updated'] = date( 'Y-m-d H:i:s' );
if ( ! empty( $existing[0] ) ) {
$where['feed_id'] = $this->feed_id;
$where['cache_key'] = $cache_key;
$affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format );
$data['cache_key'] = $cache_key;
$data['cron_update'] = $cron_update === true ? 'yes' : '';
$data['feed_id'] = $this->feed_id;
$affected = $wpdb->insert( $cache_table_name, $data, $format );
* Tasks to do after a new set of posts are retrieved
public function after_new_posts_retrieved() {
if ( $this->page === 1 ) {
* Resets caches after they expire
public function clear( $type ) {
$cache_table_name = $wpdb->prefix . 'ctf_feed_caches';
$feed_id = str_replace( array( '_CUSTOMIZER', '_CUSTOMIZER_MODMODE' ), '', $this->feed_id );
$affected = $wpdb->query(
"UPDATE $cache_table_name
AND cache_key NOT IN ( 'posts', 'posts_backup', 'header_backup' );",
$affected = $wpdb->query(
"UPDATE $cache_table_name
$mod_mode_where = esc_sql( $feed_id ) . '_CUSTOMIZER_MODMODE%';
$affected = $wpdb->query(
"UPDATE $cache_table_name
$data = array( 'cache_value' => '' );
$where['feed_id'] = $feed_id;
$where['cache_key'] = $type . $this->suffix;
$affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format );
$where['feed_id'] = $feed_id . '_CUSTOMIZER';
$affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format );
$where['feed_id'] = $feed_id . '_CUSTOMIZER_MODMODE';
$affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format );
public function get_customizer_cache() {
if ( strpos( $this->feed_id, '_CUSTOMIZER' ) === false ) {
$feed_id = $this->feed_id . '_CUSTOMIZER';
$feed_id = $this->feed_id;
$cache_table_name = $wpdb->prefix . 'ctf_feed_caches';
SELECT * FROM $cache_table_name
AND cache_key = 'posts'",
$results = $wpdb->get_results( $sql, ARRAY_A );
if ( ! empty( $results[0] ) ) {
$return = $results[0]['cache_value'];
$return = json_decode( $return, true );
$return = isset( $return['data'] ) ? $return['data'] : array();
* Clears caches in the WP Options table used mostly by legacy feeds.
* Also resets caches created by common page caching plugins
* @param false $hard_clear
public static function clear_legacy( $hard_clear = false ) {
$cache_table_name = $wpdb->prefix . 'ctf_feed_caches';
$affected = $wpdb->query(
"DELETE FROM $cache_table_name
WHERE feed_id LIKE ('ctf\_%')
AND cache_key NOT IN ( 'posts_backup', 'header_backup' );"
$affected = $wpdb->query(
"UPDATE $cache_table_name
WHERE feed_id LIKE ('ctf\_%')
AND cache_key NOT IN ( 'posts_backup', 'header_backup' );"
* Get all available caches from the ctf_cache table.
public function query_ctf_feed_caches() {
$feed_cache = wp_cache_get( $this->get_wp_cache_key() );
if ( false === $feed_cache ) {
$cache_table_name = $wpdb->prefix . 'ctf_feed_caches';
if ( $this->page === 1 ) {
SELECT * FROM $cache_table_name