Version 4.2.0
This commit is contained in:
1 parent
0dc2aee5ed
commit
96997ddd8e
2074 files changed
+125454
-55780
No files matched your search
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Facebook Promotion
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 10 Feb 2017
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Promote;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Facebook Promotion
|
||||
*/
|
||||
class _Facebook extends PromoteAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'facebook';
|
||||
|
||||
/**
|
||||
* @brief Default settings
|
||||
*/
|
||||
public $defaultSettings = array(
|
||||
'token' => NULL,
|
||||
'owner' => NULL,
|
||||
'page_name' => NULL,
|
||||
'permissions' => NULL,
|
||||
'members' => NULL,
|
||||
'page' => NULL,
|
||||
'tags' => NULL,
|
||||
'image' => NULL,
|
||||
'last_sync' => 0
|
||||
);
|
||||
|
||||
/**
|
||||
* Is connected?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connected()
|
||||
{
|
||||
return ( $this->member->fb_uid and $this->member->fb_token );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPhoto()
|
||||
{
|
||||
if ( ! $this->settings['image'] or $this->settings['last_sync'] < time() - 86400 )
|
||||
{
|
||||
/* Fetch again */
|
||||
$response = \IPS\Http\Url::external( "https://graph.facebook.com/" . $this->settings['page'] . "/picture?type=large" )->request()->get();
|
||||
|
||||
$extension = str_replace( 'image/', '', $response->httpHeaders['Content-Type'] );
|
||||
$newFile = \IPS\File::create( 'core_Promote', 'facebook_' . $this->settings['page'] . '.' . $extension, (string) $response, NULL, FALSE, NULL, FALSE );
|
||||
|
||||
$this->saveSettings( array( 'image' => (string) $newFile->url, 'last_sync' => time() ) );
|
||||
}
|
||||
|
||||
return $this->settings['image'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->settings['page_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check publish permissions
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function canPostToPage()
|
||||
{
|
||||
try
|
||||
{
|
||||
$response = \IPS\Http\Url::external( "https://graph.facebook.com/{$this->member->fb_uid}/permissions" )->setQueryString( 'access_token', $this->member->fb_token )->request()->get()->decodeJson();
|
||||
|
||||
if ( isset( $response['error'] ) )
|
||||
{
|
||||
return $response['error']['message'];
|
||||
}
|
||||
|
||||
if ( !empty( $response['data'] ) )
|
||||
{
|
||||
$got = 0;
|
||||
foreach( $response['data'] as $permission )
|
||||
{
|
||||
if ( in_array( $permission['permission'], array( 'manage_pages', 'publish_pages' ) ) and $permission['status'] == 'granted' )
|
||||
{
|
||||
$got++;
|
||||
}
|
||||
}
|
||||
|
||||
return $got === 2;
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'facebook' );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get pages this user manages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPages()
|
||||
{
|
||||
$pages = array();
|
||||
try
|
||||
{
|
||||
$response = \IPS\Http\Url::external( "https://graph.facebook.com/{$this->member->fb_uid}/accounts" )->setQueryString( 'access_token', $this->member->fb_token )->request()->get()->decodeJson();
|
||||
|
||||
if ( !empty( $response['data'] ) )
|
||||
{
|
||||
foreach( $response['data'] as $page )
|
||||
{
|
||||
$pages[ $page['id'] ] = array( $page['name'], $page['access_token'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'facebook' );
|
||||
}
|
||||
|
||||
return $pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get form elements for this share service
|
||||
*
|
||||
* @param string $text Text for the text entry
|
||||
* @param string $link Short or full link (short when available)
|
||||
* @param string $content Additional text content (usually a comment, or the item content)
|
||||
*
|
||||
* @return array of form elements
|
||||
*/
|
||||
public function form( $text, $link=null, $content=null )
|
||||
{
|
||||
|
||||
|
||||
if ( $this->promote and $this->promote->id )
|
||||
{
|
||||
$_text = $text;
|
||||
}
|
||||
else
|
||||
{
|
||||
$_text = $text;
|
||||
|
||||
if ( $content )
|
||||
{
|
||||
$_text .= "\n" . $content;
|
||||
}
|
||||
|
||||
if ( $link )
|
||||
{
|
||||
$_text .= "\n" . $link;
|
||||
}
|
||||
|
||||
if ( count( $this->settings['tags'] ) )
|
||||
{
|
||||
$_text .= "\n" . '#' . implode( ' #', $this->settings['tags'] );
|
||||
}
|
||||
}
|
||||
|
||||
return array( new \IPS\Helpers\Form\TextArea( 'promote_social_content_facebook', $_text, FALSE, array( 'maxLength' => 2000, 'rows' => 10 ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Post to Facebook
|
||||
*
|
||||
* @param \IPS\core\Promote $promote Promote Object
|
||||
* @return void
|
||||
*/
|
||||
public function post( $promote )
|
||||
{
|
||||
$photos = $promote->imageObjects();
|
||||
|
||||
/* Get the last 20 items to see if we have a duplicate */
|
||||
$items = \IPS\Http\Url::external( "https://graph.facebook.com/" . $this->settings['page'] . "/feed" )->setQueryString( array( 'limit' => 20, 'access_token' => $this->settings['token'] ) )->request()->get()->decodeJson();
|
||||
|
||||
if ( isset( $items['data'] ) )
|
||||
{
|
||||
foreach( $items['data'] as $item )
|
||||
{
|
||||
$time = new \IPS\DateTime( $item['created_time'] );
|
||||
$now = new \IPS\DateTime();
|
||||
|
||||
/* Only look back past the last 30 mins */
|
||||
if ( intval( $now->diff( $time )->format('%i') ) > 30 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( preg_replace( '#\s{1,}#', " ", $promote->text['facebook'] ) == preg_replace( '#\s{1,}#', " ", $item['message'] ) )
|
||||
{
|
||||
/* Duplicate */
|
||||
return $item['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $photos or count( $photos ) === 1 )
|
||||
{
|
||||
/* Simple message */
|
||||
try
|
||||
{
|
||||
if ( $photos )
|
||||
{
|
||||
$thePhoto = array_pop( $photos );
|
||||
$this->response = \IPS\Http\Url::external( "https://graph.facebook.com/" . $this->settings['page'] . "/photos" )->request()->post( array(
|
||||
'message' => $promote->text['facebook'],
|
||||
'url' => (string) $this->returnUrlWithProtocol( $thePhoto->url ),
|
||||
'access_token' => $this->settings['token'],
|
||||
'link' => $promote->short_link
|
||||
) )->decodeJson();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->response = \IPS\Http\Url::external( "https://graph.facebook.com/" . $this->settings['page'] . "/feed" )->request()->post( array(
|
||||
'message' => $promote->text['facebook'],
|
||||
'access_token' => $this->settings['token'],
|
||||
'link' => $promote->short_link
|
||||
) )->decodeJson();
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'facebook' );
|
||||
|
||||
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack('facebook_publish_exception') );
|
||||
}
|
||||
|
||||
if ( isset( $this->response['id'] ) )
|
||||
{
|
||||
return $this->response['id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack('facebook_publish_exception') );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have multiple photos so we first need to create an album, and then upload into that */
|
||||
try
|
||||
{
|
||||
$this->response = \IPS\Http\Url::external( "https://graph.facebook.com/" . $this->settings['page'] . "/albums" )->request()->post( array(
|
||||
'name' => $promote->objectTitle,
|
||||
'access_token' => $this->settings['token'],
|
||||
) )->decodeJson();
|
||||
|
||||
|
||||
if ( ! isset( $this->response['id'] ) )
|
||||
{
|
||||
throw new \InvalidArgumentException('Could not create album');
|
||||
}
|
||||
|
||||
$newAlbumId = $this->response['id'];
|
||||
|
||||
foreach( $photos as $photo )
|
||||
{
|
||||
$this->response = \IPS\Http\Url::external( "https://graph.facebook.com/" . $newAlbumId . "/photos" )->request()->post( array(
|
||||
'message' => $promote->text['facebook'],
|
||||
'url' => (string) $this->returnUrlWithProtocol( $photo->url ),
|
||||
'access_token' => $this->settings['token'],
|
||||
) )->decodeJson();
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'facebook' );
|
||||
|
||||
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack('facebook_publish_exception') );
|
||||
}
|
||||
|
||||
return $this->response['id'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the published URL
|
||||
*
|
||||
* @param array $data Data returned from a successful POST
|
||||
* @return \IPS\Http\Url
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getUrl( $data )
|
||||
{
|
||||
if ( $data and preg_match( '#^[0-9_]*$#', $data ) )
|
||||
{
|
||||
return \IPS\Http\Url::external( 'https://facebook.com/' . $data );
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the URL is not protocol relative
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
protected function returnUrlWithProtocol( \IPS\Http\Url $url )
|
||||
{
|
||||
if ( ! $url->data['scheme'] )
|
||||
{
|
||||
$url = $url->setScheme( ( \substr( \IPS\Settings::i()->base_url, 0, 5 ) == 'https' ) ? 'https' : 'http' );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Internal Promotion
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 10 FEB 2017
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Promote;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal Promotion
|
||||
*/
|
||||
class _Internal extends PromoteAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'plus';
|
||||
|
||||
/**
|
||||
* @brief Default settings
|
||||
*/
|
||||
public $defaultSettings = array();
|
||||
|
||||
/**
|
||||
* Get image
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPhoto()
|
||||
{
|
||||
return \IPS\Theme::i()->settings['logo_sharer'] ? \IPS\Theme::i()->settings['logo_sharer'] : \IPS\Theme::i()->settings['logo_front'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return \IPS\Settings::i()->board_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get form elements for this share service
|
||||
*
|
||||
* @param string $text Text for the text entry
|
||||
* @param string $link Short or full link (short when available)
|
||||
* @param string $content Additional text content (usually a comment, or the item content)
|
||||
*
|
||||
* @return array of form elements
|
||||
*/
|
||||
public function form( $text, $link=null, $content=null )
|
||||
{
|
||||
return array( new \IPS\Helpers\Form\TextArea( 'promote_social_content_internal', $content ?: $text, FALSE, array( 'maxLength' => 3000, 'rows' => 6 ) ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Post to internal
|
||||
*
|
||||
* @param \IPS\Content\Promote $promote Promote Object
|
||||
* @return void
|
||||
*/
|
||||
public function post( $promote )
|
||||
{
|
||||
return time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the published URL
|
||||
*
|
||||
* @param array $data Data returned from a successful POST
|
||||
* @return \IPS\Http\Url
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getUrl( $data )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Promote Abstract Class
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 13 Jun 2013
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Promote;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote Handler
|
||||
*/
|
||||
abstract class _PromoteAbstract extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'core_social_promote_sharers';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'sharer_';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] ID Database Column
|
||||
*/
|
||||
public static $databaseColumnId = 'key';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'key';
|
||||
|
||||
/**
|
||||
* @brief [Node] Automatically set position for new nodes
|
||||
*/
|
||||
public static $automaticPositionDetermination = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Default settings
|
||||
*/
|
||||
public $defaultSettings = array();
|
||||
|
||||
/**
|
||||
* @brief The last response sent back
|
||||
*/
|
||||
public $response = NULL;
|
||||
|
||||
/**
|
||||
* @brief \IPS\core\Promote object
|
||||
*/
|
||||
public $promote = NULL;
|
||||
|
||||
/**
|
||||
* Construct ActiveRecord from database row
|
||||
*
|
||||
* @param array $data Row from database table
|
||||
* @param bool $updateMultitonStoreIfExists Replace current object in multiton store if it already exists there?
|
||||
* @return static
|
||||
*/
|
||||
public static function constructFromData( $data, $updateMultitonStoreIfExists = TRUE )
|
||||
{
|
||||
/* Initiate an object */
|
||||
$classname = '\\IPS\Content\\Promote\\' . \ucfirst( $data['sharer_key'] );
|
||||
|
||||
if ( !class_exists( $classname ) )
|
||||
{
|
||||
throw new \RuntimeException;
|
||||
}
|
||||
|
||||
$obj = new $classname;
|
||||
$obj->_new = FALSE;
|
||||
|
||||
/* Import data */
|
||||
$databasePrefixLength = \strlen( static::$databasePrefix );
|
||||
foreach ( $data as $k => $v )
|
||||
{
|
||||
if( static::$databasePrefix )
|
||||
{
|
||||
$k = \substr( $k, $databasePrefixLength );
|
||||
}
|
||||
|
||||
$obj->$k = $v;
|
||||
}
|
||||
$obj->changed = array();
|
||||
|
||||
/* Return */
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Member
|
||||
*/
|
||||
protected $member;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \IPS\Member $member The member
|
||||
* @returns $this for daisy chaining
|
||||
*/
|
||||
public function setMember( \IPS\Member $member )
|
||||
{
|
||||
$this->member = $member;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lowercase key
|
||||
*
|
||||
* @returns string
|
||||
*/
|
||||
public function get__key()
|
||||
{
|
||||
return mb_strtolower( $this->key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_settings()
|
||||
{
|
||||
return array_merge( $this->defaultSettings, json_decode( $this->_data['settings'], TRUE ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a member promote using this service?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canPromote()
|
||||
{
|
||||
return $this->enabled and \IPS\core\Promote::canPromote( $this->member );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getPhoto();
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getName();
|
||||
|
||||
/**
|
||||
* Return the published URL
|
||||
*
|
||||
* @param array $data Data returned from a successful POST
|
||||
* @return \IPS\Http\Url
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
abstract function getUrl( $data );
|
||||
|
||||
/**
|
||||
* Bulk save settings
|
||||
*
|
||||
* @param array $settings Array of (k => v) settings
|
||||
* @return void
|
||||
*/
|
||||
public function saveSettings( $settings )
|
||||
{
|
||||
$this->settings = json_encode( array_merge( $this->settings, $settings ) );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Save Changed Columns
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function save()
|
||||
{
|
||||
parent::save();
|
||||
unset( \IPS\Data\Store::i()->promoters );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Twitter Promotion
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 10 FEB 2017
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Promote;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Twitter Promotion
|
||||
*/
|
||||
class _Twitter extends PromoteAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'twitter';
|
||||
|
||||
/**
|
||||
* @brief Default settings
|
||||
*/
|
||||
public $defaultSettings = array(
|
||||
'id' => NULL,
|
||||
'owner' => NULL,
|
||||
'secret' => NULL,
|
||||
'token' => NULL,
|
||||
'name' => NULL,
|
||||
'permissions' => NULL,
|
||||
'members' => NULL,
|
||||
'tags' => NULL,
|
||||
'tags_method' => 'fill',
|
||||
'image' => NULL,
|
||||
'last_sync' => 0
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Twitter log in object
|
||||
*/
|
||||
protected static $twitter = NULL;
|
||||
|
||||
/**
|
||||
* Twitter object
|
||||
*
|
||||
* @return Object
|
||||
*/
|
||||
protected function twitter()
|
||||
{
|
||||
if ( static::$twitter === NULL )
|
||||
{
|
||||
static::$twitter = \IPS\Login::getHandler('Twitter');
|
||||
}
|
||||
|
||||
return static::$twitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPhoto()
|
||||
{
|
||||
if ( ! $this->settings['image'] or $this->settings['last_sync'] < time() - 86400 )
|
||||
{
|
||||
$user = $this->twitter()->sendRequest( 'get', 'https://api.twitter.com/1.1/account/verify_credentials.json', array(), $this->settings['token'], $this->settings['secret'] )->decodeJson();
|
||||
|
||||
/* Fetch again */
|
||||
$response = \IPS\Http\Url::external( $user['profile_image_url'] )->request()->get();
|
||||
|
||||
$extension = str_replace( 'image/', '', $response->httpHeaders['Content-Type'] );
|
||||
$newFile = \IPS\File::create( 'core_Promote', 'twitter_' . $this->settings['id'] . '.' . $extension, (string) $response, NULL, FALSE, NULL, FALSE );
|
||||
|
||||
$this->saveSettings( array( 'image' => (string) $newFile->url, 'last_sync' => time() ) );
|
||||
}
|
||||
|
||||
return $this->settings['image'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->settings['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check publish permissions
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function canPostToPage()
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->twitter()->sendRequest( 'get', 'https://api.twitter.com/1.1/account/verify_credentials.json', array(), $this->settings['token'], $this->settings['secret'] )->decodeJson();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e ) { }
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get form elements for this share service
|
||||
*
|
||||
* @param string $text Text for the text entry
|
||||
* @param string $link Short or full link (short when available)
|
||||
* @param string $content Additional text content (usually a comment, or the item content)
|
||||
*
|
||||
* @return array of form elements
|
||||
*/
|
||||
public function form( $text, $link=null, $content=null )
|
||||
{
|
||||
$textToActuallyUse = $text;
|
||||
|
||||
if ( $link )
|
||||
{
|
||||
$textToActuallyUse .= ' ' . $link;
|
||||
}
|
||||
|
||||
if ( mb_strlen( $textToActuallyUse ) < 140 )
|
||||
{
|
||||
/* Got any tags to add? */
|
||||
if ( count( $this->settings['tags'] ) )
|
||||
{
|
||||
if ( $this->settings['tags_method'] === 'trim' )
|
||||
{
|
||||
$urlLength = mb_strlen( $link ) + 2; // spaces either side
|
||||
$left = 140 - $urlLength;
|
||||
$tagLength = 0;
|
||||
$tagString = '';
|
||||
$useText = $text;
|
||||
foreach( $this->settings['tags'] as $tag )
|
||||
{
|
||||
if ( $left > 0 )
|
||||
{
|
||||
$tagString .= ' #' . $tag;
|
||||
$left -= mb_strlen( $tagString );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $left > 20 )
|
||||
{
|
||||
$useText = mb_substr( $text, 0, $left );
|
||||
}
|
||||
|
||||
$textToActuallyUse = $useText . ' ' . $link . ' ' . $tagString;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach( $this->settings['tags'] as $tag )
|
||||
{
|
||||
$considerAddingThis = ' #' . $tag;
|
||||
|
||||
if ( mb_strlen( $textToActuallyUse . $considerAddingThis ) < 140 )
|
||||
{
|
||||
$textToActuallyUse .= $considerAddingThis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$return = array();
|
||||
|
||||
if ( $this->promote and $this->promote->id )
|
||||
{
|
||||
$textToActuallyUse = $text;
|
||||
$return[] = \IPS\Theme::i()->getTemplate( 'promote' )->promoteDialogTwitterDuplicate();
|
||||
}
|
||||
|
||||
$return[] = new \IPS\Helpers\Form\TextArea( 'promote_social_content_twitter', $textToActuallyUse, FALSE, array( 'maxLength' => 300, 'rows' => 3 ) );
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post to Twitter
|
||||
*
|
||||
* @param \IPS\Content\Promote $promote Promote Object
|
||||
* @return void
|
||||
*/
|
||||
public function post( $promote )
|
||||
{
|
||||
$photos = $promote->imageObjects();
|
||||
$mediaIds = array();
|
||||
|
||||
if ( count( $photos ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$done = 0;
|
||||
foreach( $photos as $photo )
|
||||
{
|
||||
/* Twitter can only have a max of 4 images */
|
||||
if ( $done < 4 )
|
||||
{
|
||||
$this->response = $this->twitter()->sendRequest( 'post', 'https://upload.twitter.com/1.1/media/upload.json', array( 'media' => $photo->contents() ), $this->settings['token'], $this->settings['secret'] )->decodeJson();
|
||||
|
||||
if ( isset( $this->response['media_id_string'] ) )
|
||||
{
|
||||
$mediaIds[] = $this->response['media_id_string'];
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Log::log( $this->response, 'twitter' );
|
||||
}
|
||||
|
||||
$done++;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e->getMessage(), 'twitter' );
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$send = array( 'status' => $promote->text['twitter'] );
|
||||
|
||||
if ( count( $mediaIds ) )
|
||||
{
|
||||
$send['media_ids'] = implode( ',', $mediaIds );
|
||||
}
|
||||
|
||||
$this->response = $this->twitter()->sendRequest( 'post', "https://api.twitter.com/1.1/statuses/update.json", $send, $this->settings['token'], $this->settings['secret'] )->decodeJson();
|
||||
|
||||
if ( isset( $this->response['id_str'] ) )
|
||||
{
|
||||
return $this->response['id_str'];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for non critical errors we don't need to flag as complete failures */
|
||||
if ( isset( $this->response['errors'] ) )
|
||||
{
|
||||
foreach( $this->response['errors'] as $error )
|
||||
{
|
||||
/* Status is a duplicate */
|
||||
if ( $error['code'] == 187 )
|
||||
{
|
||||
/* Fetch the original string if possible */
|
||||
foreach( $promote->responses('twitter') as $response )
|
||||
{
|
||||
if ( isset( $response['id_str'] ) )
|
||||
{
|
||||
return $response['id_str'];
|
||||
}
|
||||
}
|
||||
|
||||
/* No? Ok */
|
||||
return 'Duplicate status';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack('twitter_publish_exception') );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e->getMessage(), 'twitter' );
|
||||
|
||||
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack('twitter_publish_exception') );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the published URL
|
||||
*
|
||||
* @param array $data Data returned from a successful POST
|
||||
* @return \IPS\Http\Url
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getUrl( $data )
|
||||
{
|
||||
if ( $data and preg_match( '#^[0-9_]*$#', $data ) )
|
||||
{
|
||||
return \IPS\Http\Url::external( 'https://twitter.com/' . $this->settings['id'] . '/status/' . $data );
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user