: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
<?php namespace la\core\cache;
if ( ! defined( 'WPINC' ) ) die;
if ( ! defined('FF_FACEBOOK_RATE_LIMIT')) define('FF_FACEBOOK_RATE_LIMIT', 200);
use flow\social\cache\LAFacebookCacheManager as ILAFacebookCacheManager;
use flow\social\FFFeedUtils;
use flow\social\LASocialException;
use la\core\db\LADBManager;
* @author Looks Awesome <email@looks-awesome.com>
* @link http://looks-awesome.com
* @copyright Looks Awesome
class LAFacebookCacheManager implements ILAFacebookCacheManager {
protected static $postfix_at = 'la_facebook_access_token';
protected static $postfix_at_expires = 'la_facebook_access_token_expires';
private $access_token = null;
private $global_request_count;
private $global_request_array;
public function __construct($context) {
$this->db = LAUtils::dbm($context);
public function getError(){
$this->deleteOption($this->getNameExtendedAccessToken());
$this->deleteOption($this->getNameExtendedAccessToken(true));
$this->db->deleteOption('facebook_access_token');
* @return array|false|mixed|void|null
public function getAccessToken(){
if ($this->access_token != null) return $this->access_token;
if ($this->isExpiredToken()){
'message' => 'Access token is expired. Please go to AUTH tab to generate new token.'
if (false != ($token = $this->getStoredToken())){
if ($this->isExpiresToken()){
list($token, $expires, $error) = $this->refreshToken($token);
$this->save($token, $expires);
$this->db->update_options();
$this->access_token = $token;
'message' => 'Access token is not found. Please go to AUTH tab to generate token.'
protected function isExpiresToken() {
$expires = $this->getOption($this->getNameExtendedAccessToken(true));
return $expires === false || time() > ($expires - 2629743);
protected function isExpiredToken() {
$expires = $this->getOption($this->getNameExtendedAccessToken(true));
return $expires === false || time() > $expires;
protected function getStoredToken() {
$at = $this->getNameExtendedAccessToken();
if (false !== ($access_token_transient = $this->getOption($at))){
$access_token = $access_token_transient;
$auth = $this->getAuth();
$access_token = @$auth['facebook_access_token'];
if(!isset($access_token) || empty($access_token)){
protected function refreshToken( $oldToken ) {
$token_url = $this->getRefreshTokenUrl($oldToken);
$settings = $this->db->getGeneralSettings();
$response = FFFeedUtils::getFeedData($token_url, 20, false, true, $settings->useCurlFollowLocation(), $settings->useIPv4());
if (false !== $response['response']){
$response = (string)$response['response'];
$response = (array)json_decode($response);
$expires = (sizeof($response) > 2) ? (int)$response['expires_in'] : time() + 2629743*2;
$access_token = $response['access_token'];
return [ $access_token, $expires, null ];
else if (isset($response['errors'])) {
$error = $response['errors'][0];
'message' => $this->filter_error_message($error['msg']),
return [ null, null, false ];
public function save($token, $expires){
$this->updateOption($this->getNameExtendedAccessToken(), $token);
$this->updateOption($this->getNameExtendedAccessToken(true), time() + ( isset($expires) ? $expires : 2629743 ));
protected function getRefreshTokenUrl($access_token){
$auth = $this->getAuth();
$facebookAppId = $auth['facebook_app_id'];
$facebookAppSecret = $auth['facebook_app_secret'];
return "https://graph.facebook.com/oauth/access_token?client_id={$facebookAppId}&client_secret={$facebookAppSecret}&grant_type=fb_exchange_token&fb_exchange_token={$access_token}";
protected function getNameExtendedAccessToken($expires = false){
$auth = $this->getAuth();
$facebookAppId = $auth['facebook_app_id'];
$facebookAppSecret = $auth['facebook_app_secret'];
$name = $expires ? self::$postfix_at_expires : self::$postfix_at;
return $name . substr(hash('md5', $facebookAppId . $facebookAppSecret), 0, 6);
protected function getAuth(){
$this->auth = $this->db->getOption('fb_auth_options', true);
private function getOption($name){
return FF_USE_WP ? get_option($name) : $this->db->getOption($name);
private function updateOption($name, $value){
FF_USE_WP ? update_option($name, $value) : $this->db->setOption($name, $value);
private function deleteOption($name){
FF_USE_WP ? delete_option($name) : $this->db->deleteOption($name);
private function filter_error_message($message){
if (sizeof($message) > 0 && isset($message[0]['msg'])){
return stripslashes(htmlspecialchars($message[0]['msg'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'));
return stripslashes(htmlspecialchars($message, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'));
* @throws LASocialException
public function startCounter() {
$this->request_count = 0;
$this->hasHitLimit = false;
$conn = $this->db->conn();
if ( $conn->beginTransaction()){
$limit = $this->db->getOption('fb_limit_counter', true, true);
@$this->db->setOption('fb_limit_counter', [], true, false);
$limit = $this->db->getOption('fb_limit_counter', true, true);
throw new LASocialException('Can`t save `fb_limit_counter` option to mysql db.');
$this->creationTime = time();
$this->global_request_count = 0;
$limitTime = $this->creationTime - 3600;
foreach ( $limit as $time => $count ) {
if ($time > $limitTime) {
$this->global_request_count += (int)$count;
$this->global_request_array = $result;
if ($this->global_request_count + 4 > FF_FACEBOOK_RATE_LIMIT) {
throw new LASocialException('Your site has hit the Facebook API rate limit. <a href="http://docs.social-streams.com/article/133-facebook-app-request-limit-reached" target="_blank">Troubleshooting</a>.');
throw new LASocialException('Can`t get mysql transaction.');
public function stopCounter() {
if ($this->request_count > 0) {
$this->global_request_array[$this->creationTime] = $this->request_count;
$this->db->setOption('fb_limit_counter', $this->global_request_array, true, false);
$this->db->conn()->commit();
public function hasLimit() {
if ($this->hasHitLimit) return false;
if ($this->global_request_count + $this->request_count + 3 > FF_FACEBOOK_RATE_LIMIT) {
$this->hasHitLimit = true;
public function addRequest() {
public function getIdPosts($feedId) {
return $this->db->getIdPosts($feedId);