File: D:/HostingSpaces/PvdBoogaard/indoorski.nl/backup/oude-site/cms/modules/twitter/module.twitter.php
<?php
/**
* This file contains the iwp_module_twitter class
*
* @version $Id$
*
*
* @package IWP_Modules
* @subpackage twitter_Module
*/
/**
* twitter Integration Class
* This class generates and saves data relating to the twitter module
*
* @package IWP_Modules
* @subpackage twitter_Module
*/
class iwp_module_twitter extends iwp_module {
public $moduleName = "twitter";
protected $AppendContent = false;
public $hasBlocks = true;
public $tweetCount = 10;
public $cacheDirs = array('module_twitter' => array('expires' => 300, 'extension' => 'html')); // expires in 5 minutes
protected $layoutBlocks = array(
array(
'id'=>'TwitterFollow',
'name'=>'Follow on Twitter',
),
array(
'id'=>'TwitterList',
'name'=>'Recent Tweets',
),
);
/**
* Instance
* This static variable holds the current instance of this object being loaded.
* So using the getInstance function anywhere will return the very same instance.
*
* @var object Instance
*/
public static $Instance;
public $TwitterFollowUser = '';
public $TwitterFeedUsers = '';
/**
* getInstance
* This is a static function that sets up the class instance and stores it to the static variable. It will then return that instantiation in the future.
*
* @return object Returns the instantiated object
**/
public static function getInstance(){
if(!isset(self::$Instance)){
self::$Instance = new self();
}
return self::$Instance;
}
/**
* Constructor
*
* @return boolean
*/
public function __construct(){
parent::__construct();
}
/**
* Returns whether or not this module implements content functionality.
*
* @return boolean
*/
public function IsContentModule () { return true; }
/**
* Returns whether or not this module implements a configuration screen
*
* @return boolean
*/
public function HasConfigurationScreen () { return true; }
/**
* Returns whether or not this module implements website-wide functionality.
*
* @return boolean
*/
public function IsWebsiteModule () { return true; }
/**
* @see iwp_module::AdminGetVariablesArray
*/
public function AdminGetVariablesArray () {
return array(
'twitter_follow',
'twitter_users',
'twitter_tweetcount',
'twitter_message',
);
}
/**
* This function returns the array of fields for this module when it is is on a content create/edit page.
* It takes the one arguement, which is optional. If provided it will load the data from the database based on the content ID, otherwise
* it will return the default array.
*
* @param integer The ID number of the content item to load.
*
* @return array An associative array of the fields to display for a content item
*/
public function AdminGetContentArray ($id = 0)
{
$fields = array();
$id = (int)$id;
$fields['posttweet'] = array(
'type' => 'module_custom:posttweet',
'default' => 'checked',
'value' => 'checked'
);
if ($id > 0) {
//$data = $this->db->FetchQuery("SELECT * FROM " . $this->getTable() ." WHERE `id` = " . $id);
$fields['posttweet']['value'] = '';
}
return $fields;
}
public function OutputBlock($blockName, $position) {
$blocks = $this->GetLayoutBlocks();
if(!isset($blocks[$blockName])){
return '';
}
$data = array();
$data['lang'] = $this->lang->GetLangVars();
$this->template->Assign($this->moduleName, $data, false);
$this->tweetCount = $this->GetVar('twitter_tweetcount');
if($blockName == 'TwitterFollow') {
$this->template->Assign(array($this->moduleName, 'url'), 'http://www.twitter.com/' . $this->TwitterFollowUser , false);
return $this->template->ParseTemplate('twitter.follow', true, 'twitter');
}elseif(substr($blockName ,0,strlen('TwitterList')) == 'TwitterList') {
$this->cache->SetDir('module_twitter');
$cacheId = $blockName;
if(!$this->cache->HasExpired($cacheId)){
return $this->cache->ReadCache($cacheId);
}
$tweetFor = str_replace('TwitterList', '', $blockName);
foreach($this->TwitterFeedUsers as $user) {
if($user != $tweetFor) {
continue;
}
$transfer = new iwp_transfer();
$return = $transfer->ReadURL($this->GetStatusURL($user, 'json'));
$json = json_decode($return);
if(isset($json->error)){
return '';
}
if(!isset($json[0]->text)) {
return '';
}
$OutputList = array();
foreach($json as $tweet){
$OutputList[] = array(
'tweetText' => $tweet->text,
'tweetHTML' => $this->TweetTextToHTML($tweet->text),
'tweetTime' => iwp_module_twitter_helper::FormatTweetTime($tweet->created_at),
);
}
$this->template->Assign('blockTitle', sprintf($this->lang->Get('LatestTweetsFor'), '@' . $tweetFor ));
$this->template->Assign('OutputList', $OutputList, false);
$return = $this->template->ParseTemplate('twitter.feed', true, 'twitter');
$this->cache->WriteCache($cacheId, $return);
return $return;
}
return '';
}
}
public function TweetTextToHTML ($text) {
$text = ' '. $text . ' ';
// add links to URLs like: www.whatever.com
$pattern = "#([\s{}\(\)\[\]])([A-Za-z0-9\-\.]+)\.(com|org|net|gov|edu|us|info|biz|ws|name|tv|ee|co|aero|arpa|asia|cat|coop|int|jobs|mil|mobi|museum|pro|tel|travel|ac|ltd)(\.([A-Za-z]{2}))?((?:/[^\s{}\(\)\[\]]*[^\.,\s{}\(\)\[\]]?)?)#ie";
$text = preg_replace($pattern, "'$1<a href=\"http://$2\" rel=\"nofollow\" target=\"_blank\">'. elipsize('http://$2', 30, false) .'</a>'", $text);
// add links to URLs like: http://www.whatever.com
$pattern = "#([\s{}\(\)\[\]])(([a-z]+?)://([A-Za-z_0-9\-]+\.([^\s{}\(\)\[\]]+[^\s,\.\;{}\(\)\[\]])))#ie";
$text = preg_replace($pattern, "'$1<a href=\"$2\" rel=\"nofollow\" target=\"_blank\">'. elipsize('$2', 30, false) .'</a>'", $text);
// add links to @username
$count = 1;
while ($count) {
// need to repeat it so we can match instances like "@username1 @username2" where the non-word regex character check overlaps
$text = preg_replace('#(\W)@(\w{1,15})(\W)#', '$1@<a href="http://twitter.com/$2" target="_blank">$2</a>$3', $text, -1, $count);
}
$text = trim($text);
return $text;
}
/**
* This function takes care of saving the data posted by the user. It is assumed that when this function is run the ValidateSave() function has
* already been run without error. This function can not be run without a valid content ID number.
*
* @param array $post The array with the posted data
* @param integer $contentid The current content id number
* @return mixed Array if there is an error, true otherwise
*/
function SaveField ($post, $contentid)
{
if($contentid < 1){
return array('Invalid Content ID Number', null);
}
if(!isset($post['twitteruserid'])) {
// no tweet to be posted
return true;
}
if((int)$post['twitteruserid'] < 1){
return array('Invalid Twitter User', null);
}
if(!isset($post['posttweet']) || (isset($post['posttweet']) && $post['posttweet'] != 'checked')) {
// no tweet to be posted
return true;
}
$tweetTemplate = $this->getTwitterMessageTemplate();
$title = $post['title'];
$contentType = iwp_strtolower(iwp_admin_content::getInstance()->ContentType->Get('name_singular'));
$charsLeft = $currentLength = 0;
$tweetTemplate = str_replace('{contenttype}', $contentType, $tweetTemplate);
$tweetTemplate = str_replace('{url}', iwp_config::Get('siteURL') . '/' . $contentid, $tweetTemplate);
// 7 is the length of {title}
$currentLength = strlen($tweetTemplate) - 7;
$charsLeft = 140 - $currentLength;
if(strlen($title) < $charsLeft) {
$tweetTemplate = str_replace('{title}', $title, $tweetTemplate);
} else {
// make room for an ellipse
$charsLeft = $charsLeft - 3;
$tweetTemplate = str_replace('{title}', substr($title, 0, $charsLeft) . '...', $tweetTemplate);
}
$userInfo = $this->db->FetchQuery('select * from ' . $this->getTable('twitter_useraccounts') . ' where id=' . (int)$post['twitteruserid']);
$return = iwp_module_twitter_helper::makeTwitterPostRequest('statuses/update.json', array('status'=>$tweetTemplate), $userInfo['authtoken']);
if(is_null($return) || !is_object($return)) {
return array($this->lang->Get('UnableToTweet'), null);
}
return true;
}
public function getTwitterMessageTemplate () {
$template = $this->GetVar('twitter_message');
if(empty($template)) {
$this->SetVar('twitter_message', $this->lang->Get('defaultTweetMessage'));
return $this->lang->Get('defaultTweetMessage');
}
return $template;
}
public function GetLayoutBlocks(){
$icon = IWP_MODULES_URI . '/' . $this->moduleName . '/images/field_icon.png';
$twitterUsersStr = $this->GetVar('twitter_follow');
$twitterUser = iwp_module_twitter_helper::convertUserStrToArray($twitterUsersStr);
$blocks = array();
if(sizeof($twitterUser) == 1){
$this->TwitterFollowUser = $twitterUser[0];
$blocks['TwitterFollow'] = array(
'id'=>'TwitterFollow',
'name'=>'Follow on Twitter',
'icon'=>$icon
);
}
$twitterUsersStr = $this->GetVar('twitter_users');
$twitterUsers = array();
$twitterUsers = iwp_module_twitter_helper::convertUserStrToArray($twitterUsersStr);
if(!empty($twitterUsers)) {
$this->TwitterFeedUsers = $twitterUsers;
foreach($twitterUsers as $user){
$blocks['TwitterList' . $user] = array('id'=>'TwitterList' . $user, 'name'=> sprintf($this->lang->Get('LatestTweetsFor'), '@' . $user), 'icon' => $icon);
}
}
if(empty($blocks)){
$this->hasBlocks = false;
}
return $blocks;
}
public function AdminGetContentTypeArray(){
return array();
}
public function remoteEditAccount () {
if (!$this->auth->HasPerm('core', 'modules', 'configure', 'twitter')) {
echo GetLang('NoPermissionToConfigureModule');
die();
}
$userId = 0;
if(isset($_GET['userid'])) {
$userId = (int)$_GET['userid'];
}
if($userId == 0) {
$this->remoteAddAccount();
die();
}
$userInfo = $this->db->FetchQuery('select * from ' . $this->getTable('twitter_useraccounts') . ' where id=' . $userId);
if(is_array($userInfo) && !empty($userInfo)) {
$this->template->Assign('userId', (string)$userId);
$this->template->Assign('twitterUsername', $userInfo['username']);
if($userInfo['default'] == 1) {
$this->template->Assign('twitterDefaultChecked', $this->output->Checked());
}else{
$this->template->Assign('twitterDefaultChecked', '');
}
}
// Load the module language variables
$this->LoadLanguageVariables();
$this->template->ParseTemplate('twitter.useraccount', false, 'twitter');
}
public function remoteAddAccount () {
if (!$this->auth->HasPerm('core', 'modules', 'configure', 'twitter')) {
echo GetLang('NoPermissionToConfigureModule');
die();
}
// load any template variables
$this->template->Assign('userId', '0');
// Load the module language variables
$this->LoadLanguageVariables();
$this->template->ParseTemplate('twitter.useraccount', false, 'twitter');
}
public function remoteDeleteAccount () {
if (!$this->auth->HasPerm('core', 'modules', 'configure', 'twitter')) {
die(json_encode(array(
'success' => false,
'message' => GetLang('NoPermissionToConfigureModule'),
)));
}
if (!isset($_POST['userid'])) {
die(json_encode(array(
'success' => false,
'message' => $this->lang->Get('InvalidUserData'),
)));
}
$userId = (int)$_POST['userid'];
if ($userId < 1) {
die(json_encode(array(
'success' => false,
'message' => $this->lang->Get('InvalidUserData'),
)));
}
if($this->db->Query('delete from ' . $this->getTable('twitter_useraccounts') . ' where id=' . $userId)) {
die(json_encode(array(
'success' => true,
'message' => $this->lang->Get('UserAccountDeleteSuccess'),
'userid' => $userId,
)));
}
die(json_encode(array(
'success' => false,
'message' => $this->lang->Get('MySQLUserDeleteError') . $this->db->GetErrorMsg(),
)));
}
public function remoteSaveAccount () {
if (!$this->auth->HasPerm('core', 'modules', 'configure', 'twitter')) {
die(json_encode(array(
'success' => false,
'message' => GetLang('NoPermissionToConfigureModule'),
)));
}
if(!isset($_POST['username']) || !isset($_POST['password']) || !isset($_POST['userid']) || !isset($_POST['default'])) {
die(json_encode(array(
'success' => false,
'message' => $this->lang->Get('InvalidUserData'),
)));
}
$default = 0;
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$userid = (int)($_POST['userid']);
if($_POST['default'] == 'checked') {
$default = 1;
}
if(empty($username)) {
die(json_encode(array(
'success' => false,
'message' => $this->lang->Get('EnterUsername'),
)));
}
if(empty($password) && $userid === 0) {
die(json_encode(array(
'success' => false,
'message' => $this->lang->Get('EnterPassword'),
)));
}
if($userid === 0) {
// they're adding a new user
// create the user token, ensuring the user is valid
$userToken = base64_encode($username . ':' . $password);
} else {
// they're editing an existing user
$userInfo = $this->db->FetchQuery('select * from ' . $this->getTable('twitter_useraccounts') . ' where id=' . $userid);
// create the user token, ensuring the user is valid
$userToken = $userInfo['authtoken'];
}
$return = iwp_module_twitter_helper::makeTwitterGetRequest('account/verify_credentials.json', '', $userToken);
if(is_null($return) || !is_object($return)) {
die(json_encode(array(
'success' => false,
'message' => $this->lang->Get('InvalidTwitterAccount'),
)));
}
// success, twitter recognises them!
$userData = array(
'username' => $username,
'authtoken' => $userToken,
'fullname' => $return->name,
'default' => $default,
);
if($userid === 0) {
// they're adding a new user
if($this->db->InsertQuery($this->getTable('twitter_useraccounts'), $userData)) {
die(json_encode(array(
'success' => true,
'insert' => true,
'userid' => $this->db->LastId(),
'name' => $return->name . ' (' . $username . ')',
'message' => $this->lang->Get('UserAccountSaveSuccess'),
)));
}
} else {
// they're editing an existing user
if($this->db->UpdateQuery($this->getTable('twitter_useraccounts'), $userData, 'id=' . $userid)) {
die(json_encode(array(
'success' => true,
'insert' => false,
'userid' => $userid,
'name' => $return->name . ' (' . $username . ')',
'message' => $this->lang->Get('UserAccountSaveSuccess'),
)));
}
}
die(json_encode(array(
'success' => false,
'message' => $this->lang->Get('MySQLUserSaveError') . $this->db->GetErrorMsg(),
)));
}
/**
* An array of all the database tables that this module uses. These names will be appended with the module table prefix.
*
* @var array
*/
protected $dbTables = array(
'twitter_useraccounts',
);
/**
* Returns a list of database tables for this module.
*
* @param boolean $withoutPrefix A boolean for whether or not to include the prefix for the table.
*
* @return string
*/
public function getTables($withoutPrefix=false) {
if($withoutPrefix) {
return $this->dbTables;
}
$tables = $this->dbTables;
foreach($tables as $k=>$table ){
$tables[$k] = IWP_MODULE_DB_PREFIX . $table;
}
return $tables;
}
/**
* This function builds the SQL for the database tables used by this module. It uses the iwp_tablecreator to do so.
* It sets the member variables table and tableSchema with the objects and final SQL.
* @return void
*
* @see iwp_tablecreator
*/
public function CreateModuleTable ()
{
// create statements should match a SHOW CREATE result, with cr/lf chars stripped out
$userAccountsTableName = $this->getTable('twitter_useraccounts');
// primary table, "iwp_module_galleries"
$settingsTable = new iwp_tablecreator($userAccountsTableName);
$settingsTable->AddField('id')->SetAsPrimaryKey();
$settingsTable->AddField('username')->SetAsVarChar('255');
$settingsTable->AddField('fullname')->SetAsVarChar('255');
$settingsTable->AddField('authtoken')->SetAsVarChar('255');
$settingsTable->AddField('default')->SetAsInt();
$this->table = array(&$settingsTable);
$this->tableSchema = array(
$userAccountsTableName => $settingsTable->GetCreateTable(),
);
}
/**
* Called by the module framework when the configuration screen is requested.
*
* @return void
*/
public function AdminConfigure ()
{
$this->form->EnableTabs = false;
$this->form->AddGroup($this->lang->Get('SiteLayoutBlocks'));
$field = $this->form->AddField('textbox', 'twitter_follow', null, $this->lang);
$field->Append('<div class="aside">' . $this->lang->Get('field_twitter_follow_Example') . '</div>');
$field = $this->form->AddField('textbox', 'twitter_users', null, $this->lang);
$field->Append('<div class="aside">' . $this->lang->Get('field_twitter_users_Example') . '</div>');
$field = $this->form->AddField('textbox', 'twitter_tweetcount', null, $this->lang)->Value(10);
//$field->Append('<div class="aside">' . $this->lang->Get('field_twitter_users_Example') . '</div>');
$this->form->AddGroup($this->lang->Get('automaticTweetPosting'));
$field = $this->form->AddField('textbox', 'twitter_message', null, $this->lang)->DisableLabel()->Value($this->lang->Get('defaultTweetMessage'));
$field = $this->form->AddField(array('module_custom:twitterusers', 'twitter'), 'twitter_useraccounts', null, $this->lang);
}
public function GetStatusURL($user, $method='json') {
return 'http://twitter.com/statuses/user_timeline/' . $user .'.' . $method . '?count=' . $this->tweetCount;
}
/**
* Apply module-specific filtering to configure screen data before it is sent to the database
*
* @param array $data
*/
public function AdminConfigureSave (&$data)
{
$user = str_replace('@', '', $data['twitter_follow']);
$finishedUser = '';
$returnStatus = array();
$transfer = new iwp_transfer();
$user = trim($user);
if(!empty($user)){
$return = $transfer->ReadURL($this->GetStatusURL($user, 'xml'));
if(empty($return) || in_string('<error>Not found</error>', $return)) {
// user doesn't exist
$returnStatus[] = sprintf($this->lang->Get('TwitterUserNotExist'), $user);
} else {
// user does exist
$finishedUser = '@' . $user;
}
}
$data['twitter_follow'] = $finishedUser;
$data['twitter_tweetcount'] = max((int)$data['twitter_tweetcount'], 1);
$users = iwp_module_twitter_helper::convertUserStrToArray($data['twitter_users']);
$finishedUsers = array();
foreach($users as $user) {
$user = trim($user);
if(empty($user)){
continue;
}
$return = $transfer->ReadURL($this->GetStatusURL($user, 'xml'));
if(empty($return) || in_string('<error>Not found</error>', $return)) {
// user doesn't exist
$returnStatus[] = sprintf($this->lang->Get('TwitterUserNotExist'), $user);
} else {
// user does exist
$finishedUsers[] = '@' . $user;
}
}
$data['twitter_users'] = implode(', ', $finishedUsers);
if(empty($returnStatus)){
return true;
}
return $returnStatus;
}
}
class iwp_module_twitter_helper {
public static function formatTweetTime($timeStr){
$timestamp = strtotime($timeStr);
$now = time();
$oneDay = 60 * 60 * 24;
if($now < $timestamp || $timestamp > ($now - $oneDay)){
// if the timestamp is in the future, or within the last 24 hours, mark as 'today'
$hoursAgo = round((($now - $timestamp)/60)/60,0);
return $hoursAgo . ' Hours Ago';
}
if($timestamp > ($now - (7 * $oneDay))) {
// within the last week
$difference = $now - $timestamp;
$days = ceil(((($difference/60)/60)/24));
if($days < 2){
return '1 Day Ago';
}else{
return $days . ' Days Ago';
}
}else{
// older than a week
$difference = $now - $timestamp;
$days = round((((($difference/60)/60)/24)/7), 0);
if($days < 2){
return '1 Week Ago';
}else{
return $days . ' Weeks Ago';
}
}
return $timeStr;
}
public static function convertUserStrToArray($userString){
$userString = str_replace('@', '', $userString);
return preg_split('#,\s*#', $userString, -1, PREG_SPLIT_NO_EMPTY);
}
public static function makeTwitterPostRequest($url, $postData='', $authToken='') {
$transfer = new iwp_transfer();
$headers = array();
if(!empty($authToken)) {
$headers = array('Authorization: Basic ' . $authToken);
}
if(!is_array($postData)) {
$postData = array();
}
$return = $transfer->SendPOSTRequest('http://twitter.com/' . $url, $postData, $headers);
$json = json_decode($return);
return $json;
}
public static function makeTwitterGetRequest($url, $postData='', $authToken='') {
$transfer = new iwp_transfer();
$headers = array();
if(is_array($postData)) {
$postData = '?' . $transfer->ArrayToQueryString($postData);
}elseif(!empty($postData)) {
$postData = '?' . $postData;
}
if(!empty($authToken)) {
$headers = array('Authorization: Basic ' . $authToken);
}
$return = $transfer->ReadURL('http://twitter.com/' . $url . $postData, $headers);
$json = json_decode($return);
return $json;
}
}