Currently we have some license issues. We are working on it.

Commit 3a3f1810 authored by MediaFormat's avatar MediaFormat
Browse files

Initial commit

parents
<?php
class Client
{
private $instance_url;
private $access_token;
private $app;
private static $acct_id;
public function __construct($instance_url, $access_token = '') {
$this->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 '<pre>';
print_r($value);
echo '</pre>';
}
private function getValidURL($url){
if ( $ret = parse_url($url) ) {
if ( !isset($ret["scheme"]) ){
$url = "http://{$url}";
}
}
return $url;
}
}
<?php
//fedi instance
$fedi_instance = get_option('fediembedi-instance');
$access_token = get_option('fediembedi-token');
$client = new \Client($fedi_instance, $access_token);
$cred = $client->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 '<details><summary>Debug</summary><pre>'; var_dump($instance_info); echo '</pre></details>'; endif;
?>
<div class="scrollable">
<div role="feed">
<?php if($show_header): ?>
<div class="account-timeline__header">
<div class="account__header">
<div class="account__header__image">
<div class="account__header__info"></div>
<?php if ($status[0]->account->header): echo "<img src=" . $status[0]->account->header . " loading='lazy'>"; endif; ?>
</div>
<div class="account__header__bar">
<div class="account__header__tabs">
<a href="<?php echo $status[0]->account->url; ?>" class="avatar" rel="noreferrer noopener" target="_blank">
<div class="account__avatar" style="width:90px; height: 90px; background-image: url('<?php echo $status[0]->account->avatar; ?>'); background-size: cover;"></div>
</a>
<div class="spacer"></div>
<div class="account__header__tabs__buttons">
<a href="<?php echo $status[0]->account->url; ?>" rel="noreferrer noopener" class="button logo-button" style="padding: 0px 16px; height: 36px; line-height: 36px;">Follow</a>
</div>
</div>
<div class="account__header__tabs__name">
<h1>
<span><?php echo $status[0]->account->display_name; ?></span>
<small><a href="" target="_blank" rel="noreferrer noopener"><?php echo $status[0]->account->url; ?></small>
</h1>
</div>
<div class="account__header__extra">
<div class="account__header__bio">
<div class="account__header__content">
<?php echo $status[0]->account->note; ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php foreach ($status as $statut) { ?>
<article>
<div tabindex="-1">
<div class="status__wrapper status__wrapper-public focusable" tabindex="0">
<div class="status__prepend">
<?php
if(!is_null($statut->reblog)): ?>
<div class="status__prepend-icon-wrapper"><i role="img" class="fa fa-retweet status__prepend-icon fa-fw"></i></div>
</div><?php
else: echo '</div>';
endif; ?>
<div class="status status-public">
<div class="status__info">
<a href="<?php if(is_null($statut->reblog)): echo $statut->url; else: echo $statut->reblog->url; endif; ?>" class="status__relative-time" target="_blank" rel="noopener">
<time datetime="<?php echo $statut->created_at; ?>"><?php
printf( _x( '%1$s ago', '%2$s = human-readable time difference', 'fediembedi' ),
human_time_diff(
wp_date("U", strtotime($statut->created_at))
)
);
?></time>
</a>
<a href="<?php if(is_null($statut->reblog)): echo $statut->account->url; else: echo $statut->reblog->account->url; endif; ?>" class="status__display-name" rel="noopener noreferrer" target="_blank">
<div class="status__avatar">
<div class="account__avatar" style="background-image: url(<?php if(is_null($statut->reblog)): echo $statut->account->avatar; else: echo $statut->reblog->account->avatar; endif; ?>); background-size: 40px; width: 40px; height: 40px;"></div>
</div>
<span class="display-name"><?php if(is_null($statut->reblog)): echo $statut->account->display_name; else: echo $statut->reblog->account->display_name; endif; ?></span>
</a>
</div>
<div class="status__content"><?php
if(!is_null($statut->reblog)):
$statut = $statut->reblog;
endif;
if(empty($statut->spoiler_text)):
echo $statut->content;
if(!is_null($statut->card)): ?>
<a href="<?php echo $statut->card->url; ?>" class="status-card compact" target="_blank" rel="noopener noreferrer">
<div class="status-card__image"><div class="status-card__image-image" style="background-image: url(<?php echo $statut->card->image; ?>);"></div></div>
<div class="status-card__content">
<strong class="status-card__title" title="<?php echo $statut->card->title; ?>"><?php echo htmlentities($statut->card->title); ?></strong>
<p class="status-card__description"><?php echo wp_trim_words(htmlentities($statut->card->description)); ?></p>
<span class="status-card__host"><?php echo $statut->card->url; ?></span>
</div>
</a>
<?php
endif;
else: echo '<details><summary>' . $statut->spoiler_text . '</summary>'. $statut->content . '</details>';
endif;
if(!empty($statut->media_attachments)):
foreach ($statut->media_attachments as $attachment) {
if (!empty($attachment->preview_url) && $attachment->type === 'image'):
echo "<img src='" . $attachment->preview_url . "' class='media-gallery__item' alt='" . $attachment->description . "' loading='lazy'>";
elseif($attachment->type === 'video'):
echo "<video src=" . $attachment->url . " controls poster='" . $attachment->preview_url . "' class='media-gallery__item' alt=" . $attachment->description . ">";
elseif($attachment->type === 'audio'):
echo "<audio src=" . $attachment->url . " controls poster='" . $attachment->preview_url . "' class='media-gallery__item' alt=" . $attachment->description . ">";
endif;
}
endif;
?></div>
</div>
</div>
</div>
</article>
<?php }
if(WP_DEBUG_DISPLAY === true): echo '<details><summary>Debug</summary><pre>'; var_dump($status); echo '</pre></details>'; endif; ?>
</div>
</div>
<?php
class WP_Widget_fediembedi extends WP_Widget {
/**
* Sets up a new Search widget instance.
*
* @since 2.8.0
*/
public function __construct() {
$widget_ops = array(
'classname' => '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;
}
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'fediembedi'); ?>
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($instance['title']); ?>" />
</label>
</p>
<p>
<label>
<input
type="checkbox"
<?php checked( $instance[ 'show_header' ], '1' ); ?>
id="<?php echo $this->get_field_id( '1' ); ?>"
name="<?php echo $this->get_field_name('show_header'); ?>"
value="1"
/><?php _e( 'Show header', 'fediembedi' ); ?>
</label>
<br>
<label>
<input
type="checkbox"
<?php checked( $instance[ 'only_media' ], '1' ); ?>
id="<?php echo $this->get_field_id( '1' ); ?>"
name="<?php echo $this->get_field_name('only_media'); ?>"
value="1"
/><?php _e( 'Only media', 'fediembedi' ); ?>
</label>
<br>
<label>
<input
type="checkbox"
<?php checked( $instance[ 'pinned' ], '1' ); ?>
id="<?php echo $this->get_field_id( '1' ); ?>"
name="<?php echo $this->get_field_name('pinned'); ?>"
value="1"
/><?php _e( 'Show pinned statuses', 'fediembedi' ); ?>
</label>
<br>
<label>
<input
type="checkbox"
<?php checked( $instance[ 'exclude_replies' ], '1' ); ?>
id="<?php echo $this->get_field_id( '1' ); ?>"
name="<?php echo $this->get_field_name('exclude_replies'); ?>"
value="1"
/><?php _e( 'Hide replies', 'fediembedi' ); ?>
</label>
<br>
<label>
<input
type="checkbox"
<?php checked( $instance[ 'exclude_reblogs' ], '1' ); ?>
id="<?php echo $this->get_field_id( '1' ); ?>"
name="<?php echo $this->get_field_name('exclude_reblogs'); ?>"
value="1"
/><?php _e( 'Hide reblogs', 'fediembedi' ); ?>
</label>
</p>
<?php
}
/**
* Handles updating settings for the current Search widget instance.
*
* @since 2.8.0
*
* @param array $new_instance New settings for this instance as input by the user via
* WP_Widget::form().
* @param array $old_instance Old settings for this instance.
* @return array Updated settings.
*/
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$new_instance = wp_parse_args( (array) $new_instance, array( 'title' => '' ) );
$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;
}
}
<?php
/**
* Plugin Name: FediEmbedi
* Plugin URI: https://git.feneas.org/mediaformat/fediembedi
* GitHub Plugin URI: https://git.feneas.org/mediaformat/fediembedi
* Description: A widget to show your Mastodon profile timeline
* Version: 0.1.0
* Author: mediaformat
* Author URI: https://mediaformat.org
* License: GPL2
* Text Domain: fediembedi
* Domain Path: /languages
*/
namespace FediEmbedi;
require_once 'fediembedi-client.php';
class FediConfig
{
public function __construct()
{
add_action('plugins_loaded', array($this, 'init'));
add_action('widgets_init', array($this, 'fediembedi_widget'));
//add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_styles'));
add_action('admin_menu', array($this, 'configuration_page'));
//add_action('save_post', array($this, 'toot_post'));
add_action('admin_notices', array($this, 'admin_notices'));
add_filter('plugin_action_links_'.plugin_basename(__FILE__), array($this, 'fediembedi_add_plugin_page_settings_link'));
//add_action('add_meta_boxes', array($this, 'add_metabox'));
//add_action('publish_future_post', array($this, 'toot_scheduled_post'));
//add_action('wp_ajax_get_toot_preview', array($this, 'get_toot_preview_ajax_handler'));
}
/**
* Init
*
* Plugin initialization
*
* @return void
*/
public function init()
{
$plugin_dir = basename(dirname(__FILE__));
//load_plugin_textdomain('fediembedi', false, $plugin_dir . '/languages');
if (isset($_GET['code'])) {
$code = $_GET['code'];
$client_id = get_option('fediembedi-client-id');
$client_secret = get_option('fediembedi-client-secret');
if (!empty($code) && !empty($client_id) && !empty($client_secret)) {
//echo __('Authentification, please wait', 'fediembedi') . '...';
update_option('fediembedi-token', 'nada');
$instance = get_option('fediembedi-instance');
$client = new \Client($instance);
$token = $client->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' => '<strong>FediEmbedi</strong> : ' . __("Can't log you in.", 'fediembedi') .
'<p><strong>' . __('Instance message', 'fediembedi') . '</strong> : ' . $token->error_description . '</p>',
'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(