commit 3a3f1810f67f6838406c4fdd1316e21a72ce8aad Author: Django Doucet Date: Thu Dec 26 16:11:20 2019 -0500 Initial commit diff --git a/fediembedi-client.php b/fediembedi-client.php new file mode 100644 index 0000000..440edfc --- /dev/null +++ b/fediembedi-client.php @@ -0,0 +1,234 @@ +instance_url = $instance_url; + $this->access_token = $access_token; + } + + public function setStatic($param){ + self::$acct_id = $param; + } + + public function getStatic(){ + return self::$acct_id; + } + + public function register_app($redirect_uri) { + + $response = $this->_post('/api/v1/apps', array( + 'client_name' => 'FediEmbedi for WordPress', + 'redirect_uris' => $redirect_uri, + 'scopes' => 'read', + 'website' => get_site_url() + )); + + if (!isset($response->client_id)){ + return "ERROR"; + } + + $this->app = $response; + + $params = http_build_query(array( + 'response_type' => 'code', + 'redirect_uri' => $redirect_uri, + 'scope' => 'read', + 'client_id' =>$this->app->client_id + )); + + return $this->instance_url.'/oauth/authorize?'.$params; + } + + public function verify_credentials($access_token){ + + $headers = array( + 'Authorization'=>'Bearer '.$access_token + ); + + $response = $this->_get('/api/v1/accounts/verify_credentials', null, $headers); + + if(property_exists($response, 'id')){ + $this->setStatic($response->id); + } + + return $response; + } + + public function get_bearer_token($client_id, $client_secret, $code, $redirect_uri) { + + $response = $this->_post('/oauth/token',array( + 'grant_type' => 'authorization_code', + 'redirect_uri' => $redirect_uri, + 'client_id' => $client_id, + 'client_secret' => $client_secret, + 'code' => $code + )); + + return $response; + } + + public function get_client_id() { + return $this->app->client_id; + } + + public function get_client_secret() { + return $this->app->client_secret; + } + + public function getStatus($media = 'false', $pinned = 'false', $replies = 'false', $max_id = null, $since_id = null, $min_id = null, $limit = 10, $reblogs = 'false') { + + $headers = array( + 'Authorization'=> 'Bearer '.$this->access_token + ); + + $account_id = self::$acct_id; + + $query = http_build_query(array( + 'only_media' => $media, + 'pinned' => $pinned, + 'exclude_replies' => $replies, + 'max_id' => $max_id, + 'since_id' => $since_id, + 'min_id' => $min_id, + 'limit' => $limit, + 'exclude_reblogs' => $reblogs + )); + + $response = $this->_get("/api/v1/accounts/{$account_id}/statuses?{$query}", null, $headers); + + return $response; + } + + public function getAccount() { + + $headers = array( + 'Authorization'=> 'Bearer '.$this->access_token + ); + + $account_id = self::$acct_id; + + $response = $this->_get("/api/v1/accounts/{$account_id}", null, $headers); + + return $response; + } + + public function getInstance() { + + $headers = array( + 'Authorization'=> 'Bearer '.$this->access_token + ); + + $account_id = self::$acct_id; + + $response = $this->_get("/api/v1/instance", null, $headers); + + return $response; + } + + public function postStatus($status, $mode, $media = '', $spoiler_text = '') { + + $headers = array( + 'Authorization'=> 'Bearer '.$this->access_token + ); + + $response = $this->_post('/api/v1/statuses', array( + 'status' => $status, + 'visibility' => $mode, + 'spoiler_text' => $spoiler_text, + 'media_ids[]' => $media + ), $headers); + + return $response; + } + + public function create_attachment($media_path) { + + $filename =basename($media_path); + $mime_type = mime_content_type($media_path); + + $boundary ='hlx'.time(); + + $headers = array ( + 'Authorization'=> 'Bearer '.$this->access_token, + 'Content-Type' => 'multipart/form-data; boundary='. $boundary, + ); + + $nl = "\r\n"; + + $data = '--'.$boundary.$nl; + $data .= 'Content-Disposition: form-data; name="file"; filename="'.$filename.'"'.$nl; + $data .= 'Content-Type: '. $mime_type .$nl.$nl; + $data .= file_get_contents($media_path) .$nl; + $data .= '--'.$boundary.'--'; + + $response = $this->_post('/api/v1/media', $data, $headers); + + return $response; + } + + private function _post($url, $data = array(), $headers = array()) { + return $this->post($this->instance_url.$url, $data, $headers); + } + + public function _get($url, $data = array(), $headers = array()) { + return $this->get($this->instance_url.$url, $data, $headers); + } + + private function post($url, $data = array(), $headers = array()) { + $args = array( + 'headers' => $headers, + 'body'=> $data, + 'redirection' => 5 + ); + + $response = wp_remote_post( $this->getValidURL($url), $args ); + if ( is_wp_error( $response ) ) { + $error_message = $response->get_error_message(); + + } else { + $responseBody = wp_remote_retrieve_body($response); + return json_decode($responseBody); + } + + return $response; + } + + public function get($url, $data = array(), $headers = array()) { + $args = array( + 'headers' => $headers, + 'redirection' => 5 + ); + $response = wp_remote_get( $this->getValidURL($url), $args ); + if ( is_wp_error( $response ) ) { + $error_message = $response->get_error_message(); + + } else { + $responseBody = wp_remote_retrieve_body($response); + return json_decode($responseBody); + } + + return $response; + } + + public function dump($value){ + echo '
';
+		print_r($value);
+		echo '
'; + } + + private function getValidURL($url){ + if ( $ret = parse_url($url) ) { + if ( !isset($ret["scheme"]) ){ + $url = "http://{$url}"; + } + } + return $url; + + } +} diff --git a/fediembedi-widget-template.php b/fediembedi-widget-template.php new file mode 100644 index 0000000..abd419d --- /dev/null +++ b/fediembedi-widget-template.php @@ -0,0 +1,132 @@ +verify_credentials($access_token); +//$profile = $client->getAccount(); + +//widget options +$show_header = (!empty($instance['show_header'])) ? $instance['show_header'] : ''; +$only_media = (!empty($instance['only_media'])) ? $instance['only_media'] : ''; +$pinned = (!empty($instance['pinned'])) ? $instance['pinned'] : ''; +$exclude_replies = (!empty($instance['exclude_replies'])) ? $instance['exclude_replies'] : ''; +$exclude_reblogs = (!empty($instance['exclude_reblogs'])) ? $instance['exclude_reblogs'] : ''; +$query = http_build_query(array( + 'only_media' => $only_media, + 'pinned' => $pinned, + 'exclude_replies' => $exclude_replies, + 'limit' => 5, + 'exclude_reblogs' => $exclude_reblogs +)); +$status = $client->getStatus($only_media, $pinned, $exclude_replies, null, null, null, 10, $exclude_reblogs); + +$instance_info = $client->getInstance(); +if(WP_DEBUG_DISPLAY === true): echo '
Debug
'; var_dump($instance_info); echo '
'; endif; +?> +
+
+ + + + +
+
+
+
+ reblog)): ?> +
+
'; + endif; ?> + +
+ +
reblog)): + $statut = $statut->reblog; + endif; + if(empty($statut->spoiler_text)): + echo $statut->content; + if(!is_null($statut->card)): ?> + +
+
+ card->title); ?> +

card->description)); ?>

+ card->url; ?> +
+
+ ' . $statut->spoiler_text . ''. $statut->content . ''; + endif; + if(!empty($statut->media_attachments)): + foreach ($statut->media_attachments as $attachment) { + if (!empty($attachment->preview_url) && $attachment->type === 'image'): + echo "" . $attachment->description . ""; + elseif($attachment->type === 'video'): + echo "
+
+
+
+
+ Debug
'; var_dump($status); echo '
'; endif; ?> +
+
diff --git a/fediembedi-widget.php b/fediembedi-widget.php new file mode 100644 index 0000000..7f98177 --- /dev/null +++ b/fediembedi-widget.php @@ -0,0 +1,137 @@ + 'widget_fediembedi', + 'description' => __( 'Display a profile timeline', 'fediembedi' ), + 'customize_selective_refresh' => true, + ); + parent::__construct( 'fediembedi', _x( 'FediEmbedi', 'fediembedi' ), $widget_ops ); + } + + /** + * Outputs the content for the current Search widget instance. + * + * @since 2.8.0 + * + * @param array $args Display arguments including 'before_title', 'after_title', + * 'before_widget', and 'after_widget'. + * @param array $instance Settings for the current Search widget instance. + */ + public function widget( $args, $instance ) { + include(plugin_dir_path(__FILE__) . 'fediembedi-widget-template.php' );//fediembedi_widget_template + } + + /** + * Outputs the settings form for the Search widget. + * + * @since 2.8.0 + * + * @param array $instance Current settings. + */ + public function form( $instance ) { + $instance = wp_parse_args( (array) $instance, array( 'title' => '') ); + //Radio inputs : https://wordpress.stackexchange.com/a/276659/87622 + $show_header = (!empty( $instance['show_header'])) ? $instance['show_header'] : NULL; + $only_media = (!empty( $instance['only_media'])) ? $instance['only_media'] : NULL; + $pinned = (!empty($instance['pinned'])) ? $instance['pinned'] : NULL; + $exclude_replies = (!empty($instance['exclude_replies'])) ? $instance['exclude_replies'] : NULL; + $exclude_reblogs = (!empty($instance['exclude_reblogs'])) ? $instance['exclude_reblogs'] : NULL; + $remote_instance = get_option('fediembedi-instance'); + $client = new \Client($remote_instance); + $instance_info = $client->getInstance(); + + $pixelfed = ''; + if (strpos($instance_info->version, 'Pixelfed') !== false) { + $pixelfed = true; + } + ?> +

+ +

+

+ +
+ +
+ +
+ +
+ +

+ '' ) ); + $instance['title'] = sanitize_text_field( $new_instance['title'] ); + $instance['show_header'] = $new_instance['show_header']; + $instance['only_media'] = $new_instance['only_media']; + $instance['pinned'] = $new_instance['pinned']; + $instance['exclude_replies'] = $new_instance['exclude_replies']; + $instance['exclude_reblogs'] = $new_instance['exclude_reblogs']; + return $instance; + } + +} diff --git a/fediembedi.php b/fediembedi.php new file mode 100644 index 0000000..1d180e6 --- /dev/null +++ b/fediembedi.php @@ -0,0 +1,275 @@ +get_bearer_token($client_id, $client_secret, $code, get_admin_url()); + $instance_info = $client->getInstance(); + + if (isset($token->error)) { + //print_r($token); + //TODO: Propper error message + update_option( + 'fediembedi-notice', + serialize( + array( + 'message' => 'FediEmbedi : ' . __("Can't log you in.", 'fediembedi') . + '

' . __('Instance message', 'fediembedi') . ' : ' . $token->error_description . '

', + 'class' => 'error', + ) + ) + ); + unset($token); + update_option('fediembedi-token', ''); + } else { + update_option('fediembedi-client-id', ''); + update_option('fediembedi-client-secret', ''); + update_option('fediembedi-token', $token->access_token); + update_option('fediembedi-instance-info', $instance_info); + + } + $redirect_url = get_admin_url() . 'options-general.php?page=fediembedi'; + } else { + //Probably hack or bad refresh, redirect to homepage + $redirect_url = home_url(); + } + + wp_redirect($redirect_url); + exit; + } + + $token = get_option('fediembedi-token'); + // if (empty($token)) { + // update_option( + // 'fediembedi-notice', + // serialize( + // array( + // 'message' => 'FediEmbedi : ' . __('Please login to your account!', 'fediembedi') . ' ' . __('Go to FediEmbedi configuration', 'fediembedi') . '', + // 'class' => 'error', + // ) + // ) + // ); + // } + + } + + /* + * Widget + */ + public function fediembedi_widget() { + include(plugin_dir_path(__FILE__) . 'fediembedi-widget.php' );// + register_widget( 'WP_Widget_fediembedi' ); + } + + public function enqueue_styles($hook) + { + if( is_active_widget( false, false, 'fediembedi') ) { + $instance = get_option('fediembedi-instance'); + $client = new \Client($instance); + $instance_info = $client->getInstance(); + if (strpos($instance_info->version, 'Pixelfed') === false) { + wp_enqueue_style( 'fediembedi', plugin_dir_url( __FILE__ ) . 'mastodon-light.css', array(), filemtime(plugin_dir_path( __FILE__ ) . 'mastodon-light.css') ); + } else { + //https://css-tricks.com/lozad-js-performant-lazy-loading-images/ lazyloading for background images + wp_enqueue_style( 'fediembedi', plugin_dir_url( __FILE__ ) . 'pixelfed-light.css', array(), filemtime(plugin_dir_path( __FILE__ ) . 'pixelfed-light.css') ); + } + } + } + + /** + * Configuration_page + * + * Add the configuration page menu + * + * @return void + */ + public function configuration_page() + { + add_options_page( + 'FediEmbedi', + 'FediEmbedi', + 'manage_options', + 'fediembedi', + array($this, 'show_configuration_page') + ); + } + + /** + * Show_configuration_page + * + * Content of the configuration page + * + * @throws Exception The exception. + * @return void + */ + public function show_configuration_page() + { + + wp_enqueue_style('fediembedi-configuration', plugin_dir_url(__FILE__) . 'style.css'); + + if (isset($_GET['disconnect'])) { + update_option('fediembedi-token', ''); + } + + $token = get_option('fediembedi-token'); + + if (isset($_POST['save'])) { + + $is_valid_nonce = wp_verify_nonce($_POST['_wpnonce'], 'fediembedi-configuration'); + + if ($is_valid_nonce) { + $instance = esc_url($_POST['instance']); + + $client = new \Client($instance); + $redirect_url = get_admin_url(); + $auth_url = $client->register_app($redirect_url); + + if ($auth_url == "ERROR") { + //var_dump('$auth_url = ERROR'); //die; + update_option( + 'fediembedi-notice', + serialize( + array( + 'message' => 'FediEmbedi : ' . __('The given instance url belongs to an unrecognized service!', 'fediembedi'), + 'class' => 'error', + ) + ) + ); + + } else { + //var_dump($auth_url); //die; + if (empty($instance)) { + //var_dump($instance); //die; + update_option( + 'fediembedi-notice', + serialize( + array( + 'message' => 'FediEmbedi : ' . __('Please set your instance before you connect !', 'fediembedi'), + 'class' => 'error', + ) + ) + ); + } else { + update_option('fediembedi-client-id', $client->get_client_id()); + update_option('fediembedi-client-secret', $client->get_client_secret()); + update_option('fediembedi-instance', $instance); + + $account = $client->verify_credentials($token); + + if (is_null($account) || isset($account->error)) { + echo ''; + echo __('Redirect to ', 'fediembedi') . $instance; + exit; + } + + //Inform user that save was successfull + update_option( + 'fediembedi-notice', + serialize( + array( + 'message' => 'FediEmbedi : ' . __('Configuration successfully saved!', 'fediembedi'), + 'class' => 'success', + ) + ) + ); + + } + } + + $this->admin_notices(); + } + } + + $instance = get_option('fediembedi-instance'); + + if (!empty($token)) { + $client = new \Client($instance); + $account = $client->verify_credentials($token); + } + + include 'form.tpl.php'; + } + + /** + * Admin_notices + * Show the notice (error or info) + * + * @return void + */ + public function admin_notices() + { + + $notice = unserialize(get_option('fediembedi-notice')); + + if (is_array($notice)) { + echo '

' . $notice['message'] . '

'; + update_option('fediembedi-notice', null); + } + } + + /** + * @param $links + * + * @return array + */ + function fediembedi_add_plugin_page_settings_link( $links ) { + $links[] = '' . __('Configuration', 'fediembedi') . ''; + return $links; + } + +} + +$fediconfig = new FediConfig(); diff --git a/form.tpl.php b/form.tpl.php new file mode 100644 index 0000000..ae9b0b8 --- /dev/null +++ b/form.tpl.php @@ -0,0 +1,55 @@ + + + +
+

+
+ + +
+
+
+ +
"> + + +
+
"> + +
+ + +
+ +
+ + +
+ +
diff --git a/img/retoot.svg b/img/retoot.svg new file mode 100644 index 0000000..14c640e --- /dev/null +++ b/img/retoot.svg @@ -0,0 +1 @@ + diff --git a/instanceList.php b/instanceList.php new file mode 100644 index 0000000..642fed5 --- /dev/null +++ b/instanceList.php @@ -0,0 +1,9 @@ +'; + foreach($mInstancesArray as $row => $singleInstance){ + echo '