9. Connected social networks
Kết quả:
<?php
echo "<div class='aaaaaaaaaaa'>";
echo "<pre>";
var_export($profiles);
echo "</pre>";
echo "</div>";
die();
?>
(object) array(
'facebook' =>
array (
0 =>
(object) array(
'_id' => '60b210722e55684818ac0435',
'avatar' => 'https://scontent-dus1-1.xx.fbcdn.net/v/t1.6435-1/c39.0.100.100a/p100x100/36703701_148427009280426_2862236467424395264_n.jpg?_nc_cat=107&ccb=1-3&_nc_sid=dbb9e7&_nc_ohc=fIs9Hi_KamIAX_sAJb6&_nc_ht=scontent-dus1-1.xx&tp=27&oh=b5593c79ac63365ee1790d61c3f30eb0&oe=60DB97BA',
'avatar_https' => 'https://scontent-dus1-1.xx.fbcdn.net/v/t1.6435-1/c39.0.100.100a/p100x100/36703701_148427009280426_2862236467424395264_n.jpg?_nc_cat=107&ccb=1-3&_nc_sid=dbb9e7&_nc_ohc=fIs9Hi_KamIAX_sAJb6&_nc_ht=scontent-dus1-1.xx&tp=27&oh=b5593c79ac63365ee1790d61c3f30eb0&oe=60DB97BA',
'can_see_content_library' => false,
'counts' =>
(object) array(
'sent' => 9,
'pending-story-groups-with-errors' => 0,
'drafts' => 0,
'reminders' => 0,
'pending' => 0,
),
'cover_photo' => 'https://scontent-dus1-1.xx.fbcdn.net/v/t1.6435-9/36684023_148427169280410_7367504685294419968_n.jpg?_nc_cat=104&ccb=1-3&_nc_sid=1091cb&_nc_ohc=_z1ZbBW7b4IAX8_-Cr6&_nc_ht=scontent-dus1-1.xx&oh=b656aaa2f05e4b13f609d20841da9aed&oe=60DBB0C4',
'created_at' => 1622282354,
'default' => false,
'disabled' => false,
'disabled_features' =>
array (
),
'disconnected' => false,
'formatted_service' => 'Facebook Page',
'formatted_username' => 'Có 86.133 người theo dõi',
'id' => '60b210722e55684818ac0435',
'is_analyze_enabled' => false,
'is_on_business_v2' => false,
'location' => NULL,
'locked' => false,
'paused' => false,
'paused_schedules' =>
array (
),
'preferences' =>
(object) array(
),
'reports_logo' => NULL,
'schedules' =>
array (
0 =>
(object) array(
'days' =>
array (
0 => 'sun',
),
'times' =>
array (
),
),
1 =>
(object) array(
'days' =>
array (
0 => 'mon',
),
'times' =>
array (
),
),
2 =>
(object) array(
'days' =>
array (
0 => 'tue',
),
'times' =>
array (
),
),
3 =>
(object) array(
'days' =>
array (
0 => 'wed',
),
'times' =>
array (
),
),
4 =>
(object) array(
'days' =>
array (
0 => 'thu',
),
'times' =>
array (
),
),
5 =>
(object) array(
'days' =>
array (
0 => 'fri',
),
'times' =>
array (
),
),
6 =>
(object) array(
'days' =>
array (
0 => 'sat',
),
'times' =>
array (
),
),
),
'service' => 'facebook',
'service_id' => '148426725947121',
'service_type' => 'page',
'service_username' => 'Có 86.133 người theo dõi',
'shortener' =>
(object) array(
'domain' => 'buff.ly',
),
'timezone' => 'Europe/London',
'timezone_city' => 'London - Europe',
'user_id' => '60b20b90749c0b5a2013b833',
'utm_tracking' => 'disabled',
'verb' => 'post',
),
1 =>
(object) array(
'_id' => '60b21073eb3b04f8adaf8f8f',
'avatar' => 'https://scontent-iad3-1.xx.fbcdn.net/v/t1.18169-1/p100x100/15873436_1425522254139076_2021791658776998138_n.jpg?_nc_cat=106&ccb=1-3&_nc_sid=dbb9e7&_nc_ohc=i87bgsythwoAX8sri9R&_nc_ht=scontent-iad3-1.xx&tp=6&oh=abfeafdca021e0b49d6af25d29489934&oe=60E13816',
'avatar_https' => 'https://scontent-iad3-1.xx.fbcdn.net/v/t1.18169-1/p100x100/15873436_1425522254139076_2021791658776998138_n.jpg?_nc_cat=106&ccb=1-3&_nc_sid=dbb9e7&_nc_ohc=i87bgsythwoAX8sri9R&_nc_ht=scontent-iad3-1.xx&tp=6&oh=abfeafdca021e0b49d6af25d29489934&oe=60E13816',
'can_see_content_library' => false,
'counts' =>
(object) array(
'sent' => 3,
'pending-story-groups-with-errors' => 0,
'drafts' => 0,
'reminders' => 0,
'pending' => 0,
),
'cover_photo' => 'https://scontent-iad3-1.xx.fbcdn.net/v/t31.18172-8/17097934_1488416797849621_2761330093553928701_o.jpg?_nc_cat=103&ccb=1-3&_nc_sid=1091cb&_nc_ohc=RwKljJ991AEAX-q0ub1&_nc_ht=scontent-iad3-1.xx&oh=42953175e46e8e46d3515d4919bebeb9&oe=60E08DF9',
'created_at' => 1622282355,
'default' => false,
'disabled' => false,
'disabled_features' =>
array (
),
'disconnected' => false,
'formatted_service' => 'Facebook Page',
'formatted_username' => 'Học để khẳng định mình',
'id' => '60b21073eb3b04f8adaf8f8f',
'is_analyze_enabled' => false,
'is_on_business_v2' => false,
'location' => NULL,
'locked' => false,
'paused' => false,
'paused_schedules' =>
array (
),
'preferences' =>
(object) array(
),
'reports_logo' => NULL,
'schedules' =>
array (
0 =>
(object) array(
'days' =>
array (
0 => 'sun',
),
'times' =>
array (
),
),
1 =>
(object) array(
'days' =>
array (
0 => 'mon',
),
'times' =>
array (
),
),
2 =>
(object) array(
'days' =>
array (
0 => 'tue',
),
'times' =>
array (
),
),
3 =>
(object) array(
'days' =>
array (
0 => 'wed',
),
'times' =>
array (
),
),
4 =>
(object) array(
'days' =>
array (
0 => 'thu',
),
'times' =>
array (
),
),
5 =>
(object) array(
'days' =>
array (
0 => 'fri',
),
'times' =>
array (
),
),
6 =>
(object) array(
'days' =>
array (
0 => 'sat',
),
'times' =>
array (
),
),
),
'service' => 'facebook',
'service_id' => '1209125505778753',
'service_type' => 'page',
'service_username' => 'Học để khẳng định mình',
'shortener' =>
(object) array(
'domain' => 'buff.ly',
),
'timezone' => 'Europe/London',
'timezone_city' => 'London - Europe',
'user_id' => '60b20b90749c0b5a2013b833',
'utm_tracking' => 'disabled',
'verb' => 'post',
),
),
)
wp-content/plugins/lionel-setup-content/admin/class-lionel_content-settings.php
<?php
class Lionel_Content_Settings
{
private $plugin_name;
private $version;
private $buffer;
private $buffer_profiles;
public function __construct (Lionel_Content_Buffer $buffer) {
$this->buffer = $buffer;
$this->load_settings ();
}
public function load_settings () {
$this->buffer_token = $this->buffer->get_token ();
$this->buffer_profiles = $this->buffer->profiles();
}
public function load_page () {
$token = $this->buffer_token;
$profiles = $this->buffer_profiles;
?>
<div class="ecp-grid ecp-col-940 ecp-top-menu" ecp-registered="1">
<div class="ecp-header-wrapper">
<div class="ecp-grid ecp-col-700">
<div class="ecp-header-logo"></div>
<ul class="ecp-header-menu">
<li class="ecp-active-tab"><a class="ecp-tab-selector" href="#" data-link="ecp_settings"><span><?php _e('Settings', 'evergreen_content_poster'); ?></span></a></li>
<li class=""><a class="ecp-tab-selector" href="<?php echo get_bloginfo('wpurl'); ?>/wp-admin/admin.php?page=evergreen_content_library" data-link="ecp_content_library"><span><?php _e('Content Library', 'evergreen_content_poster'); ?></span></a></li>
</ul>
</div>
<div class="ecp-grid ecp-col-220 ecp-fit">
<?php
wp_nonce_field('evergreen-settings-save', 'evergreen-settings-save');
?>
<button id="save_settings" class="button ecp-navy-button ecp-save-settings" disabled><?php _e('Save Changes', 'evergreen_content_poster'); ?></button>
</div>
<div class="ecp-grid ecp-col-940 ecp-top-menu" ecp-registered="1">
<div class="ecp-grid ecp-col-940 ecp-fit ecp-loading-saving">Saving Settings</div>
<label class="hidden saving-default">Saving Settings</label>
<label class="hidden saving-success">Settings Saved!</label>
<label class="hidden saving-error">There was an error saving your settings. Please try again later.</label>
<label class="hidden saving-posting-time-success">Successfully added a new posting timeslot</label>
<label class="hidden saving-posting-time-error">There is an error trying to add this posting timeslot, please try again</label>
<label class="hidden delete-posting-time-success">Successfully deleted posting timeslot</label>
<label class="hidden delete-posting-time-error">There is an error trying to delete this posting timeslot, please try again</label>
<label class="hidden clear-posting-time-success">Successfully cleared posting timeslot</label>
<label class="hidden clear-posting-time-error">There is an error trying to clear this posting timeslot, please try again</label>
</div>
<div class="ecp-clearfix"></div>
</div>
<div class="ecp-wrapper">
<div class="ecp-container">
<div class="ecp-section">
<div class="ecp-grid ecp-col-700">
<form id="ecp_settings_form" method="post" action="<?php echo esc_html (admin_url ('admin-post.php')); ?>">
<div class="ecp-admin-tab ecp-grid ecp-col-940"
style="display: block;">
<div class="ecp-section ecp-grid ecp-col-940 ecp-fit ecp-option-container ecp-general-settings-title-wrapper">
<h2><?php _e('General Settings', 'evergreen_content_poster'); ?></h2>
</div>
<div class="ecp-grid ecp-col-940 ecp-option-container ecp-field-setting">
<div class="ecp-grid ecp-col-300">
<p class="ecp-input-label ecp-label-min-days"><?php _e('Minimum number of days not to repeat the same post', 'evergreen_content_poster'); ?></p>
<p class="description"><?php _e('If zero, this won\'t be taken into account and post can be potentially be posted twice on the same day.', 'evergreen_content_poster'); ?></p>
</div>
<div class="ecp-grid ecp-col-300">
<input type="number" name="eg_numberofdays" min="1" max="120" required="true" value="2" class="ecp-admin-input field-setting" data-ref="saved_numberofdays" aria-invalid="false" />
<input type="hidden" name="saved_numberofdays" value="1" />
</div>
</div>
<div class="ecp-section ecp-grid ecp-col-940 ecp-fit ecp-option-container ecp-social-networks-title-wrapper" id="connected_profiles">
<h2><a name="AccountSettings" style="color: #1b3a51"><?php _e('Account Settings', 'evergreen_content_poster'); ?></a></h2>
<div class="ecp-grid ecp-col-300 ecp-no-bottom-margin">
<?php if (!$token) : ?>
<a href="<?php echo $this->buffer->oauth_url(); ?>" class="button ecp-navy-button ecp-save-settings"><?php _e('Connect to Buffer', 'evergreen_content_poster'); ?></a>
<p><?php _e('Connect to Buffer to start using Evergreen Content Poster.', 'evergreen_content_poster'); ?> <?php _e('If you don\'t have a Buffer account yet, you can create a <a href="https://buffer.com/signup" target="_blank" class="ecp-link">free account here</a>.', 'evergreen_content_poster'); ?></p>
<?php else : ?>
<a href="<?php echo $this->buffer->deauthorize_url(); ?>" class="button ecp-green-button ecp-save-settings buffer-connected" data-connected="<?php _e('Connected to Buffer', 'evergreen_content_poster'); ?>" data-disconnect="<?php _e('Disconnect from Buffer', 'evergreen_content_poster'); ?>"><?php _e('Connected to Buffer', 'evergreen_content_poster'); ?></a>
<?php endif; ?>
</div>
</div>
<?php if ($token) : ?>
<?php
echo "<div class='aaaaaaaaaaa'>";
echo "<pre>";
var_export($profiles);
echo "</pre>";
echo "</div>";
die();
?>
<?php if (!empty($profiles)) : ?>
<div class="ecp-grid ecp-col-940 ecp-option-container ecp-field-setting">
<div class="ecp-grid ecp-col-300 ecp-no-bottom-margin">
<p><?php _e('Connected social networks', 'evergreen_content_poster'); ?></p>
</div>
</div>
<?php else : ?>
<div class="ecp-grid ecp-col-940 ecp-option-container ecp-field-setting">
<div class="ecp-grid ecp-col-300">
<p><?php _e('No profiles added to Buffer yet...', 'evergreen_content_poster'); ?></p>
<p><?php _e('Add a profile to start using the Evergreen Content Poster', 'evergreen_content_poster'); ?></p>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<?php
}
}
wp-content/plugins/lionel-setup-content/includes/class-lionel_content_buffer.php
<?php
/**
* The core Buffer class.
*
* This class is used for handling all Buffer related functions.
*
*
* @link https://usergrowth.io/
* @since 1.0.0
* @package Evergreen_Content_Poster
* @subpackage Evergreen_Content_Poster/includes
* @author usergrowth <info@usergrowth.io>
*
*
* $client_id = '';
* $client_secret = '';
* $callback_url = '';
* $buffer = new BufferApp($client_id, $client_secret, $callback_url);
*
*/
class Lionel_Content_Buffer {
private $client_id;
private $client_secret;
private $code;
private $access_token;
private $callback_url;
private $authorize_url = 'https://bufferapp.com/oauth2/authorize';
private $access_token_url = 'https://api.bufferapp.com/1/oauth2/token.json';
private $buffer_url = 'https://api.bufferapp.com/1';
/**
* The service OAuth URL
*/
private $oauth_url;
private $redirect_uri;
/**
* The plugin option fields
*/
private $option_token = LIONEL_CONTENT_KEY_PREFIX . '_buffer_token';
private $option_general_settings = LIONEL_CONTENT_KEY_PREFIX . '_general_settings';
private $option_schedule_settings = LIONEL_CONTENT_KEY_PREFIX . '_schedule_settings';
private $option_profiles = LIONEL_CONTENT_KEY_PREFIX . '_buffer_profiles';
private $option_timezone = LIONEL_CONTENT_KEY_PREFIX . '_timezone';
public $ok = false;
private $endpoints = array(
'/user' => 'get',
'/profiles' => 'get',
'/profiles/:id/schedules/update' => 'post',
'/profiles/:id/updates/reorder' => 'post',
'/profiles/:id/updates/pending' => 'get',
'/profiles/:id/updates/sent' => 'get',
'/profiles/:id/schedules' => 'get',
'/profiles/:id' => 'get',
'/updates/:id/update' => 'post',
'/updates/create' => 'post',
'/updates/:id/destroy' => 'post',
'/updates/:id' => 'get',
'/links/shares' => 'get',
);
public $errors = array(
'invalid-endpoint' => 'The endpoint you supplied does not appear to be valid.',
'401' => 'Unauthorized.',
'403' => 'Permission denied.',
'404' => 'Endpoint not found.',
'405' => 'Method not allowed.',
'1000' => 'An unknown error occurred.',
'1001' => 'Access token required.',
'1002' => 'Not within application scope.',
'1003' => 'Parameter not recognized.',
'1004' => 'Required parameter missing.',
'1005' => 'Unsupported response format.',
'1010' => 'Profile could not be found.',
'1011' => 'No authorization to access profile.',
'1012' => 'Profile did not save successfully.',
'1013' => 'Profile schedule limit reached.',
'1014' => 'Profile limit for user has been reached.',
'1020' => 'Update could not be found.',
'1021' => 'No authorization to access update.',
'1022' => 'Update did not save successfully.',
'1023' => 'Update limit for profile has been reached.',
'1024' => 'Update limit for team profile has been reached.',
'1028' => 'Update soft limit for profile reached.',
'1030' => 'Media filetype not supported.',
'1031' => 'Media filesize out of acceptable range.',
);
public $responses = array(
'403' => 'Permission denied.',
'404' => 'Endpoint not found.',
'405' => 'Method not allowed.',
'500' => 'An unknown error occurred.',
'403' => 'Access token required.',
'403' => 'Not within application scope.',
'400' => 'Parameter not recognized.',
'400' => 'Required parameter missing.',
'406' => 'Unsupported response format.',
'404' => 'Profile could not be found.',
'403' => 'No authorization to access profile.',
'400' => 'Profile did not save successfully.',
'403' => 'Profile schedule limit reached.',
'403' => 'Profile limit for user has been reached.',
'404' => 'Update could not be found.',
'403' => 'No authorization to access update.',
'400' => 'Update did not save successfully.',
'403' => 'Update limit for profile has been reached.',
'403' => 'Update limit for team profile has been reached.',
'403' => 'Update soft limit for profile reached.',
'400' => 'Media filetype not supported.',
'400' => 'Media filesize out of acceptable range.',
);
function __construct($client_id = '', $client_secret = '', $callback_url = '') {
if ($client_id) $this->set_client_id($client_id);
if ($client_secret) $this->set_client_secret($client_secret);
if ($callback_url) $this->set_callback_url($callback_url);
if ( !empty($_GET['code']) ) {
$this->code = sanitize_text_field($_GET['code']);
$this->create_access_token_url();
}
$this->client_id = '562a5c440ad287301db8c3ad';
$this->redirect_uri = 'https://api.usergrowth.io/';
$this->oauth_url = 'https://buffer.com/oauth2/authorize?client_id=592d41d14d97ab7e4e571edb&redirect_uri=https%3A%2F%2Fapi.usergrowth.io%2F%3Foauth%3Dbuffer&response_type=code&state=' . urlencode(admin_url('/admin.php?page=lionel_content_settings') );
$this->retrieve_access_token();
$this->profiles = $this->load_profiles();
$this->load_dependencies();
$this->setting = new Lionel_Content_Buffer_Setting();
$this->schedule = new Lionel_Content_Buffer_Schedule();
}
public function load_dependencies() {
/**
* The wrapper class responsible for defining all methods for buffer integration.
*/
require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-lionel_content_buffer_setting.php';
require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-lionel_content_buffer_schedule.php';
}
/**
* Function to
*
* @since 1.0.0
*
*/
function go($endpoint = '', $data = '') {
if (in_array($endpoint, array_keys($this->endpoints))) {
$done_endpoint = $endpoint;
} else {
$ok = false;
foreach (array_keys($this->endpoints) as $done_endpoint) {
if (preg_match('/' . preg_replace('/(\:\w+)/i', '(\w+)', str_replace('/', '\/', $done_endpoint)) . '/i', $endpoint, $match)) {
$ok = true;
break;
}
}
if (!$ok) return $this->error('invalid-endpoint');
}
if (!$data || !is_array($data)) $data = array();
$data['access_token'] = $this->access_token;
$method = $this->endpoints[$done_endpoint]; //get() or post()
return $this->$method($this->buffer_url . $endpoint . '.json', $data);
}
/**
* Function to
*
* @since 1.0.0
*
*/
function store_access_token() {
$_SESSION['oauth']['buffer']['access_token'] = $this->access_token;
}
function retrieve_access_token() {
$this->access_token = $this->get_token();
if ( !is_null( $this->access_token ) ) {
$this->ok = true;
}
}
/**
* Function to
*
* @since 1.0.0
*
*/
function error($error) {
return (object) array('error' => $this->errors[$error]);
}
/**
* Function to
*
* @since 1.0.0
*
*/
function create_access_token_url() {
$data = array(
'code' => $this->code,
'grant_type' => 'authorization_code',
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'redirect_uri' => $this->callback_url,
);
$obj = $this->post($this->access_token_url, $data);
$this->access_token = $obj->access_token;
$this->store_access_token();
}
/**
* Function to
*
* @since 1.0.0
*
*/
function req($url = '', $data = '', $post = true) {
if (!$url) return false;
if (!$data || !is_array($data)) $data = array();
$options = array(CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false);
if ($post) {
$options += array(
CURLOPT_POST => $post,
CURLOPT_POSTFIELDS => $data
);
} else {
$url .= '?' . http_build_query($data);
}
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$rs = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($code >= 400) {
return $this->error($code);
}
return json_decode($rs);
}
/**
* Function to
*
* @since 1.0.0
*
*/
function get($url = '', $data = '') {
return $this->req($url, $data, false);
}
function post($url = '', $data = '') {
return $this->req($url, $data, true);
}
/**
* Function to
*
* @since 1.0.0
*
*/
function get_login_url() {
return $this->authorize_url . '?'
. 'client_id=' . $this->client_id
. '&redirect_uri=' . urlencode($this->callback_url)
. '&response_type=code';
}
/**
* Function to
*
* @since 1.0.0
*
*/
function set_client_id($client_id) {
$this->client_id = $client_id;
}
/**
* Function to
*
* @since 1.0.0
*
*/
function set_client_secret($client_secret) {
$this->client_secret = $client_secret;
}
/**
* Function to
*
* @since 1.0.0
*
*/
function set_callback_url($callback_url) {
$this->callback_url = $callback_url;
}
/**
* Public function to save the Buffer auth token to the
* WordPress wp_options table
*
* @since 1.0.0
*
*/
public function save_token ( $token ) {
// If the current logged-in user can't edit option values, abort
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
$token = esc_sql($token);
if ( empty($token) ) {
return false;
}
// Check to see if the token is saved
$current_token = $this->get_token();
if ( null === $current_token ) {
$success = add_option( $this->option_token, $token );
} else {
$success = update_option( $this->option_token, $token );
}
// Double check to see if the token is saved, if not force saving via direct query
$current_token = $this->get_token();
if ( null === $current_token ) {
global $wpdb;
$query = 'select * from ' . $wpdb->options . ' where option_name = "' . $this->option_token . '" limit 1';
echo "<pre>";
var_export($query);
echo "</pre>";
die();
$row = $wpdb->get_row($query);
if ( ! empty($row) ) {
$wpdb->query(
$wpdb->prepare(
"DELETE FROM $wpdb->options
WHERE option_name = %s
LIMIT 1
",
$this->option_token
)
);
}
// prepare an insert of new token
$affected_rows = $wpdb->insert(
// $wpdb->prefix . 'options',
$wpdb->options,
array(
'option_name' => $this->option_token,
'option_value' => $token
)
);
if ( $affected_rows ) {
$success = $wpdb->insert_id;
}
}
return $success;
}
/**
* Public function that triggers a series of actions
* to deauthorize Buffer access in local install
*
* @since 1.0.0
*
*/
public function deauthorize() {
// first delete token
$this->remove_token();
// get curent profile
$profiles = json_decode($this->profiles);
$pre_profiles = array();
foreach ($profiles as $service => $profile) {
$pre_profiles[$service] = array();
foreach ($profile as $value) {
$temp = new stdClass();
$temp->id = $value->id;
$temp->formatted_username = $value->formatted_username;
$pre_profiles[$service][] = $temp;
}
}
// Save the profile last time to compare with the next connection
$pre_profiles_json = json_encode($pre_profiles);
// save pre_profile
$pre_profile_db = get_option('ecp_buffer_pre_profile');
if ( null === $pre_profile_db ) {
$success = add_option('ecp_buffer_pre_profile', $pre_profiles_json);
} else {
$success = update_option('ecp_buffer_pre_profile', $pre_profiles_json);
}
// then delete profiles
$this->remove_profiles();
}
/**
* Public function to remove the Buffer auth token from the
* WordPress wp_options table
*
* @since 1.0.0
*
*/
public function remove_token() {
// if user can't edit option values, abort
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
// delete_user_meta( $user_id, 'ecp_buffer_access_token' );
delete_option( $this->option_token );
}
/**
* Public function to fetch the current stored Buffer
* auth token from the
*
* @since 1.0.0
*
*/
public function get_token() {
$token = get_option( $this->option_token );
// "false" if token does not exist (plugin is deauthorized)
// "null" if plugin is activated first time but no connection has been made yet to Buffer
if ( !$token || 'null' == $token )
return false;
return $token;
}
public function oauth_url() {
// Return oAuth URL
return 'https://bufferapp.com/oauth2/authorize?client_id=' . $this->client_id . '&redirect_uri=' . urlencode( $this->redirect_uri ) . '&response_type=code&state=' . urlencode( admin_url( 'admin.php?page=lionel_content_settings' ) );
}
public function deauthorize_url() {
return '/wp-admin/admin.php?page=lionel_content_settings&action=ba_remove';
}
public function fetch_profiles() {
$token = $this->get_token();
if ( is_null( $token ) )
return false;
$access_token_slug = '?access_token=' . $token;
// get user's info configuration first
// Note: it is highly recommended to call this endpoint first before getting list of profiles for authenticated user.
$get_buffer_info_config = 'https://api.bufferapp.com/1/info/configuration.json' . $access_token_slug;
$buffer_info_response = wp_remote_get(
$get_buffer_info_config,
array(
'timeout' => 60,
'sslverify' => false,
)
);
if ( is_array( $buffer_info_response ) && ! is_wp_error( $buffer_info_response ) ) {
$info_response_decoded = json_decode( wp_remote_retrieve_body( $buffer_info_response ) );
}
$get_buffer_profiles = 'https://api.bufferapp.com/1/profiles.json' . $access_token_slug;
$buffer_response = wp_remote_get(
$get_buffer_profiles,
array(
'timeout' => 60,
'sslverify' => false,
)
);
$twitter_profile_ids = [];
$profiles = [];
if ( is_array( $buffer_response ) && ! is_wp_error( $buffer_response ) ) {
$response_decoded = json_decode( wp_remote_retrieve_body( $buffer_response ) );
// update_term_meta($dispensary_id, 'dispensary_tax_info', $response_decoded->taxRateInfo );
if ( !is_null($response_decoded) ) {
foreach ($response_decoded as $key => $profile_object) {
$get_buffer_profile_single = 'https://api.bufferapp.com/1/profiles/' . $profile_object->id . '.json?access_token=' . $this->get_token();
// $get_buffer_profile_single = 'https://api.bufferapp.com/1/profiles/' . $profile_object->user_id . '.json';
$profile_single_response = wp_remote_get(
$get_buffer_profile_single,
array(
'timeout' => 60,
'sslverify' => false,
)
);
if ( is_array( $profile_single_response ) && ! is_wp_error( $profile_single_response ) ) {
$single_response_decoded = json_decode( wp_remote_retrieve_body( $profile_single_response ) );
if ( !empty($single_response_decoded) ) {
if ( 'twitter' == $single_response_decoded->service) {
$twitter_profile_ids[] = $single_response_decoded->service_id;
}
// exclude Facebook personal profiles
if ( 'facebook' == $single_response_decoded->service && 'profile' == $single_response_decoded->service_type )
continue;
$profiles[ $single_response_decoded->service ][] = $single_response_decoded;
}
}
}
}
}
$get_twitter_profile = 'https://api.usergrowth.io/?service_id=' . implode(',', $twitter_profile_ids) . '&action=twitter_request&type=query_user';
$ug_api_response = wp_remote_get(
$get_twitter_profile,
array(
'timeout' => 60,
'sslverify' => false,
)
);
if ( is_array( $ug_api_response ) && ! is_wp_error( $ug_api_response ) ) {
$ug_response_body = json_decode( wp_remote_retrieve_body( $ug_api_response ) );
if (isset($profiles['twitter'])) {
foreach ($profiles['twitter'] as $key => $twitter_profile) {
foreach ($ug_response_body->data as $twitter_user) {
if ($twitter_user->id == $twitter_profile->service_id) {
$twitter_profile->formatted_username = $twitter_user->username;
$twitter_profile->service_username = $twitter_user->username;
$twitter_profile->avatar = $twitter_user->profile_image_url;
$twitter_profile->avatar_https = $twitter_user->profile_image_url;
$profiles['twitter'][$key] = $twitter_profile;
}
}
}
}
}
// save profile schedules to settings
$schedules_setting = $this->schedules();
$schedules = isset($schedules_setting['schedules']) ? $schedules_setting['schedules'] : [];
foreach ($profiles as $service => $service_profiles) {
foreach ($service_profiles as $profile) {
if (!isset($schedules[strtolower($service)][$profile->id]) || empty($schedules[strtolower($service)][$profile->id])) {
$schedules_init = array();
foreach ($profile->schedules as $std) {
$std->times = array();
$schedules_init[] = $std;
}
$schedules[strtolower($service)][$profile->id] = $schedules_init;
}
}
}
// get pre_profile
$pre_profile = get_option('ecp_buffer_pre_profile');
if (isset($pre_profile) && !is_null($pre_profile)) {
$pre_profile = json_decode($pre_profile);
$pre_profile_delete = array();
if (!empty($pre_profile)) {
foreach ($pre_profile as $service => $profile) {
foreach ($profile as $k => $item) {
foreach ($profiles as $service_temp => $value) {
if ($service == $service_temp) {
foreach ($value as $row) {
if ($item->id == $row->id) {
unset($profile[$k]);
}
}
}
}
}
$pre_profile_delete[$service] = $profile;
}
}
if (!empty($pre_profile_delete)) {
foreach ($pre_profile_delete as $service => $profile) {
if (!empty($profile)) {
$network_names = '';
foreach ($profile as $item) {
unset($schedules[strtolower($service)][$item->id]);
$network_names .= $item->formatted_username . ', ';
}
$network_names = trim($network_names, ', ');
// show notify delete schedule
if (!session_id()) {
session_start();
}
$_SESSION['show_delete_schedule'] = true;
$_SESSION['message'] = sprintf ( __ ( 'Network %s has been removed from Buffer, we also removed it from your schedule', 'lionel_content_poster' ),
$network_names);
}
}
}
}
$schedules_setting['schedules'] = $schedules;
$this->save_schedules($schedules_setting);
$profiles_encoded = json_encode($profiles);
$this->save_profiles($profiles_encoded);
return $profiles_encoded;
}
/**
* Load existing Buffer profile schedules stored in options table
*/
public function load_schedules() {
return get_option( $this->option_schedule_settings );
}
/**
* Delete stored Buffer profile schedules
*/
public function remove_schedules() {
return delete_option ( $this->option_schedule_settings );
}
public function save_schedules($schedules) {
// if user can't edit option values, abort
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
// $profiles = esc_sql($profiles);
if ( empty($schedules) ) {
return false;
}
$current_schedules = $this->load_schedules();
if ( false === $current_schedules ) {
$success = add_option( $this->option_schedule_settings, $schedules );
} else {
$success = update_option( $this->option_schedule_settings, $schedules );
}
return $success;
}
/**
* Save Buffer user profiles to WP options
* $profiles text The JSON encoded string of user profile objects
*/
public function save_profiles( $profiles ) {
// if user can't edit option values, abort
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
// $profiles = esc_sql($profiles);
if ( empty($profiles) ) {
return false;
}
$current_profiles = $this->load_profiles();
if ( false === $current_profiles ) {
$success = add_option( $this->option_profiles, $profiles );
} else {
$success = update_option( $this->option_profiles, $profiles );
}
return $success;
}
/**
* Load existing Buffer profiles stored in options table
*/
public function load_profiles() {
return get_option( $this->option_profiles );
}
/**
* Delete stored Buffer profiles
*/
public function remove_profiles() {
return delete_option ( $this->option_profiles );
}
public function profiles() {
if ( !$this->get_token() )
return [];
$refetch = false;
if ( empty( $this->profiles ) )
$refetch = true;
if (null == json_decode( $this->profiles ))
$refetch = true;
if ($refetch)
$this->profiles = $this->fetch_profiles();
if ( !$this->profiles )
return [];
return json_decode( $this->profiles );
}
public function general_settings() {
$settings = get_option( $this->option_general_settings );
// "false" if token does not exist (plugin is deauthorized)
// "null" if plugin is activated first time but no connection has been made yet to Buffer
if ( !$settings || empty( $settings ) ) {
$settings = [
'eg_timezone' => $this->timezone(),
'eg_position' => 'top',
'eg_postingorder' => 'random',
'eg_numberofdays' => 0,
'utm_tags' => 'N'
];
}
if (!isset($settings['ecp_posting_schedule']))
$settings['ecp_posting_schedule'] = 'timestamp';
return $settings;
}
public function save_settings($settings) {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
if ( empty($settings) ) {
return false;
}
$success = update_option( $this->option_general_settings, $settings );
return $success;
}
public function schedules() {
$settings = get_option( $this->option_schedule_settings );
// "false" if token does not exist (plugin is deauthorized)
// "null" if plugin is activated first time but no connection has been made yet to Buffer
if ( !$settings || empty( $settings ) )
return [
'schedules' => [],
'generals' => []
];
return $settings;
}
public function default_schedule() {
return [
'hour' => 0,
'minute' => 0,
'day_period' => 'PM'
];
}
/**
* Return an array of connected networks
*/
public function networks() {
$networks = [];
foreach ( $this->profiles() as $key => $profiles ) {
foreach ( $profiles as $key => $single_profile) {
$networks[ $single_profile->id ] = [
'service' => $single_profile->service,
'formatted_service' => $single_profile->formatted_service . ' (' . $single_profile->formatted_username .')',
'avatar' => $single_profile->avatar
];
}
// }
}
return $networks;
}
/**
* Get Buffer plugin timezone. Else, return default WP timezone.
*/
public function timezone() {
$timezone = $this->load_timezone();
// "false" if token does not exist (plugin is deauthorized)
// "null" if plugin is activated first time but no connection has been made yet to Buffer
if ( !$timezone || 'null' == $timezone )
$timezone = $this->wp_timezone();
return $timezone;
}
public function load_timezone() {
return get_option( $this->option_timezone );
}
public function wp_timezone() {
// timezone here is timezone set from WP admin backend
$timezone = get_option('timezone_string');
// if ( empty($timezone) )
// $timezone = 'UTC+0';
return empty($timezone) ? 'UTC+0' : $timezone;
}
/**
* Checks if an access token was set. Called by any function which
* performs a call to the API
*
* @since 1.0.0
*
* @return bool Token Exists
*/
private function check_access_token_exists() {
if ( empty( $this->access_token ) ) {
return false;
}
return true;
}
/**
* Creates an update to Buffer
*
* @since 1.0.0
*
* @param array $params Params
* @return mixed WP_Error | Update object
*/
public function updates_create( $params ) {
// Check access token
if ( ! $this->check_access_token_exists() ) {
return false;
}
// Send request
$result = $this->post_buffer( 'updates/create.json', $params );
// Bail if the result is an error
if ( is_wp_error( $result ) ) {
return $result;
}
// Return array of just the data we need to send to the Plugin
return array(
'id' => $result->updates[0]->_id,
'profile_id' => $result->updates[0]->profile_id,
'message' => $result->message,
'status_text' => $result->updates[0]->text,
'status_created_at' => $result->updates[0]->created_at,
'due_at' => $result->updates[0]->due_at,
);
}
/**
* Get the posts pending in the buffer
*
* @since 1.0.0
*
* @param array $profileId String
* @param array $params Params
* @return mixed WP_Error | Update object
*/
public function updates_pending( $profileId, $params = array() ) {
// Check access token
if ( ! $this->check_access_token_exists() ) {
return false;
}
// Send request
$result = $this->get_buffer( 'profiles/' . $profileId . '/updates/pending.json', $params );
// Bail if the result is an error
if ( is_wp_error( $result ) ) {
return $result;
}
// Return array of just the data we need to send to the Plugin
return array(
'profile_id' => $profileId,
'total' => $result->total
);
}
/**
* Private function to perform a POST request to Buffer
*
* @since 1.0.0
*
* @param string $cmd Command (required)
* @param array $params Params (optional)
* @return mixed WP_Error | object
*/
private function post_buffer( $cmd, $params = array() ) {
return $this->request( $cmd, 'post', $params );
}
private function get_buffer( $cmd, $params = array() ) {
return $this->request( $cmd, 'get', $params );
}
/**
* Main function which handles sending requests to the Buffer API
*
* @since 1.0.0
*
* @param string $cmd Command
* @param string $method Method (get|post)
* @param array $params Parameters (optional)
* @return mixed WP_Error | object
*/
private function request( $cmd, $method = 'get', $params = array() ) {
// Check required parameters exist
if ( empty( $this->access_token ) ) {
return new WP_Error( 'missing_access_token', __( 'No access token was specified', 'evergreen_content_poster' ) );
}
// Add access token to command, depending on the command's format
if ( strpos ( $cmd, '?' ) !== false ) {
$cmd .= '&access_token=' . $this->access_token;
} else {
$cmd .= '?access_token=' . $this->access_token;
}
// Build endpoint URL
$url = 'https://api.bufferapp.com/' . '1' . '/' . $cmd;
// Define the timeout
$timeout = 20;
/**
* Defines the number of seconds before timing out a request to the Buffer API.
*
* @since 1.0.0
*
* @param int $timeout Timeout, in seconds
*/
$timeout = apply_filters( 'evergreen_content_poster' . '_buffer_api_request', $timeout );
// Request via WordPress functions
$result = $this->request_wordpress( $url, $method, $params, $timeout );
// Request via cURL if WordPress functions failed
// if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) {
// if ( is_wp_error( $result ) ) {
// $result = $this->request_curl( $url, $method, $params, $timeout );
// }
// }
// Result will be WP_Error or the data we expect
return $result;
}
/**
* Performs POST and GET requests through WordPress wp_remote_post() and
* wp_remote_get() functions
*
* @since 1.0.0
*
* @param string $url URL
* @param string $method Method (post|get)
* @param array $params Parameters
* @param int $timeout Timeout, in seconds (default: 10)
* @return mixed WP_Error | object
*/
private function request_wordpress( $url, $method, $params, $timeout = 20 ) {
// Send request
switch ( $method ) {
/**
* GET
*/
case 'get':
$response = wp_remote_get( $url, array(
'body' => $params,
'timeout' => $timeout,
) );
break;
/**
* POST
*/
case 'post':
$response = wp_remote_post( $url, array(
'body' => $params,
'timeout' => $timeout,
) );
break;
}
// If an error occured, return it now
if ( is_wp_error( $response ) ) {
return $response;
}
// Fetch HTTP code and body
$http_code = wp_remote_retrieve_response_code( $response );
$response = wp_remote_retrieve_body( $response );
// Parse the response, to return the JSON data or an WP_Error object);
return $this->parse_response( $response, $http_code, $params );
}
/**
* Performs POST and GET requests through PHP's curl_exec() function.
*
* If this function is called, request_wordpress() failed, most likely
* due to a DNS lookup failure or CloudFlare failing to respond.
*
* We therefore use CURLOPT_RESOLVE, to tell cURL the IP address for the domain.
*
* @since 1.0.0
*
* @param string $url URL
* @param string $method Method (post|get)
* @param array $params Parameters
* @param int $timeout Timeout, in seconds (default: 20)
* @return mixed WP_Error | object
*/
private function request_curl( $url, $method, $params, $timeout = 20 ) {
// Bail if cURL isn't installed
if ( ! function_exists( 'curl_init' ) ) {
return new WP_Error(
'lionel_content' . '_api_request_curl',
sprintf(
__( '%s requires the PHP cURL extension to be installed and enabled by your web host.', 'lionel_content' ),
'lionel_content'
)
);
}
// Init
$ch = curl_init();
switch ( $method ) {
/**
* GET
*/
case 'get':
curl_setopt_array( $ch, array(
CURLOPT_URL => $url . '&' . http_build_query( $params ),
CURLOPT_RESOLVE => array(
str_replace( 'https://', '', 'https://api.bufferapp.com/' ) . ':443:104.16.97.40',
str_replace( 'https://', '', 'https://api.bufferapp.com/' ) . ':443:104.16.98.40',
),
) );
break;
/**
* POST
*/
case 'post':
curl_setopt_array( $ch, array(
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query( $params ),
CURLOPT_RESOLVE => array(
str_replace( 'https://', '', 'https://api.bufferapp.com/' ) . ':443:104.16.97.40',
str_replace( 'https://', '', 'https://api.bufferapp.com/' ) . ':443:104.16.98.40',
),
) );
break;
}
// }
// Set shared options
curl_setopt_array( $ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_CONNECTTIMEOUT => $timeout,
CURLOPT_TIMEOUT => $timeout,
) );
// Execute
$response = curl_exec( $ch );
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
$error = curl_error( $ch );
curl_close( $ch );
// If our error string isn't empty, something went wrong
if ( ! empty( $error ) ) {
return new WP_Error( 'lionel_content' . '_api_request_curl', $error );
}
// Parse the response, to return the JSON data or an WP_Error object
// var_dump($this->parse_response( $response, $http_code, $params )); die;
return $this->parse_response( $response, $http_code, $params );
}
/**
* Parses the response body and HTTP code, returning either
* a WP_Error object or the JSON decoded response body
*
* @since 1.0.0
*
* @param string $response Response Body
* @param int $http_code HTTP Code
* @param array $params Request Parameters
* @return mixed WP_Error | object
*/
private function parse_response( $response, $http_code, $params ) {
// Decode response
$body = json_decode( $response );
// Return body if HTTP code is 200
if ( $http_code == 200 ) {
return $body;
}
// Return basic WP_Error if we don't have any more information
if ( is_null( $body ) ) {
return new WP_Error(
$http_code,
sprintf(
__( 'Buffer API Error: HTTP Code %s. Sorry, we don\'t have any more information about this error. Please try again.', 'lionel_content' ),
$http_code
)
);
}
// Return detailed WP_Error
// Define the error message
$message = array();
if ( isset( $body->error ) ) {
$message[] = $body->error;
}
if ( isset( $body->message ) ) {
$message[] = $body->message;
}
// For certain error codes, we can provide better error messages to the user, detailing
// the steps they should take to resolve the issue.
if (isset($body->code)) {
switch ( $body->code ) {
/**
* Unauthorized
* Permission Denied
* Access Token Required
*/
case 401:
case 403:
case 1001:
$message[] = __( 'Click the "Disconnect from Buffer" button, and then the "Connect to Buffer" button on the Plugin\'s Settings screen', 'lionel_content' );
break;
/**
* Parameter not recognized (invalid image url parameter supplied)
*/
case 1003:
$message[] = __( 'Run this Plugin on a publicly accessible domain that does not have password protection.', 'lionel_content' );
break;
/**
* Featured Image Missing
* Message too long
*/
case 1004:
// Image missing
if ( strpos( $body->message, 'image' ) !== false ) {
// If the site isn't web accessible, Buffer won't be able to fetch the image, even if it's specified
if ( $this->is_local_host() ) {
$message = array(
__( 'Buffer can\'t fetch the image because your site is running on a local host and not web accessible. Please run the Plugin on a publicly accessible domain.', 'lionel_content' )
);
} else {
$message = array(
__( 'Specify a Featured Image, Additional Image or an image in the Post Content.', 'lionel_content' )
);
}
}
break;
/**
* No authorization to access profile
*/
case 1011:
$message[] = sprintf(
__( 'Pinterest: Choose a Pinterest board in the status settings. Otherwise, reconnect the %s Account %s in Buffer.', 'lionel_content' ),
$profile['formatted_service'],
$profile['formatted_username'],
'https://faq.buffer.com/article/294-publish-reconnect-social-account'
);
break;
case 1023:
$message = __( 'Your Twitter queue is full at Buffer, try again later or upgrade to <a href="https://buffer.com/pro" target="_blank">a paid Buffer plan</a>', 'lionel_content' );
break;
/**
* Duplicate update
*/
case 1025:
$message = __( 'Whoops, you try to send the same message multiple times to soon after each other. Try again later.', 'lionel_content' );
break;
/**
* Media filetype not supported (...)
* The provided image does not appear to be valid
*/
case 1030:
if ( $this->is_local_host() ) {
$message = array(
__( 'Buffer can\'t fetch the image because your site is running on a local host and not web accessible. Please run the Plugin on a publicly accessible domain.', 'lionel_content' )
);
} else {
$message = __('Whoops, there seem to be an issue with your image. Can you upload a new one?', 'lionel_content');
}
break;
/**
* Cannot schedule updates in the past
*/
case 1034:
if ( isset( $params['scheduled_at'] ) ) {
$message[] = sprintf(
__( 'The Custom Time (based on Custom Field / Post Meta Value) field cannot be %s, which is a date in the past.', 'lionel_content' ),
$params['scheduled_at']
);
} else {
$message[] = sprintf(
__( '<a href="%s">WordPress</a> and <a href="%s">%s</a> timezones must match.', 'lionel_content' ),
admin_url( 'options-general.php' ),
$this->get_timezone_settings_url( $params['profile_ids'][0] )
);
}
break;
}
} else {
$body->code = 500;
}
if (is_array($message)) {
foreach ($message as $k => $row) {
if ($row == 'It looks like this tweet may have been shared recently. Check out our guide to repeating posts in the FAQs') {
$message[$k] = __('Whoops, you try to send the same message multiple times to soon after each other. Try again later.', 'lionel_content');
}
}
}
// Return WP_Error
return new WP_Error(
$body->code,
__( is_array($message) ? implode( "\n", $message ) : $message, 'lionel_content' )
);
}
/**
* Returns the Buffer URL where the user can change the timezone for the
* given profile ID.
*
* @since 1.0.0
*
* @param string $profile_id Profile ID
* @return string Timezone Settings URL
*/
public function get_timezone_settings_url( $profile_id ) {
return 'https://buffer.com/app/profile/' . $profile_id . '/schedule';
}
/**
* Determines if the WordPress URL is a local, non-web accessible URL.
*
* @since 1.0.0
*
* @return bool Locally Hosted Site
*/
private function is_local_host() {
// Get URL of site and its information
$url = parse_url( get_bloginfo( 'url' ) );
// Iterate through local host addresses to check if they exist
// in part of the site's URL host
foreach ( $this->get_local_hosts() as $local_host ) {
if ( strpos( $url['host'], $local_host ) !== false ) {
return true;
}
}
// If here, we're not on a local host
return false;
}
/**
* Check to see if the website is hosted locally (development environment)
* See: https://www.sqa.org.uk/e-learning/WebTech01CD/page_12.htm
*
* @since 1.0.0
*/
private function get_local_hosts() {
$local_hosts = array(
'localhost',
'127.0.0.1',
'10.0.',
'192.168.',
'.dev',
'.local',
'.localhost',
'.test',
);
// Add 172.16.0.* to 172.16.31.*
for ( $i = 0; $i <= 31; $i++ ) {
$local_hosts[] = '172.16.' . $i . '.';
}
return $local_hosts;
}
public function updates_share($id) {
// Check access token
if ( ! $this->check_access_token_exists() ) {
return false;
}
// Send request
$result = $this->post_buffer( 'updates/' . $id . '/share.json');
// Bail if the result is an error
if ( is_wp_error( $result ) ) {
return $result;
}
// Return array of just the data we need to send to the Plugin
return array(
'message' => $result->message,
'success' => $result->success
);
}
}
Full code:
Previous8. Connect to Buffer (ok)NextChú ý: Khi chuyển trang từ một mạng xã hội xác thực để sử dụng được wp_get_current_user (ok)
Last updated