# 8. Connect to Buffer (ok)

![](https://2370029328-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWPtKFbhw0XehxVuoiZ%2F-MbtAKNaxq8UsTwPR3A7%2F-MbtBXGS1FvXPNjV7joc%2Fimage.png?alt=media\&token=d6f64845-c0e2-4f21-af21-0f02dbde164a)

wp-content/plugins/lionel-setup-content/admin/class-lionel\_content-admin.php

```
<?php
  class Lionel_Content_Admin
  {
    private $plugin_name;
    private $version;
    private $plugin_public_name;
    private $service;
    private $client_id;
    private $settings;
    private $buffer_service;
    public function __construct ($plugin_name, $version)
    {
      $this->plugin_name = $plugin_name;
      $this->version = $version;
      $this->plugin_public_name = 'Lionel Content';
      $this->service = 'Buffer';
      $this->load_dependencies();
    }
    public function enqueue_styles ()
    {
      if (LIONEL_CONTENT_ENABLE_DEBUG == true) :
        wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/lionel_content-admin.css', array(), time(), 'all');
      else :
        wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/lionel_content-admin.css', array(), $this->version, 'all');
      endif;
    }
    public function enqueue_scripts ()
    {
      if (LIONEL_CONTENT_ENABLE_DEBUG == true) :
        wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/lionel_content-admin.js', array('jquery'), time(), false);
        // set variables for script
        wp_localize_script($this->plugin_name, 'ajaxSettings', array('ajaxurl' => admin_url('admin-ajax.php')));
      else :
        wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/lionel_content-admin.js', array('jquery'), $this->version, false);
        // set variables for script
        wp_localize_script($this->plugin_name, 'ajaxSettings', array('ajaxurl' => admin_url('admin-ajax.php')));
      endif;
    }
    public function load_dependencies ()
    {
			require_once	plugin_dir_path(	dirname(	__FILE__	)	)
										.	'includes/class-lionel_content_buffer.php';
	    $this->buffer_service = new Lionel_Content_Buffer();
			 require_once plugin_dir_path(dirname(__FILE__))
                    . 'admin/class-lionel_content-settings.php';
      $this->buffer_service = new Lionel_Content_Buffer();
      $this->settings = new Lionel_Content_Settings($this->buffer_service);
    }
    public function lionel_content_admin_menu ()
    {
      if (!is_user_logged_in()) {
        return;
      }
      add_menu_page(
        __('Evergreen Content', 'evergreen_content_poster'),
'Evergreen Content',
        'edit_posts',
        'lionel_content_settings',
        array($this, 'lionel_content_settings_page'),
        'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDEzIiBoZWlnaHQ9IjUyNCIgdmlld0JveD0iMCAwIDQxMyA1MjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzk2LjU2NiAyNDYuODQ1QzQwNy4zNTkgMjcyLjA4OSA0MTIuNzU2IDI5OC41MyA0MTIuNzU2IDMyNi4xNjlDNDEyLjc1NiAzNTMuODA3IDQwNy4zNTkgMzgwLjI0OSAzOTYuNTY2IDQwNS40OTNDMzg2LjE0MiA0MjkuODc1IDM3MS40MjggNDUxLjQ2NyAzNTIuNDIyIDQ3MC4yNjlDMzQ4LjM5IDQ3NC4yNTggMzQ0LjIzMSA0NzguMDU2IDMzOS45NDUgNDgxLjY2M0wzNDAuNzIxIDQ3MS40MjJMMzQwLjg2IDQ2OS41ODZDMzQyLjczMyA0NjcuODY4IDM0NC41NzkgNDY2LjEwOSAzNDYuMzk4IDQ2NC4zMDlDMzY0LjYxOSA0NDYuMjgxIDM3OC43MjYgNDI1LjU4MiAzODguNzE4IDQwMi4yMUMzOTkuMDYyIDM3OC4wMTUgNDA0LjIzNCAzNTIuNjY4IDQwNC4yMzQgMzI2LjE2OUM0MDQuMjM0IDI5OS42NzEgMzk5LjA2MiAyNzQuMzI0IDM4OC43MTggMjUwLjEyOUMzODQuNjMxIDI0MC41NjggMzc5Ljg1NSAyMzEuNDU0IDM3NC4zOTEgMjIyLjc4OEwzNzMuNjM3IDIwNi42MDVDMzgyLjc3MyAyMTkuMDQ3IDM5MC40MTcgMjMyLjQ2IDM5Ni41NjYgMjQ2Ljg0NVpNNjEuMTE3OSA0NzAuMjY5QzQyLjExMzIgNDUxLjQ2NyAyNy4zOTkxIDQyOS44NzUgMTYuOTc1NSA0MDUuNDkzQzYuMTgyOSAzODAuMjQ5IDAuNzg2NjE3IDM1My44MDcgMC43ODY2MTcgMzI2LjE2OUMwLjc4NjYxOCAyOTguNTMgNi4xODI5IDI3Mi4wODkgMTYuOTc1NSAyNDYuODQ1QzIzLjI5MzcgMjMyLjA2NiAzMS4xODgyIDIxOC4zMTMgNDAuNjU5MiAyMDUuNTg0TDM5LjM0MTIgMjIyLjQ4N0MzMy43OTc0IDIzMS4yNDMgMjguOTU4MSAyNDAuNDU3IDI0LjgyMzMgMjUwLjEyOUMxNC40Nzk0IDI3NC4zMjMgOS4zMDc0NCAyOTkuNjcgOS4zMDc0NCAzMjYuMTY5QzkuMzA3NDQgMzUyLjY2OCAxNC40Nzk0IDM3OC4wMTUgMjQuODIzMyA0MDIuMjFDMzQuODE1MiA0MjUuNTgyIDQ4LjkyMTggNDQ2LjI4MiA2Ny4xNDMxIDQ2NC4zMDlDNjguOTYxMSA0NjYuMTA4IDcwLjgwNiA0NjcuODY1IDcyLjY3NzcgNDY5LjU4M0w3My41OTI1IDQ4MS42NjFDNjkuMzA3NCA0NzguMDU1IDY1LjE0OTIgNDc0LjI1NyA2MS4xMTc5IDQ3MC4yNjlaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMTE4LjE3NSA1MTYuMDY5TDg3LjM5NCAyNDEuOTlIMzI0Ljc2NkwyOTguNzIgNTE2LjA2OUgxMTguMTc1WiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxNSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNOTQuMjc0MyA0MjUuMzEzTDc5LjIxNzggMjk2LjI0M0gzMzMuNjczTDMyMC42MjQgNDI1LjMxM0g5NC4yNzQzWiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxMy42NDEzIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik03My43NzkgMTUxLjE2OEM3MC44MTIxIDE1MS4xNjggNjguMjIxNyAxNTMuMTc3IDY3LjQ4MzUgMTU2LjA1TDU0LjQ2MDYgMjA2Ljc0QzUzLjk2MDYgMjA4LjY4NiA1NC4zODg2IDIxMC43NTQgNTUuNjE5OCAyMTIuMzQxQzU2Ljg1MSAyMTMuOTI5IDU4Ljc0NzEgMjE0Ljg1OCA2MC43NTYxIDIxNC44NThIMzQ5LjYyOEMzNTEuNjc0IDIxNC44NTggMzUzLjYwMSAyMTMuODk0IDM1NC44MjggMjEyLjI1N0MzNTYuMDU2IDIxMC42MiAzNTYuNDQxIDIwOC41IDM1NS44NjcgMjA2LjUzNkwzNDEuMDY5IDE1NS44NDZDMzQwLjI1OSAxNTMuMDc0IDMzNy43MTcgMTUxLjE2OCAzMzQuODI5IDE1MS4xNjhINzMuNzc5WiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxMyIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNMjA2LjcxMyA0MDcuNzg0QzIzMy4wNTQgNDA3Ljc4NCAyNTQuNDA4IDM4Ni41MjIgMjU0LjQwOCAzNjAuMjkzQzI1NC40MDggMzM0LjA2NSAyMzMuMDU0IDMxMi44MDMgMjA2LjcxMyAzMTIuODAzQzE4MC4zNzEgMzEyLjgwMyAxNTkuMDE3IDMzNC4wNjUgMTU5LjAxNyAzNjAuMjkzQzE1OS4wMTcgMzg2LjUyMiAxODAuMzcxIDQwNy43ODQgMjA2LjcxMyA0MDcuNzg0WiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxMCIvPgo8cGF0aCBkPSJNMTgzLjkyIDM4MC4zNDdDMTg5LjcyNSAzNjYuMjQzIDIwMC4wOTIgMzUzLjcxIDIxMy44OTQgMzQ0LjQ3QzIxMy45NyAzNDQuNDE5IDIxNC4wMDkgMzQ0LjQ4MSAyMTMuOTM5IDM0NC41NDJDMjAwLjcyOSAzNTYuMjc4IDE5MS43NzIgMzcxLjA4NiAxODguMDg0IDM4Ni43N0MxODcuOTYgMzg3LjI5NCAxODcuODQzIDM4Ny44MTcgMTg3LjczMSAzODguMzQzQzE4Ny42ODQgMzg4LjU2MiAxODcuNjQgMzg4Ljc4MSAxODcuNTk1IDM4OC45OTlMMTg3LjU5IDM4OS4wMjVDMTg3LjUwMiAzODkuNDU3IDE4Ny40MjEgMzg5Ljg5IDE4Ny4zNDEgMzkwLjMyMkMxODcuMjkxIDM5MC41OTYgMTg3LjI0IDM5MC44NzEgMTg3LjE5NSAzOTEuMTQ0QzE4Ny4xMzEgMzkxLjUyMiAxODcuMDcxIDM5MS45MDEgMTg3LjAxMiAzOTIuMjc4TDE4Ny4wMDIgMzkyLjM0QzE4Ni45NTYgMzkyLjYzNCAxODYuOTEgMzkyLjkyNiAxODYuODY5IDM5My4yMkMxODYuODI2IDM5My41MjYgMTg2Ljc4OSAzOTMuODMyIDE4Ni43NDkgMzk0LjEzOUMxODYuNjI2IDM5NS4wOTggMTg2LjUxOSAzOTYuMDYgMTg2LjQzNiAzOTcuMDI0TDE4Ni40MzUgMzk3LjA0QzE4Ni4yMzkgMzk5LjMxNCAxODYuMTUyIDQwMS41OTMgMTg2LjE4NCA0MDMuODc4QzE4Ni4yMTMgNDA1LjkyMiAxODcuODA1IDQwNy41NTQgMTg5LjczOSA0MDcuNTI0QzE5MC4xMzUgNDA3LjUxOCAxOTAuNTE0IDQwNy40NDQgMTkwLjg2OCA0MDcuMzExQzE5Mi4yNDIgNDA2Ljc5MyAxOTMuMjE1IDQwNS4zOTUgMTkzLjE5MyA0MDMuNzY3QzE5My4xMyAzOTkuMzQ1IDE5My41NTggMzk0LjkyNiAxOTQuNDM4IDM5MC41NjZDMjAwLjE2MyAzOTIuODk0IDIwNi43OTQgMzkyLjUzIDIxMi4zNTYgMzkwLjQzMkMyMjMuNzkzIDM4Ni4xMTkgMjMwLjg1MSAzNzMuMTA2IDIyNy4xNyAzNjEuMTYyTDIyNy4xNzYgMzYxLjE3N0MyMjQuMjM2IDM1Mi40NyAyMjUuMDM4IDM0My4zMTcgMjI4LjU5NiAzMzUuNzI5QzIyOS40OTQgMzMzLjgxNiAyMjcuOTA3IDMzMy40MzMgMjI3LjA0OSAzMzMuMjg4QzIyMC41NzYgMzMyLjE5MSAyMTMuMTU3IDMzMi44ODUgMjA1Ljc4OCAzMzUuNjY1QzE4OS4xOTEgMzQxLjkyNiAxNzkuOTk0IDM1NC4yODMgMTgxLjIwNyAzNjkuMzAzQzE4MS41NDkgMzczLjY4NyAxODIuNTA5IDM3Ny4zMzkgMTgzLjkyIDM4MC4zNDdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzQ5LjIxIDcuOTYzMzhMMjk0LjUyNiAxMjguNTQzTDM0MS42NjcgMTI4LjU0M0wzOTQuMjUzIDcuOTYzMzhMMzQ5LjIxIDcuOTYzMzhaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjE1IiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPgo='
      );
    }
    public function lionel_content_settings_page()
    {
      $this->settings->load_page();
    }
    public function save_settings()
    {
      if ($_SERVER['REQUEST_METHOD'] != 'POST') {
        wp_send_json_error();
      }
      $updated_fields = [];
			$fields_array	=	explode(	'&',	$_POST['fields']	);
			//	array (
			//		0 => 'eg_numberofdays=3',
			//    1 => 'saved_numberofdays=1',
			//  )
			 foreach ($fields_array as $value) {
        list($field_key, $field_val) = explode('=', $value); // eg_numberofdays=4
        if (stripos($field_key, 'saved_') === true) continue;
				 $updated_fields[$field_key] = urldecode($field_val);
				}
	    // Save  settings
	    $updated_fields['utm_tags'] = isset($updated_fields['utm_tags']) ? $updated_fields['utm_tags'] : 'N';
      if (!$this->buffer_service->save_settings($updated_fields)) wp_send_json_error();
	    wp_send_json_success(__('Buffer Settings have been saved successfully!', 'evergreen_content_poster'));
    }
  }
```

wp-content/plugins/lionel-setup-content/admin/class-lionel\_content-settings.php

```
<?php
  class Lionel_Content_Settings
  {
    private $plugin_name;
    private $version;
    private $buffer;
    public function __construct (Lionel_Content_Buffer $buffer) {
      $this->buffer = $buffer;
      $this->load_settings ();
    }
    public function load_settings () {
      $this->buffer_token = $this->buffer->get_token ();
    }
    public function load_page () {
      $token = $this->buffer_token;
?>
<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>
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
<?php
    }
  }
```

wp-content/plugins/lionel-setup-content/includes/class-lionel\_content.php

```
<?php
  class Lionel_Content
  {
    protected $loader;
    protected $plugin_name;
    protected $version;
    private $plugin_admin;
    private $buffer_service;
    public function __construct ()
    {
      if ( defined( 'LIONEL_CONTENT_PLUGIN_VERSION' ) ) {
        $this->version = LIONEL_CONTENT_PLUGIN_VERSION;
      } else {
        $this->version = '1.0.0';
      }
      $this->plugin_name = 'lionel_content';
      $this->load_dependencies ();
      $this->define_admin_hooks();
    }
    private function load_dependencies ()
    {
      require_once plugin_dir_path (dirname (__FILE__))
        . 'includes/class-lionel_content-loader.php';
      $this->loader = new Lionel_Content_Loader();
      require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-lionel_content_buffer.php';
      $this->buffer_service = new Lionel_Content_Buffer();
      /**
       * Part 3
       */
      require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-lionel_content-admin.php';
    }
    public function get_loader() {
      return $this->loader;
    }
    public function get_plugin_name() {
      return $this->plugin_name;
    }
    public function get_version() {
      return $this->version;
    }
    public static $instance;
    public static function get_instance() {
      if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) {
        self::$instance = new self;
      }
      return self::$instance;
    }
    public function install() {
      $this->add_lionel_content_defaults();
    }
    public function add_lionel_content_defaults ()
    {
      global $wpdb;
      $options = get_option ('lionel_options');
      if ( !isset($options['lionel_installed']) || $options['lionel_installed'] != 1 || !is_array($options) )
      {
        $opt = array(
          'lionel_version' => LIONEL_CONTENT_PLUGIN_VERSION,
          'lionel_db_version' => LIONEL_CONTENT_DB_VERSION,
          'lionel_installed' => 1,
          'premium' => 0
        );
        if ( is_multisite() )
        {
          update_site_option( 'lionel_options', $opt );
        } else {
          $this->lionel_content_update_option( 'lionel_options', $opt );
        }
      }
      $this->lionel_content_db_install();
    }
    public function lionel_content_update_option( $option_name, $new_value ) {
      if ( get_option( $option_name ) !== false ) {
        // The option already exists, so we just update it.
        update_option( $option_name, $new_value );
      } else {
        // The option hasn't been added yet. We'll add it with $autoload set to 'no'.
        add_option( $option_name, $new_value, $deprecated=null, $autoload='no' );
      }
    }
    public function lionel_content_db_install ()
    {
      global $wpdb;
      $charset_collate = $wpdb->get_charset_collate ();
      $this->lionel_content_set_wpdb_tables ();
      require_once (ABSPATH . 'wp-admin/includes/upgrade.php');
      $sql = "CREATE TABLE IF NOT EXISTS $wpdb->lionel_content_logs (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `post_id` int(11) NOT NULL,
        `action` enum('publish','update','repost','bulk_publish', 'share', 'add_queue') DEFAULT NULL,
        `request_sent` datetime NOT NULL,
        `profile_id` varchar(191) NOT NULL,
        `profile_name` varchar(191) NOT NULL DEFAULT '',
        `result` enum('success','test','pending','warning','error') NOT NULL DEFAULT 'success',
        `result_message` text,
        `status_text` text,
        `status_image` text,
        `status_link` text,
        `status_created_at` datetime DEFAULT NULL,
        `status_due_at` datetime DEFAULT NULL,
        `lionel_posting_schedule` text,
        PRIMARY KEY (`id`),
        KEY `post_id` (`post_id`),
        KEY `action` (`action`),
        KEY `result` (`result`),
        KEY `profile_id` (`profile_id`)
      ) {$charset_collate};";
      dbDelta ($sql);
      $sqlCate = "CREATE TABLE IF NOT EXISTS $wpdb->lionel_categories (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `name` varchar(191) NOT NULL DEFAULT '',
        `description` text,
        `random_availability` int(1) NOT NULL DEFAULT 1,
        `status` int(1) NOT NULL DEFAULT 1,
        `is_default` int(1) DEFAULT NULL,
        `created_at` datetime DEFAULT NULL,
        `updated_at` datetime DEFAULT NULL,
        PRIMARY KEY (`id`)
      ) {$charset_collate};";
      dbDelta ($sqlCate);
      // Check categories
      $categories = $wpdb->get_results("SELECT * FROM {$wpdb->lionel_categories}");
      if(empty((array)$categories)) {
        // add default Category
				$dateNow	=	date(	'Y-m-d H:i:s'	);
				 $insertSql = "INSERT INTO ({$wpdb->lionel_categories})(name, description, random_availability, status, is_default, created_at, updated_at) VALUES ('Your evergreen content', 'Use this category to promote your own content - share any blog posts or pages you publish.', 1, 1, 1, '$dateNow', null), ('Promotional', 'Use this category to promote your services/products. Make sure to include Calls To Actions (CTAs) like \"Book a call with us\" or \"start a trial account\".', 1, 1, 0, '$dateNow', null), ('Quotes, Questions, and Fun', 'Use this category to generate engagement on your socials. Share inspirational or fun quotes, from your niche or create open questions for your audience.', 1, 1, 0, '$dateNow', null)";
        dbDelta($insertSql);
      }
    }
    public function lionel_content_set_wpdb_tables()
    {
      global $wpdb;
      $wpdb->lionel_content_logs = $wpdb->prefix . 'lionel_content_logs';
      $wpdb->lionel_categories = $wpdb->prefix . 'lionel_categories';
    }
    public function run ()
    {
      $this->loader->run ();
      if ( isset($_REQUEST['ba_response']) && !empty($_REQUEST['ba_response']) ) {
        $token = sanitize_text_field ( $_REQUEST['ba_response'] );
        $this->buffer_service->save_token($token);
        wp_redirect('/wp-admin/admin.php?page=lionel_content_settings#AccountSettings');
      }
      if ( isset($_REQUEST['action']) && 'ba_remove' == strtolower( $_REQUEST['action'] ) ) {
        $this->buffer_service->deauthorize();
        wp_redirect('/wp-admin/admin.php?page=lionel_content_settings&removed_auth=Y');
      }
    }
    /**
     * Part 4
     */
    private function define_admin_hooks ()
    {
      $plugin_admin = new Lionel_Content_Admin($this->get_plugin_name (),
        $this->get_version ());
      $this->plugin_admin = $plugin_admin;
      $this->loader->add_action( 'admin_menu', $plugin_admin, 'lionel_content_admin_menu' );
      $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
      $this->loader->add_action('admin_enqueue_scripts', $plugin_admin,
        'enqueue_scripts');
      $this->loader->add_action( 'wp_ajax_nopriv_save_settings', $plugin_admin, 'save_settings' );
      $this->loader->add_action ( 'wp_ajax_save_settings', $plugin_admin, 'save_settings' );
    }
  }
```

wp-content/plugins/lionel-setup-content/includes/class-lionel\_content-activator.php

```
<?php
  class Lionel_Content_Activator
  {
    public static function lionel_activate( $network_wide ) {
      if ( ! current_user_can( 'activate_plugins' ) )
        return;
      // Initialise Plugin
      $lionel = Lionel_Content::get_instance();
      // Check if we are on a multisite install, activating network wide, or a single install
      if ( ! is_multisite() || ! $network_wide ) {
        // Single Site activation
        // $ecp->get_class( 'install' )->install();
        $lionel->install ();
      } else      // Multisite network wide activation
        $sites = get_sites( array('number' => 0) );
        foreach ( $sites as $site ) {
          switch_to_blog( $site->blog_id );
          $lionel = (new Lionel_Content)->install();
          restore_current_blog();
        }
      }
    public static function register_settings ()
    {
      $opts = array(
        'lionel_version' => LIONEL_CONTENT_PLUGIN_VERSION,
        'lionel_db_version' => LIONEL_CONTENT_DB_VERSION,
        'premium' => 0
      );
      add_option (LIONEL_CONTENT_KEY_PREFIX . '_options', $opts);
      add_option( LIONEL_CONTENT_KEY_PREFIX . '_general_settings', [] );
    }
  }
function activate_lionel_content ( $network_wide ) {
  Lionel_Content_Activator::lionel_activate($network_wide);
  add_action('wpmu_new_blog', 'ecp_activate_new_site');
  add_action('activate_blog', 'ecp_activate_new_site');
  // activate plugin setting options
  Lionel_Content_Activator::register_settings();
  // Don't do redirects when multiple plugins are bulk activated
  if (
    (isset($_REQUEST['action']) && 'activate-selected' === sanitize_text_field($_REQUEST['action'])) &&
    (isset($_POST['checked']) && count($_POST['checked']) > 1)
  ) {
    return;
  }
  $today_now = date('Y-m-d H:i:s');
  $date_last_active = get_option('lionel_date_last_active');
  if(isset($date_last_active) && !is_null($date_last_active)) {
    // update option ecp_date_last_active with current time
    update_option('lionel_date_last_active', $today_now);
  } else {
    // add new option
    add_option('lionel_date_last_active', $today_now);
  }
  // needed as validator when redirecting user after activating the plugin
  add_option('lionel_plugin_activation_redirect', wp_get_current_user()->ID);
}
function lionel_plugin_settings_redirect () {
  // Make sure it's the correct user
  if (intval(get_option('lionel_plugin_activation_redirect', false)) === wp_get_current_user()->ID && wp_get_current_user()->ID > 0) {
    // Make sure we don't redirect again after this one
    delete_option('lionel_plugin_activation_redirect');
    wp_safe_redirect(admin_url('/admin.php?page=lionel_content_settings#AccountSettings'));
  }
}
```

wp-content/plugins/lionel-setup-content/includes/class-lionel\_content-loader.php

```
<?php
  class Lionel_Content_Loader
  {
    protected $actions;
    protected $filters;
    public function __construct() {
      $this->actions = array();
      $this->filters = array();
    }
    public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
      $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
    }
    public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
      $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args );
    }
    private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
      $hooks[] = array(
        'hook'          => $hook,
        'component'     => $component,
        'callback'      => $callback,
        'priority'      => $priority,
        'accepted_args' => $accepted_args
      );
      return $hooks;
    }
    public function run() {
      foreach ( $this->filters as $hook ) {
        add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
      }
      foreach ( $this->actions as $hook ) {
        add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
      }
    }
  }
```

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
    );

  }
}
```

wp-content/plugins/lionel-setup-content/lionel\_setup\_content.php

```
<?php
/**
 *
 * @link              https://usergrowth.io/
 * @since             1.0.0
 * @package           Evergreen_Content_Poster
 *
 * @wordpress-plugin
 * Plugin Name:       Lionel Setup Content
 * Plugin URI:        https://usergrowth.io/resources/tools/evergreen-content-poster/?utm_source=plugin%20description&utm_medium=software&utm_campaign=Evergreen%20Content%20Poster
 * Description:       Automatically share your WordPress evergreen content on Twitter, Facebook, Instagram, LinkedIn or Pinterest. Get more visitors to your website and keep your content alive. For questions, comments, or feature requests, <a href="https://usergrowth.io/contact/?utm_source=plugin%20description&utm_medium=software&utm_campaign=Evergreen%20Content%20Poster">contact</a> us!
 * Version:           1.1.4
 * Author:            User Growth
 * Author URI:        https://usergrowth.io/?utm_source=plugin%20description&utm_medium=software&utm_campaign=Evergreen%20Content%20Poster
 * License:           GPL-2.0+
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain:       lionel
 * Domain Path:       /languages/
 */
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
  die;
}
  if ( ! defined ('ABSPATH')) {
    exit;
  }
if ( !function_exists('wp_get_current_user') ) {
  include(ABSPATH . "wp-includes/pluggable.php");
}
  if ( ! defined ('LIONEL_CONTENT_PATH')) {
    define ('LIONEL_CONTENT_PATH',
      untrailingslashit (plugins_url ('', __FILE__)));
    //https://reset.com/wp-content/plugins/lionel-setup-content
  }
  if ( !defined('LIONEL_CONTENT_PLUGIN_DIR') )
    define('LIONEL_CONTENT_PLUGIN_DIR', untrailingslashit(dirname( __FILE__ )));
    // /var/www/reset/wp-content/plugins/lionel-setup-content
  if ( !defined('LIONEL_CONTENT_PLUGIN_SLUG') )
    define ('LIONEL_CONTENT_PLUGIN_SLUG', basename (dirname (__FILE__)));
//  lionel-setup-content
  
  if ( !defined('LIONEL_CONTENT_DB_VERSION') )
    define('LIONEL_CONTENT_DB_VERSION', '0.0.4');
  
  if ( !defined('LIONEL_CONTENT_PLUGIN_VERSION') )
    define('LIONEL_CONTENT_PLUGIN_VERSION', '1.1.4');
  
  if ( !defined('LIONEL_CONTENT_ENABLE_DEBUG') )
    define('LIONEL_CONTENT_ENABLE_DEBUG', TRUE);
  
  if ( !defined('LIONEL_CONTENT_KEY_PREFIX') )
    define('LIONEL_CONTENT_KEY_PREFIX', 'lionel');
  if( LIONEL_CONTENT_ENABLE_DEBUG ) {
    error_reporting (E_ALL);
    ini_set('display_errors', 1);
  }
  /**
   * Part 1
   */
  require_once plugin_dir_path (__FILE__)
    . 'includes/class-lionel_content-activator.php';
  register_activation_hook (__FILE__, 'activate_lionel_content');
  /**
   * Part 2
   */
require plugin_dir_path ( __FILE__ ) . 'includes/class-lionel_content.php';
/**
 * Part 5
 */
add_action('admin_init', 'lionel_plugin_settings_redirect');
  function run_lionel_content() {
    $plugin = new Lionel_Content();
    $plugin->run();
  }
  run_lionel_content();
```

Full code

{% file src="<https://2370029328-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LWPtKFbhw0XehxVuoiZ%2F-MbtAKNaxq8UsTwPR3A7%2F-MbtBcA9iE3t7VzXw3d-%2Flionel-setup-content.zip?alt=media&token=2b2bdb32-9061-45e4-b26c-fb10401d7004>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://learnphp.gitbook.io/learnphp/wordpress/8.-connect-to-buffer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
