2014-05-14 16:46:07 +09:00
< ? php
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ·
· Q V I T T E R ·
· ·
· http :// github . com / hannesmannerheim / qvitter ·
· ·
· ·
· < o ) ·
· / _ //// ·
· ( ____ / ·
· ( o < ·
· o > \\\\_\ ·
· \\ ) \____ ) ·
· ·
· ·
· ·
· Qvitter is free software : you can redistribute it and / or modify it ·
· under the terms of the GNU Affero General Public License as published by ·
· the Free Software Foundation , either version three of the License or ( at ·
· your option ) any later version . ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY ; without even the implied warranty of MERCHANTABILTY or FITNESS ·
· FOR A PARTICULAR PURPOSE . See the GNU Affero General Public License for ·
· more details . ·
· ·
· You should have received a copy of the GNU Affero General Public License ·
· along with Qvitter . If not , see < http :// www . gnu . org / licenses />. ·
· ·
· Contact h @ nnesmannerhe . im if you have any questions . ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
2014-11-28 21:49:00 +09:00
const QVITTERDIR = __DIR__ ;
2014-05-14 16:46:07 +09:00
class QvitterPlugin extends Plugin {
public function settings ( $setting )
{
2015-01-28 05:22:17 +09:00
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· S E T T I N G S ·
· ·
2014-05-14 16:46:07 +09:00
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
2014-11-28 05:04:41 +09:00
// THESE SETTINGS CAN BE OVERRIDDEN IN CONFIG.PHP
// e.g. $config['site']['qvitter']['enabledbydefault'] = 'false';
2014-05-14 16:46:07 +09:00
// ENABLED BY DEFAULT (true/false)
$settings [ 'enabledbydefault' ] = true ;
// DEFAULT BACKGROUND COLOR
$settings [ 'defaultbackgroundcolor' ] = '#f4f4f4' ;
2015-01-28 05:22:17 +09:00
// DEFAULT BACKGROUND IMAGE
$settings [ 'sitebackground' ] = 'img/vagnsmossen.jpg' ;
2015-01-22 05:03:38 +09:00
2015-01-28 05:22:17 +09:00
// DEFAULT FAVICON
$settings [ 'favicon' ] = 'img/favicon.ico?v=4' ;
2015-01-22 05:03:38 +09:00
2014-05-14 16:46:07 +09:00
// DEFAULT LINK COLOR
$settings [ 'defaultlinkcolor' ] = '#0084B4' ;
2015-05-30 00:30:03 +09:00
// ENABLE DEFAULT WELCOME TEXT
$settings [ 'enablewelcometext' ] = false ;
// CUSTOM WELCOME TEXT (overrides 'enablewelcometext')
$settings [ 'customwelcometext' ] = false ;
// Example:
// $settings['customwelcometext']['sv'] = '<h1>Välkommen till Quitter.se – en federerad<sup>1</sup> mikrobloggsallmänning!</h1><p>Det här är stället för dig som har tröttnat på att privata företag kontrollerar dina relationer och samtal och säljer dem för vinst. Här är du inte instängd i en kommersiell tjänst; med Quitter.se kan du följa och prata med mikrobloggare från hela det öppna <em>GNU Social</em>-nätverket.<sup>2</sup> Tillsammans tar vi makten över kommunikationsmedlen och skapar verklig demokrati på nätet.<br><br>Quitter.se är inte en tjänst, eftersom vi inte säljer varor.<sup>3</sup> Istället kallar vi det för en allmänning.<sup>4</sup> Sajten sköts av den ideella föreningen <em>En kompis kompis</em><sup>5</sup> och finansieras av gåvor och medlemsavgifter. Allt arbete är oavlönat och frivilligt. Det är helt gratis att <span class="welcome-text-register-link">registrera sig</span>, men den som vill hjälpa till lite extra kan bli stödmedlem i föreningen eller donera valfri summa anonymt.<sup>6</sup><br><br><small class="notes"><sup>1</sup> "Federerad" är motsatsen till centraliserad. Epost är federerat, du kan mejla från Gmail till Hotmail. Kommersiella sociala medier är inte federerade, du kan inte prata med Facebook-användare på Twitter. Att hängna in och isolera en stor användarskara är nämligen hela affärsidén med sociala medier!<br><sup>2</sup> <a href="http://gnu.io/social/">http://gnu.io/social/</a> "GNU Social" är den mjukvara som Quitter.se använder. Nätverket kallas även <em>fediversum</em> ("The Fediverse" på engelska) och består egentligen av alla sajter som kommunicerar enligt Ostatus-protokollet. GNU Social-anslutna mikrobloggssajter kallas <em>instanser</em>. Det finns många andra, t ex: <a href="https://quitter.is/">quitter.is</a>, <a href="https://quitter.no/">quitter.no</a>, <a href="https://quitter.es/">quitter.es</a> och <a href="https://quitter.cat/">quitter.cat</a>. Det spelar ingen roll vilken du har ditt konto på, du kan ändå kommunicera med alla på nätverket.<br><sup>3</sup> Karl Marx. <em>Kapitalet, band I-III</em><br><sup>4</sup> <a href="http://skapaallmanningar.se/vad-ar-en-allmanning/">http://skapaallmanningar.se/vad-ar-en-allmanning/</a><br><sup>5</sup> <a href="http://enkompiskompis.se/">http://enkompiskompis.se/</a><br><sup>6</sup> <a href="http://enkompiskompis.se/sv/donationer/">http://enkompiskompis.se/sv/donationer/</a></small></p>';
// $settings['customwelcometext']['en'] = '<h1>Welcome to Quitter.se – a federated microblog common!</h1><p></p>';
2015-02-05 05:40:56 +09:00
2014-05-14 16:46:07 +09:00
// TIME BETWEEN POLLING
$settings [ 'timebetweenpolling' ] = 5000 ; // ms
2015-01-28 05:22:17 +09:00
2014-09-20 09:53:10 +09:00
// URL SHORTENER
$settings [ 'urlshortenerapiurl' ] = 'http://qttr.at/yourls-api.php' ;
2014-11-28 05:04:41 +09:00
$settings [ 'urlshortenersignature' ] = 'b6afeec983' ;
2015-01-26 03:05:09 +09:00
// CUSTOM TERMS OF USE
$settings [ 'customtermsofuse' ] = false ;
2015-02-04 22:44:04 +09:00
// IP ADDRESSES BLOCKED FROM REGISTRATION
$settings [ 'blocked_ips' ] = array ();
2014-05-14 16:46:07 +09:00
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ( o > > o ) ·
· \\\\_\ / _ //// .
· \____ ) ( ____ / ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
2014-11-28 05:04:41 +09:00
// config.php settings override the settings in this file
2014-11-28 07:39:25 +09:00
$configphpsettings = common_config ( 'site' , 'qvitter' ) ? : array ();
2014-11-28 05:04:41 +09:00
foreach ( $configphpsettings as $configphpsetting => $value ) {
$settings [ $configphpsetting ] = $value ;
2014-11-28 08:01:25 +09:00
}
2014-05-14 16:46:07 +09:00
2014-11-28 08:01:25 +09:00
if ( isset ( $settings [ $setting ])) {
return $settings [ $setting ];
}
else {
return false ;
}
2014-05-14 16:46:07 +09:00
}
2014-09-25 06:20:35 +09:00
// make sure we have a notifications table
function onCheckSchema ()
{
$schema = Schema :: get ();
$schema -> ensureTable ( 'qvitternotification' , QvitterNotification :: schemaDef ());
return true ;
}
// route/reroute urls
2014-05-14 16:46:07 +09:00
public function onRouterInitialized ( $m )
{
2015-02-26 05:16:24 +09:00
$m -> connect ( 'api/qvitter/favs_and_repeats/:notice_id.json' ,
array ( 'action' => 'ApiFavsAndRepeats' ),
array ( 'notice_id' => '[0-9]+' ));
2014-05-14 16:46:07 +09:00
$m -> connect ( 'api/statuses/public_and_external_timeline.:format' ,
array ( 'action' => 'ApiTimelinePublicAndExternal' ,
'format' => '(xml|json|rss|atom|as)' ));
$m -> connect ( 'api/qvitter/update_link_color.json' ,
array ( 'action' => 'apiqvitterupdatelinkcolor' ));
$m -> connect ( 'api/qvitter/update_background_color.json' ,
array ( 'action' => 'apiqvitterupdatebackgroundcolor' ));
2014-05-16 19:36:30 +09:00
$m -> connect ( 'api/qvitter/checklogin.json' ,
2014-05-23 21:13:38 +09:00
array ( 'action' => 'apiqvitterchecklogin' ));
2014-05-28 03:40:51 +09:00
$m -> connect ( 'api/qvitter/allfollowing/:id.json' ,
array ( 'action' => 'apiqvitterallfollowing' ,
'id' => Nickname :: INPUT_FMT ));
2014-06-02 04:51:28 +09:00
$m -> connect ( 'api/qvitter/update_cover_photo.json' ,
2014-11-24 21:47:45 +09:00
array ( 'action' => 'ApiUpdateCoverPhoto' ));
$m -> connect ( 'api/qvitter/update_background_image.json' ,
array ( 'action' => 'ApiUpdateBackgroundImage' ));
$m -> connect ( 'api/qvitter/update_avatar.json' ,
array ( 'action' => 'ApiUpdateAvatar' ));
2015-01-23 21:20:30 +09:00
$m -> connect ( 'api/qvitter/upload_image.json' ,
array ( 'action' => 'ApiUploadImage' ));
2014-11-24 21:47:45 +09:00
$m -> connect ( 'api/qvitter/external_user_show.json' ,
array ( 'action' => 'ApiExternalUserShow' ));
$m -> connect ( 'api/qvitter/toggle_qvitter.json' ,
array ( 'action' => 'ApiToggleQvitter' ));
2014-09-25 06:20:35 +09:00
$m -> connect ( 'api/qvitter/statuses/notifications.json' ,
array ( 'action' => 'apiqvitternotifications' ));
$m -> connect ( ':nickname/notifications' ,
array ( 'action' => 'qvitter' ,
'nickname' => Nickname :: INPUT_FMT ));
2014-05-14 16:46:07 +09:00
$m -> connect ( 'settings/qvitter' ,
array ( 'action' => 'qvittersettings' ));
2014-09-25 06:20:35 +09:00
$m -> connect ( 'panel/qvitter' ,
array ( 'action' => 'qvitteradminsettings' ));
common_config_append ( 'admin' , 'panels' , 'qvitteradm' );
2014-05-14 16:46:07 +09:00
$m -> connect ( 'main/qlogin' ,
array ( 'action' => 'qvitterlogin' ));
// check if we should reroute UI to qvitter
$logged_in_user = common_current_user ();
$qvitter_enabled_by_user = false ;
$qvitter_disabled_by_user = false ;
if ( $logged_in_user ) {
try {
$qvitter_enabled_by_user = Profile_prefs :: getData ( $logged_in_user -> getProfile (), 'qvitter' , 'enable_qvitter' );
} catch ( NoResultException $e ) {
$qvitter_enabled_by_user = false ;
}
try {
$qvitter_disabled_by_user = Profile_prefs :: getData ( $logged_in_user -> getProfile (), 'qvitter' , 'disable_qvitter' );
} catch ( NoResultException $e ) {
$qvitter_disabled_by_user = false ;
}
}
if (( self :: settings ( 'enabledbydefault' ) && ! $logged_in_user ) ||
( self :: settings ( 'enabledbydefault' ) && ! $qvitter_disabled_by_user ) ||
( ! self :: settings ( 'enabledbydefault' ) && $qvitter_enabled_by_user )) {
$m -> connect ( '' , array ( 'action' => 'qvitter' ));
$m -> connect ( 'main/all' , array ( 'action' => 'qvitter' ));
$m -> connect ( 'search/notice' , array ( 'action' => 'qvitter' ));
URLMapperOverwrite :: overwrite_variable ( $m , ':nickname' ,
array ( 'action' => 'showstream' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , ':nickname/' ,
array ( 'action' => 'showstream' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , ':nickname/all' ,
array ( 'action' => 'all' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , ':nickname/subscriptions' ,
array ( 'action' => 'subscriptions' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , ':nickname/subscribers' ,
array ( 'action' => 'subscribers' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , ':nickname/groups' ,
array ( 'action' => 'usergroups' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , ':nickname/replies' ,
array ( 'action' => 'replies' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , ':nickname/favorites' ,
array ( 'action' => 'showfavorites' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , 'group/:nickname' ,
array ( 'action' => 'showgroup' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , 'group/:nickname/members' ,
array ( 'action' => 'groupmembers' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ),
'qvitter' );
$m -> connect ( 'group/:nickname/admins' ,
array ( 'action' => 'qvitter' ),
array ( 'nickname' => Nickname :: DISPLAY_FMT ));
URLMapperOverwrite :: overwrite_variable ( $m , 'tag/:tag' ,
array ( 'action' => 'showstream' ),
array ( 'tag' => Router :: REGEX_TAG ),
2014-09-25 06:20:35 +09:00
'qvitter' );
URLMapperOverwrite :: overwrite_variable ( $m , 'notice/:notice' ,
array ( 'action' => 'shownotice' ),
array ( 'notice' => '[0-9]+' ),
'qvitter' );
2014-05-14 16:46:07 +09:00
}
2014-10-31 08:28:06 +09:00
2015-01-20 02:01:10 +09:00
// if qvitter is opt-out, disable the default register page (if we don't have a valid invitation code)
2015-01-20 22:15:01 +09:00
if ( isset ( $_POST [ 'code' ])) {
$valid_code = Invitation :: getKV ( 'code' , $_POST [ 'code' ]);
2015-01-20 02:01:10 +09:00
}
if ( self :: settings ( 'enabledbydefault' ) && empty ( $valid_code )) {
2014-10-31 08:28:06 +09:00
$m -> connect ( 'main/register' ,
array ( 'action' => 'qvitter' ));
}
2014-05-14 16:46:07 +09:00
}
2014-11-24 21:47:45 +09:00
/**
* Add script to default ui , to be able to toggle Qvitter with one click
*
* @ return boolean hook return
*/
function onEndShowScripts ( $action ){
if ( common_logged_in ()) {
$user = common_current_user ();
$profile = $user -> getProfile ();
$qvitter_enabled = 'false' ;
// if qvitter is enabled by default but _not_ disabled by the user,
if ( QvitterPlugin :: settings ( 'enabledbydefault' )) {
$disabled = Profile_prefs :: getConfigData ( $profile , 'qvitter' , 'disable_qvitter' );
if ( $disabled == 0 ) {
$qvitter_enabled = 'true' ;
}
}
// if qvitter is disabled by default and _enabled_ by the user,
else {
$enabled = Profile_prefs :: getConfigData ( $profile , 'qvitter' , 'enable_qvitter' );
if ( $enabled == 1 ) {
$qvitter_enabled = 'true' ;
}
}
2014-11-27 20:54:56 +09:00
$action -> inlineScript ( ' var toggleQvitterAPIURL = \'' . common_path ( '' , true ) . ' api / qvitter / toggle_qvitter . json\ ' ;
var toggleText = \ 'New ' . str_replace ( " ' " , " \ ' " , common_config ( 'site' , 'name' )) . ' \ ' ;
var qvitterEnabled = '.$qvitter_enabled.' ;
var qvitterAllLink = \ '' . common_local_url ( 'all' , array ( 'nickname' => $user -> nickname )) . ' \ ' ;
' );
2014-12-05 12:48:55 +09:00
$action -> script ( $this -> path ( 'js/toggleqvitter.js' ) . '?changed=' . date ( 'YmdHis' , filemtime ( QVITTERDIR . '/js/toggleqvitter.js' )));
2014-11-24 21:47:45 +09:00
}
}
/**
* User colors in default UI too , if theme is neo - quitter
*
* @ return boolean hook return
*/
function onEndShowStylesheets ( $action ) {
$theme = common_config ( 'site' , 'theme' );
if ( common_logged_in () && substr ( $theme , 0 , 11 ) == 'neo-quitter' ) {
$user = common_current_user ();
$profile = $user -> getProfile ();
$backgroundcolor = Profile_prefs :: getConfigData ( $profile , 'theme' , 'backgroundcolor' );
if ( ! $backgroundcolor ) {
$backgroundcolor = substr ( QvitterPlugin :: settings ( 'defaultbackgroundcolor' ), 1 );
}
$linkcolor = Profile_prefs :: getConfigData ( $profile , 'theme' , 'linkcolor' );
if ( ! $linkcolor ) {
$linkcolor = substr ( QvitterPlugin :: settings ( 'defaultlinkcolor' ), 1 );
}
$ligthen_elements = '' ;
if ( $this -> darkness ( $backgroundcolor ) < 0.5 ) {
$ligthen_elements = "
#nav_profile a:before,
#nav_timeline_replies a:before,
#nav_timeline_personal a:before,
#nav_local_default li:first-child ul.nav li:nth-child(4) a:before,
#nav_timeline_favorites a:before,
#nav_timeline_public a:before,
#nav_groups a:before,
#nav_recent-tags a:before,
#nav_timeline_favorited a:before,
#nav_directory a:before,
#nav_lists a:before,
#site_nav_local_views h3,
#content h1,
#aside_primary h2,
#gnusocial-version p,
#page_notice,
#pagination .nav_next a {
color : rgba ( 255 , 255 , 255 , 0.4 );
}
. nav li . current a : before ,
. entity_actions a {
color : rgba ( 255 , 255 , 255 , 0.6 ) ! important ;
}
#aside_primary,
. entity_edit a : before ,
. entity_remote_subscribe : before ,
#export_data a:before,
. peopletags_edit_button : before ,
. form_group_join : before ,
. form_group_leave : before ,
. form_group_delete : before ,
#site_nav_object li.current a,
#pagination .nav_next a:hover,
#content .guide {
color : rgba ( 255 , 255 , 255 , 0.6 );
}
#site_nav_local_views a,
#site_nav_object a,
#aside_primary a:not(.invite_button) {
color : rgba ( 255 , 255 , 255 , 0.7 );
}
#site_nav_local_views li.current a,
. entity_edit a : hover : before ,
. entity_remote_subscribe : hover : before ,
. peopletags_edit_button : hover : before ,
. form_group_join : hover : before ,
. form_group_leave : hover : before ,
. form_group_delete : hover : before {
color : rgba ( 255 , 255 , 255 , 0.8 );
}
#site_nav_local_views li.current a {
background - position : - 3 px 1 px ;
}
#site_nav_local_views li a:hover {
background - position :- 3 px - 24 px ;
}
#gnusocial-version,
#pagination .nav_next a {
border - color : rgba ( 255 , 255 , 255 , 0.3 );
}
#pagination .nav_next a:hover {
border - color : rgba ( 255 , 255 , 255 , 0.5 );
}
#site_nav_object li.current a {
background - position : - 3 px 2 px ;
}
#site_nav_object li a:hover {
background - position : - 3 px - 23 px ;
}
" ;
}
$action -> style ( "
body {
background - color : #".$backgroundcolor.";
}
a ,
a : hover ,
a : active ,
#site_nav_global_primary a:hover,
. threaded - replies . notice - faves : before ,
. threaded - replies . notice - repeats : before ,
2014-11-28 05:04:41 +09:00
. notice - reply - comments > a : before ,
#content .notices > .notice > .entry-metadata .conversation {
2014-11-24 21:47:45 +09:00
color : #".$linkcolor.";
}
#site_nav_global_primary a:hover {
border - color : #".$linkcolor.";
}
address {
background - color : #".$linkcolor.";
}
" . $ligthen_elements );
}
}
2014-05-14 16:46:07 +09:00
/**
* Menu item for Qvitter
*
* @ param Action $action action being executed
*
* @ return boolean hook return
*/
function onEndAccountSettingsNav ( $action )
{
$action_name = $action -> trimmed ( 'action' );
$action -> menuItem ( common_local_url ( 'qvittersettings' ),
// TRANS: Poll plugin menu item on user settings page.
_m ( 'MENU' , 'Qvitter' ),
// TRANS: Poll plugin tooltip for user settings menu item.
_m ( 'Enable/Disable Qvitter UI' ),
$action_name === 'qvittersettings' );
return true ;
}
2014-09-25 06:20:35 +09:00
/**
* Menu item for admin panel
*
* @ param Action $action action being executed
*
* @ return boolean hook return
*/
function onEndAdminPanelNav ( $action )
{
$action_name = $action -> trimmed ( 'action' );
$action -> out -> menuItem ( common_local_url ( 'qvitteradminsettings' ),
// TRANS: Poll plugin menu item on user settings page.
_m ( 'MENU' , 'Qvitter' ),
// TRANS: Poll plugin tooltip for user settings menu item.
_m ( 'Qvitter Sidebar Notice' ),
$action_name === 'qvitteradminsettings' );
return true ;
}
2014-09-10 03:48:44 +09:00
/**
2014-10-03 02:24:54 +09:00
* Add stuff to notices in API responses
2014-09-10 03:48:44 +09:00
*
* @ param Action $action action being executed
*
* @ return boolean hook return
*/
2015-02-26 05:16:24 +09:00
function onNoticeSimpleStatusArray ( $notice , & $twitter_status , $scoped )
2014-09-10 03:48:44 +09:00
{
2014-10-03 02:24:54 +09:00
// groups
2014-09-10 03:48:44 +09:00
$notice_groups = $notice -> getGroups ();
$group_addressees = false ;
foreach ( $notice_groups as $g ) {
2014-11-24 21:47:45 +09:00
$group_addressees = array ( 'nickname' => $g -> nickname , 'url' => $g -> mainpage );
}
2014-09-10 03:48:44 +09:00
$twitter_status [ 'statusnet_in_groups' ] = $group_addressees ;
2015-02-26 05:16:24 +09:00
// include the repeat-id, which we need when unrepeating later
2015-03-13 07:57:25 +09:00
if ( array_key_exists ( 'repeated' , $twitter_status ) && $twitter_status [ 'repeated' ] === true ) {
2015-02-26 05:16:24 +09:00
$repeated = Notice :: pkeyGet ( array ( 'profile_id' => $scoped -> id ,
'repeat_of' => $notice -> id ));
$twitter_status [ 'repeated_id' ] = $repeated -> id ;
}
2014-11-24 21:47:45 +09:00
2014-10-03 02:24:54 +09:00
// thumb urls
// find all thumbs
$attachments = $notice -> attachments ();
2015-01-24 00:28:41 +09:00
$attachment_url_to_id = array ();
2014-10-03 02:24:54 +09:00
if ( ! empty ( $attachments )) {
foreach ( $attachments as $attachment ) {
2015-04-30 19:50:28 +09:00
if ( is_object ( $attachment )) {
2014-10-03 02:24:54 +09:00
try {
$enclosure_o = $attachment -> getEnclosure ();
2015-01-26 08:30:01 +09:00
$thumb = $attachment -> getThumbnail ();
$attachment_url_to_id [ $enclosure_o -> url ][ 'id' ] = $attachment -> id ;
$attachment_url_to_id [ $enclosure_o -> url ][ 'thumb_url' ] = $thumb -> getUrl ();
2014-10-03 02:24:54 +09:00
} catch ( ServerException $e ) {
2015-01-26 09:47:45 +09:00
$thumb = File_thumbnail :: getKV ( 'file_id' , $attachment -> id );
2015-03-04 20:52:43 +09:00
if ( $thumb instanceof File_thumbnail ) {
2015-01-26 09:47:45 +09:00
$attachment_url_to_id [ $enclosure_o -> url ][ 'id' ] = $attachment -> id ;
2015-03-04 20:52:43 +09:00
$attachment_url_to_id [ $enclosure_o -> url ][ 'thumb_url' ] = $thumb -> getUrl ();
2015-01-26 09:47:45 +09:00
}
2014-10-03 02:24:54 +09:00
}
}
2015-04-30 19:50:28 +09:00
}
2014-10-03 02:24:54 +09:00
}
// add thumbs to $twitter_status
if ( ! empty ( $twitter_status [ 'attachments' ])) {
foreach ( $twitter_status [ 'attachments' ] as & $attachment ) {
2015-01-24 00:28:41 +09:00
if ( ! empty ( $attachment_url_to_id [ $attachment [ 'url' ]])) {
2015-01-26 03:05:09 +09:00
$attachment [ 'id' ] = $attachment_url_to_id [ $attachment [ 'url' ]][ 'id' ];
// if the attachment is other than image, and we have a thumb (e.g. videos),
// we include the default thumbnail url
if ( substr ( $attachment [ 'mimetype' ], 0 , 5 ) != 'image' ) {
$attachment [ 'thumb_url' ] = $attachment_url_to_id [ $attachment [ 'url' ]][ 'thumb_url' ];
}
2014-10-03 02:24:54 +09:00
}
}
}
2014-11-24 21:47:45 +09:00
// reply-to profile url
2014-11-25 09:58:30 +09:00
$twitter_status [ 'in_reply_to_profileurl' ] = null ;
2014-11-24 21:47:45 +09:00
if ( $notice -> reply_to ) {
$reply = Notice :: getKV ( intval ( $notice -> reply_to ));
if ( $reply ) {
$replier_profile = $reply -> getProfile ();
2014-11-25 09:58:30 +09:00
$twitter_status [ 'in_reply_to_profileurl' ] = $replier_profile -> profileurl ;
}
2014-11-24 21:47:45 +09:00
}
2014-11-25 09:58:30 +09:00
2014-11-24 21:47:45 +09:00
// some more metadata about notice
if ( $notice -> is_local == '1' ) {
$twitter_status [ 'is_local' ] = true ;
}
else {
$twitter_status [ 'is_local' ] = false ;
2015-05-25 19:17:38 +09:00
if ( $notice -> object_type != 'activity' ) {
$twitter_status [ 'external_url' ] = $notice -> getUrl ( true );
}
2014-11-24 21:47:45 +09:00
}
2015-05-25 19:17:38 +09:00
2014-11-24 21:47:45 +09:00
if ( $notice -> object_type == 'activity' ) {
$twitter_status [ 'is_activity' ] = true ;
}
else {
$twitter_status [ 'is_activity' ] = false ;
}
2014-10-03 02:24:54 +09:00
2014-09-10 03:48:44 +09:00
return true ;
}
/**
2014-11-24 21:47:45 +09:00
* Cover photo in API response , also follows_you , etc
2014-09-10 03:48:44 +09:00
*
* @ return boolean hook return
*/
2014-09-30 21:52:41 +09:00
function onTwitterUserArray ( $profile , & $twitter_user , $scoped )
2014-09-10 03:48:44 +09:00
{
$twitter_user [ 'cover_photo' ] = Profile_prefs :: getConfigData ( $profile , 'qvitter' , 'cover_photo' );
2014-11-24 21:47:45 +09:00
$twitter_user [ 'background_image' ] = Profile_prefs :: getConfigData ( $profile , 'qvitter' , 'background_image' );
2014-09-10 03:48:44 +09:00
2014-09-30 21:52:41 +09:00
// follows me?
if ( $scoped ) {
$twitter_user [ 'follows_you' ] = $profile -> isSubscribed ( $scoped );
}
2014-11-24 21:47:45 +09:00
// local user?
$twitter_user [ 'is_local' ] = $profile -> isLocal ();
2014-09-30 21:52:41 +09:00
2014-09-10 03:48:44 +09:00
return true ;
}
2014-09-25 06:20:35 +09:00
/**
* Insert into notification table
*/
function insertNotification ( $to_profile_id , $from_profile_id , $ntype , $notice_id = false )
{
2015-05-19 23:51:42 +09:00
// no notifications from blocked profiles
$to_user = User :: getKV ( 'id' , $to_profile_id );
$from_user = Profile :: getKV ( $from_profile_id );
if ( $to_user instanceof User && $to_user -> hasBlocked ( $from_user )) {
return false ;
}
2014-09-25 06:20:35 +09:00
// never notify myself
2015-05-19 23:51:42 +09:00
if ( $to_profile_id == $from_profile_id ) {
return false ;
}
2014-09-25 06:20:35 +09:00
2015-05-19 23:51:42 +09:00
// insert
$notif = new QvitterNotification ();
$notif -> to_profile_id = $to_profile_id ;
$notif -> from_profile_id = $from_profile_id ;
$notif -> ntype = $ntype ;
$notif -> notice_id = $notice_id ;
$notif -> created = common_sql_now ();
if ( ! $notif -> insert ()) {
common_log_db_error ( $notif , 'INSERT' , __FILE__ );
return false ;
2014-09-25 06:20:35 +09:00
}
2015-05-19 23:51:42 +09:00
2014-09-25 06:20:35 +09:00
return true ;
}
/**
* Insert likes in notification table
*/
public function onEndFavorNotice ( $profile , $notice )
{
// don't notify people favoriting their own notices
if ( $notice -> profile_id != $profile -> id ) {
2015-01-22 01:49:59 +09:00
$this -> insertNotification ( $notice -> profile_id , $profile -> id , 'like' , $notice -> id );
2014-09-25 06:20:35 +09:00
}
}
/**
* Remove likes in notification table on dislike
*/
public function onEndDisfavorNotice ( $profile , $notice )
{
$notif = new QvitterNotification ();
$notif -> from_profile_id = $profile -> id ;
$notif -> notice_id = $notice -> id ;
$notif -> ntype = 'like' ;
$notif -> delete ();
return true ;
}
/**
* Insert notifications for replies , mentions and repeats
*
* @ return boolean hook flag
*/
function onStartNoticeDistribute ( $notice ) {
2015-01-20 23:47:58 +09:00
// don't add notifications for activity type notices
if ( $notice -> object_type == 'activity' ) {
return true ;
}
2014-09-25 06:20:35 +09:00
2015-05-19 23:51:42 +09:00
// mark reply/mention-notifications as read if we're replying to a notice we're notified about
if ( $notice -> reply_to ) {
$user = common_current_user ();
$notification_to_mark_as_seen = QvitterNotification :: pkeyGet ( array ( 'is_seen' => 0 ,
'notice_id' => $notice -> reply_to ,
'to_profile_id' => $user -> id ));
if ( $notification_to_mark_as_seen instanceof QvitterNotification
&& ( $notification_to_mark_as_seen -> ntype == 'mention' || $notification_to_mark_as_seen -> ntype == 'reply' )) {
$orig = clone ( $notification_to_mark_as_seen );
$notification_to_mark_as_seen -> is_seen = 1 ;
$notification_to_mark_as_seen -> update ( $orig );
}
}
2014-09-25 06:20:35 +09:00
// repeats
if ( $notice -> isRepeat ()) {
$repeated_notice = Notice :: getKV ( 'id' , $notice -> repeat_of );
if ( $repeated_notice instanceof Notice ) {
$this -> insertNotification ( $repeated_notice -> profile_id , $notice -> profile_id , 'repeat' , $repeated_notice -> id );
}
}
// replies and mentions (no notifications for these if this is a repeat)
else {
2014-10-05 21:07:31 +09:00
$reply_notification_to = false ;
2014-09-25 06:20:35 +09:00
// check for reply to insert in notifications
if ( $notice -> reply_to ) {
$replyparent = $notice -> getParent ();
$replyauthor = $replyparent -> getProfile ();
2015-01-20 23:14:46 +09:00
if ( $replyauthor instanceof Profile && ! empty ( $notice -> id )) {
2014-09-25 06:20:35 +09:00
$reply_notification_to = $replyauthor -> id ;
$this -> insertNotification ( $replyauthor -> id , $notice -> profile_id , 'reply' , $notice -> id );
}
}
// check for mentions to insert in notifications
$mentions = common_find_mentions ( $notice -> content , $notice );
$sender = Profile :: getKV ( $notice -> profile_id );
2015-05-19 21:11:33 +09:00
$all_mentioned_user_ids = array ();
2014-09-25 06:20:35 +09:00
foreach ( $mentions as $mention ) {
foreach ( $mention [ 'mentioned' ] as $mentioned ) {
2015-05-19 21:11:33 +09:00
// no duplicate mentions
if ( in_array ( $mentioned -> id , $all_mentioned_user_ids )) {
continue ;
}
$all_mentioned_user_ids [] = $mentioned -> id ;
2014-09-25 06:20:35 +09:00
// only notify if mentioned user is not already notified for reply
2015-01-20 23:14:46 +09:00
if ( $reply_notification_to != $mentioned -> id && ! empty ( $notice -> id )) {
2014-09-25 06:20:35 +09:00
$this -> insertNotification ( $mentioned -> id , $notice -> profile_id , 'mention' , $notice -> id );
}
}
}
}
return true ;
}
/**
* Delete any notifications tied to deleted notices and un - repeats
*
* @ return boolean hook flag
*/
public function onNoticeDeleteRelated ( $notice )
{
$notif = new QvitterNotification ();
// unrepeats
if ( $notice -> isRepeat ()) {
$repeated_notice = Notice :: getKV ( 'id' , $notice -> repeat_of );
$notif -> notice_id = $repeated_notice -> id ;
$notif -> from_profile_id = $notice -> profile_id ;
}
// notices
else {
$notif -> notice_id = $notice -> id ;
}
$notif -> delete ();
return true ;
}
/**
* Add notification on subscription , remove on unsubscribe
*
* @ return boolean hook flag
*/
public function onEndSubscribe ( $subscriber , $other )
{
if ( Subscription :: exists ( $subscriber , $other )) {
2015-01-22 01:49:59 +09:00
$this -> insertNotification ( $other -> id , $subscriber -> id , 'follow' , 1 );
2014-09-25 06:20:35 +09:00
}
return true ;
}
public function onEndUnsubscribe ( $subscriber , $other )
{
if ( ! Subscription :: exists ( $subscriber , $other )) {
$notif = new QvitterNotification ();
$notif -> to_profile_id = $other -> id ;
$notif -> from_profile_id = $subscriber -> id ;
$notif -> ntype = 'follow' ;
$notif -> delete ();
}
return true ;
}
2014-11-28 09:16:34 +09:00
/**
* Replace GNU Social 's default FAQ with Qvitter' s
*
* @ return boolean hook flag
*/
public function onEndLoadDoc ( $title , & $output )
{
if ( $title == 'faq' ) {
2015-01-26 03:05:09 +09:00
$faq = file_get_contents ( QVITTERDIR . '/doc/en/faq.html' );
2014-11-28 09:16:34 +09:00
$faq = str_replace ( '{instance-name}' , common_config ( 'site' , 'name' ), $faq );
$faq = str_replace ( '{instance-url}' , common_config ( 'site' , 'server' ), $faq );
$faq = str_replace ( '{instance-url-with-protocol}' , common_path ( '' , true ), $faq );
if ( common_logged_in ()) {
$user = common_current_user ();
$faq = str_replace ( '{nickname}' , $user -> nickname , $faq );
}
$output = $faq ;
}
return true ;
}
/**
* Add menu items to top header in Classic
*
* @ return boolean hook flag
*/
public function onStartPrimaryNav ( $action )
{
$action -> menuItem ( common_local_url ( 'doc' , array ( 'title' => 'faq' )),
// TRANS: Menu item in primary navigation panel.
_m ( 'MENU' , 'FAQ' ),
// TRANS: Menu item title in primary navigation panel.
_ ( 'Frequently asked questions' ),
false ,
'top_nav_doc_faq' );
return true ;
2015-02-04 22:44:04 +09:00
}
/**
* No registration for blocked ips
*
* @ return boolean hook flag
*/
public function onStartUserRegister ( $profile )
{
if ( is_array ( self :: settings ( " blocked_ips " ))) {
if ( in_array ( $_SERVER [ 'REMOTE_ADDR' ], self :: settings ( " blocked_ips " ))) {
return false ;
}
}
return true ;
}
2014-11-28 09:16:34 +09:00
2015-01-27 01:13:34 +09:00
/**
* Add unread notification count to all API responses
*
* @ return boolean hook flag
*/
public function onEndSetApiUser ( $user ) {
2015-02-13 09:02:03 +09:00
if ( ! $user instanceof User ) {
return true ;
}
2015-01-27 01:13:34 +09:00
$user_id = $user -> id ;
$notification = new QvitterNotification ();
$notification -> selectAdd ();
$notification -> selectAdd ( 'ntype' );
$notification -> selectAdd ( 'count(id) as count' );
$notification -> whereAdd ( " (to_profile_id = ' " . $user_id . " ') " );
$notification -> groupBy ( 'ntype' );
$notification -> whereAdd ( " (is_seen = '0') " );
2015-02-01 10:57:18 +09:00
$notification -> whereAdd ( " (notice_id IS NOT NULL) " ); // sometimes notice_id is NULL, those notifications are corrupt and should be discarded
2015-01-27 01:13:34 +09:00
$notification -> find ();
2015-01-28 09:19:36 +09:00
$new_notifications = array ();
2015-01-27 01:13:34 +09:00
while ( $notification -> fetch ()) {
$new_notifications [ $notification -> ntype ] = $notification -> count ;
}
header ( 'Qvitter-Notifications: ' . json_encode ( $new_notifications ));
return true ;
}
2014-11-28 09:16:34 +09:00
2014-09-30 21:52:41 +09:00
2014-11-24 21:47:45 +09:00
function onPluginVersion ( & $versions )
{
$versions [] = array ( 'name' => 'Qvitter' ,
'version' => '4' ,
'author' => 'Hannes Mannerheim' ,
'homepage' => 'https://github.com/hannesmannerheim/qvitter' ,
'rawdescription' => _m ( 'User interface' ));
return true ;
}
function darkness ( $hex ) {
$r = hexdec ( $hex [ 0 ] . $hex [ 1 ]);
$g = hexdec ( $hex [ 2 ] . $hex [ 3 ]);
$b = hexdec ( $hex [ 4 ] . $hex [ 5 ]);
return ( max ( $r , $g , $b ) + min ( $r , $g , $b )) / 510.0 ; // HSL algorithm
}
2014-05-14 16:46:07 +09:00
}
2014-09-10 03:48:44 +09:00
2014-05-14 16:46:07 +09:00
/**
* Overwrites variables in URL - mapping
*
*/
class URLMapperOverwrite extends URLMapper
{
function overwrite_variable ( $m , $path , $args , $paramPatterns , $newaction )
{
$m -> connect ( $path , array ( 'action' => $newaction ), $paramPatterns );
$regex = URLMapper :: makeRegex ( $path , $paramPatterns );
foreach ( $m -> variables as $n => $v )
if ( $v [ 1 ] == $regex )
$m -> variables [ $n ][ 0 ][ 'action' ] = $newaction ;
}
}
?>