diff --git a/.gitignore b/.gitignore index 41ec42389..a2d1ffa54 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ include/jquery-1.4.2.min.js *.version* favicon.* home.html +*~ diff --git a/addon/calc/calc.php b/addon/calc/calc.php index 8c079dc7a..47fb22d33 100644 --- a/addon/calc/calc.php +++ b/addon/calc/calc.php @@ -17,7 +17,7 @@ function calc_uninstall() { } function calc_app_menu($a,&$b) { - $b['app_menu'] .= '
Calculator
'; + $b['app_menu'][] = Array('url'=>'calc', 'name'=>'Calculator'); } diff --git a/addon/convert/convert.php b/addon/convert/convert.php index 7a4c90a53..aaa56a43e 100644 --- a/addon/convert/convert.php +++ b/addon/convert/convert.php @@ -15,7 +15,7 @@ function convert_uninstall() { } function convert_app_menu($a,&$b) { - $b['app_menu'] .= '
Units Conversion
'; + $b['app_menu'][] = Array('url'=>'convert', 'name'=>'Units Conversion'); } diff --git a/addon/facebook/README b/addon/facebook/README index 19c594886..325f18dd1 100644 --- a/addon/facebook/README +++ b/addon/facebook/README @@ -33,3 +33,7 @@ long posts truncated - with a link to view the full post. Facebook contacts will not be able to view private photos, as they are not able to authenticate to your site to establish identity. We will address this in a future release. + +Info: please make sure that you understand all aspects due to Friendika's +default licence which is: Creative Commons Attribution 3.0 (further info: +http://creativecommons.org/licenses/by/3.0/ ) diff --git a/addon/facebook/facebook.php b/addon/facebook/facebook.php index 33895f80d..e8a24070d 100644 --- a/addon/facebook/facebook.php +++ b/addon/facebook/facebook.php @@ -273,6 +273,10 @@ function facebook_post(&$a) { $no_linking = get_pconfig($uid,'facebook','no_linking'); + $no_wall = ((x($_POST,'facebook_no_wall')) ? intval($_POST['facebook_no_wall']) : 0); + set__pconfig($uid,'facebook','no_wall',$no_wall); + + $linkvalue = ((x($_POST,'facebook_linking')) ? intval($_POST['facebook_linking']) : 0); set_pconfig($uid,'facebook','no_linking', (($linkvalue) ? 0 : 1)); @@ -359,12 +363,11 @@ function facebook_content(&$a) { $checked = (($no_linking) ? '' : ' checked="checked" '); $o .= '' . ' ' . t('Link all your Facebook friends and conversations') . EOL ; - $hidden = (($a->user['hidewall'] || get_config('system','block_public')) ? true : false); - if(! $hidden) { - $o .= EOL; - $o .= t('Warning: Your Facebook privacy settings can not be imported.') . EOL; - $o .= t('Linked Facebook items may be publicly visible, depending on your privacy settings for this website/account.') . EOL; - } + $no_wall = get_pconfig(local_user(),'facebook','no_wall'); + $checked = (($no_wall) ? ' checked="checked" ' : ''); + $o .= '' . ' ' . t('Do not link your Facebook profile wall posts - as these could be visible to people that would not be able to see them on Facebook.') . EOL ; + + $o .= ''; } @@ -766,12 +769,13 @@ function fb_consume_all($uid) { if(! $access_token) return; - - $s = fetch_url('https://graph.facebook.com/me/feed?access_token=' . $access_token); - if($s) { - $j = json_decode($s); - logger('fb_consume_stream: wall: ' . print_r($j,true), LOGGER_DATA); - fb_consume_stream($uid,$j,true); + if(! get_pconfig($uid,'facebook','no_wall')) { + $s = fetch_url('https://graph.facebook.com/me/feed?access_token=' . $access_token); + if($s) { + $j = json_decode($s); + logger('fb_consume_stream: wall: ' . print_r($j,true), LOGGER_DATA); + fb_consume_stream($uid,$j,true); + } } $s = fetch_url('https://graph.facebook.com/me/home?access_token=' . $access_token); if($s) { diff --git a/addon/impressum/README b/addon/impressum/README index 9a38c0bec..8e4255bd1 100644 --- a/addon/impressum/README +++ b/addon/impressum/README @@ -7,7 +7,7 @@ License: 3-clause BSD license (same as Friendika) About This plugin adds an Impressum block to the /friendika page with informations - about the page operator/owner and how to countact you in case of any questions. + about the page operator/owner and how to contact you in case of any questions. In the notes and postal fields you can use HTML tags for formatting. diff --git a/addon/sniper/sniper.php b/addon/sniper/sniper.php index d431a2466..c7d29cfdf 100644 --- a/addon/sniper/sniper.php +++ b/addon/sniper/sniper.php @@ -22,7 +22,7 @@ function sniper_uninstall() { } function sniper_app_menu($a,&$b) { - $b['app_menu'] .= '
Hot Shot Sniper
'; + $b['app_menu'][] = Array('url'=>'sniper', 'name'=>'Hot Shot Sniper'); } diff --git a/addon/statusnet/README b/addon/statusnet/README index 8d5e27297..6ace48284 100644 --- a/addon/statusnet/README +++ b/addon/statusnet/README @@ -3,30 +3,30 @@ by Tobias Diekershoff tobias.diekershoff(at)gmx.net !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! This addon is currently in under development. If you have any problem !! +!! This addon is currently under development. If you have any problem !! !! with it, please contact the Author. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! With this addon to Friendika you can give your user the possibility to post -their public messages to any StatusNet instance like identi.ca for example. The -messages will be strapped their rich context and shortened to to the character +their public messages to any StatusNet instance (like identi.ca for example). +The messages will be strapped their rich context and shortened to to the character limit of the StatusNet instance in question if necessary. If shortening of the message was performed a link will be added to the notice pointing to the original message on your server. -There is a similar plugin to forward public messages to Twitter Twitter Plugin. +There is a similar plugin to forward public messages to Twitter: Twitter Plugin. Online version of this document: http://ur1.ca/35mpb ___ Requirements ___ Due to the distributed nature of the StatusNet network, each user who wishes to -forward public messages to a StatusNet account has get the OAuth credentials -for themselves, which makes this addon a little bit more user unfriendly then -the Twitter Plugin is. Nothing to geeky though! +forward public messages to a StatusNet account has to get the OAuth credentials +for themselves, which makes this addon a little bit more user unfriendly than +the Twitter Plugin is. Nothing too geeky though! The inclusion of a shorturl for the original posting in cases when the message -was longer then the maximal allowed notice length requires it, that you have +was longer than the maximal allowed notice length requires it, that you have PHP5+ and curl on your server. Where to find @@ -58,7 +58,7 @@ To get the OAuth Consumer key pair the user has to (a) ask her Friendika admin if a pair already exists or (b) has to register the Friendika server as a client application on the StatusNet server. This can be done from the account settings under "Connect -> Connections -> Register an OAuth client application --> Register new application". +-> Register a new application". During the registration of the OAuth client remember the following: * there is no callback url @@ -69,7 +69,7 @@ During the registration of the OAuth client remember the following: After the required credentials for the application are stored in the configuration you have to actually connect your Friendika account with StatusNet. To do so follow the Sign in with StatusNet button, allow the access -and copy the security code into the addon configuration. Friendika will then +and copy the security code into the plugin configuration. Friendika will then try to acquire the final OAuth credentials from the API, if successful the -addon settings will allow you to select to post your public messages to your +plugin settings will allow you to select to post your public messages to your StatusNet account. diff --git a/addon/statusnet/statusnet.php b/addon/statusnet/statusnet.php index 2f02ded54..f1b35d6c0 100644 --- a/addon/statusnet/statusnet.php +++ b/addon/statusnet/statusnet.php @@ -355,7 +355,10 @@ function statusnet_post_hook(&$a,&$b) { logger('StatusNet post invoked'); - if((local_user()) && (local_user() == $b['uid']) && (! $b['private']) && (!$b['parent']) ) { + if((local_user()) && (local_user() == $b['uid']) && (! $b['private'])) { + + // mike 2-9-11 there was a restriction to only allow this for top level posts + // now relaxed so should allow one's own comments to be forwarded through the connector as well. // Status.Net is not considered a private network if($b['prvnets']) diff --git a/addon/tictac/tictac.php b/addon/tictac/tictac.php index d6cec08a0..cc2701f8b 100644 --- a/addon/tictac/tictac.php +++ b/addon/tictac/tictac.php @@ -17,7 +17,7 @@ function tictac_uninstall() { } function tictac_app_menu($a,&$b) { - $b['app_menu'] .= '
' . t('Three Dimensional Tic-Tac-Toe') . '
'; + $b['app_menu'][] = Array('url'=>'tictac', 'name'=>'Three Dimensional Tic-Tac-Toe'); } diff --git a/addon/twitter/README b/addon/twitter/README index a49fa5cda..e6d5f12c9 100644 --- a/addon/twitter/README +++ b/addon/twitter/README @@ -3,7 +3,7 @@ By Tobias Diekershoff tobias.diekershoff(at)gmx.net !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! This addon is currently in under development. If you have any problem !! +!! This addon is currently under development. If you have any problem !! !! with it, please contact the Author. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -29,7 +29,7 @@ After you registered the application you get an OAuth consumer key / secret pair that identifies your app, you will need them for configuration. The inclusion of a shorturl for the original posting in cases when the -message was longer then 140 characters requires it, that you have *PHP5+* and +message was longer than 140 characters requires it, that you have *PHP5+* and *curl* on your server. ___ Where to find ___ @@ -51,19 +51,19 @@ To activate this addon add @twitter@ to the list of active addons in your .htconfig.php file $a->config['system']['addon'] = "twitter, ..." Afterwards you need to add your OAuth consumer key / secret pair to it by -adding the following to lines +adding the following two lines $a->config['twitter']['consumerkey'] = 'your consumer KEY here'; $a->config['twitter']['consumersecret'] = 'your consumer SECRET here'; When this is done your user can now configure their Twitter connection at -"Settings -> Addon Settings" and enable the forwarding of their *public* +"Settings -> Plugin Settings" and enable the forwarding of their *public* messages to Twitter. __ User Configuration __ When the OAuth consumer informations are correctly placed into the -configuration file and a user visits the "Addon Settings" page they can now +configuration file and a user visits the "Plugin Settings" page they can now connect to Twitter. To do so one has to follow the _Sign in with Twitter_ button (the page will be opened in a new browser window/tab) and get a PIN from Twitter. This PIN has to be entered on the settings page. After submitting the @@ -71,7 +71,7 @@ PIN the plugin will get OAuth credentials identifying this user from the Friendika account. If this first step was successful the Twitter configuration will be changed -on the "Addon Settings" page displaying two check boxes. One to enable/disable +on the "Plugin Settings" page displaying two check boxes. One to enable/disable the forwarding of *all public* postings to Twitter and one to clear the personal configuration from the Twitter credentials. diff --git a/addon/widgets/widget_like.php b/addon/widgets/widget_like.php index 9b54212a8..6927d4324 100644 --- a/addon/widgets/widget_like.php +++ b/addon/widgets/widget_like.php @@ -4,7 +4,7 @@ function like_widget_name() { return "Shows likes"; } function like_widget_help() { - return "Search first item wich contains KEY and print like/dislike count"; + return "Search first item which contains KEY and print like/dislike count"; } function like_widget_args(){ diff --git a/boot.php b/boot.php index 28467006d..10195c2ba 100644 --- a/boot.php +++ b/boot.php @@ -8,9 +8,9 @@ require_once("include/pgettext.php"); require_once('include/nav.php'); -define ( 'FRIENDIKA_VERSION', '2.2.1083' ); +define ( 'FRIENDIKA_VERSION', '2.2.1093' ); define ( 'DFRN_PROTOCOL_VERSION', '2.21' ); -define ( 'DB_UPDATE_VERSION', 1082 ); +define ( 'DB_UPDATE_VERSION', 1087 ); define ( 'EOL', "
\r\n" ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); @@ -246,7 +246,7 @@ class App { public $timezone; public $interactive = true; public $plugins; - public $apps; + public $apps = Array(); public $identities; private $scheme; @@ -675,6 +675,8 @@ function login($register = false) { '$lostlink' => $lostlink )); + call_hooks('login_hook',$o); + return $o; }} @@ -719,14 +721,16 @@ function remote_user() { if(! function_exists('notice')) { function notice($s) { $a = get_app(); + if(! x($_SESSION,'sysmsg')) $_SESSION['sysmsg'] = array(); if($a->interactive) - $_SESSION['sysmsg'] .= $s; + $_SESSION['sysmsg'][] = $s; }} if(! function_exists('info')) { function info($s) { $a = get_app(); + if(! x($_SESSION,'sysmsg_info')) $_SESSION['sysmsg_info'] = array(); if($a->interactive) - $_SESSION['sysmsg_info'] .= $s; + $_SESSION['sysmsg_info'][] = $s; }} @@ -808,8 +812,8 @@ function profile_load(&$a, $nickname, $profile = 0) { $a->page['aside'] .= profile_sidebar($a->profile, $block); - if(! $block) - $a->page['aside'] .= contact_block(); + /*if(! $block) + $a->page['aside'] .= contact_block();*/ return; }} @@ -837,132 +841,105 @@ function profile_sidebar($profile, $block = 0) { $a = get_app(); $o = ''; - $location = ''; + $location = false; $address = false; + $pdesc = true; if((! is_array($profile)) && (! count($profile))) return $o; call_hooks('profile_sidebar_enter', $profile); - $fullname = '
' . $profile['name'] . '
'; - - $pdesc = '
' . $profile['pdesc'] . '
'; - - $tabs = ''; - - $photo = '
' . $profile['name'] . '
'; - + // don't show connect link to yourself - $connect = (($profile['uid'] != local_user()) ? '
  • ' . t('Connect') . '
  • ' : ''); + $connect = (($profile['uid'] != local_user()) ? t('Connect') : False); // don't show connect link to authenticated visitors either if((remote_user()) && ($_SESSION['visitor_visiting'] == $profile['uid'])) - $connect = ''; + $connect = False; + + // show edit profile to yourself + if ($profile['uid'] == local_user()) { + $profile['edit'] = array($a->get_baseurl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles')); + + $r = q("SELECT * FROM `profile` WHERE `uid` = %d", + local_user()); + + $profile['menu'] = array( + 'chg_photo' => t('Change profile photo'), + 'cr_new' => t('Create New Profile'), + 'entries' => array(), + ); + + if(count($r)) { + + foreach($r as $rr) { + $profile['menu']['entries'][] = array( + 'photo' => $rr['thumb'], + 'id' => $rr['id'], + 'alt' => t('Profile Image'), + 'profile_name' => $rr['profile-name'], + 'visible' => (($rr['is-default']) ? '' . t('visible to everybody') . '' + : '' . t('Edit visibility') . '') + ); + } + + + } + + + } + + + + if((x($profile,'address') == 1) || (x($profile,'locality') == 1) || (x($profile,'region') == 1) || (x($profile,'postal-code') == 1) || (x($profile,'country-name') == 1)) - $address = true; + $location = t('Location:'); - if($address) { - $location .= '
    ' . t('Location:') . '
    '; - $location .= ((x($profile,'address') == 1) ? '
    ' . $profile['address'] . '
    ' : ''); - $location .= (((x($profile,'locality') == 1) || (x($profile,'region') == 1) || (x($profile,'postal-code') == 1)) - ? '' . $profile['locality'] . '' - . ((x($profile['locality']) == 1) ? t(', ') : '') - . '' . $profile['region'] . '' - . ' ' . $profile['postal-code'] . '' : ''); - $location .= ((x($profile,'country-name') == 1) ? ' ' . $profile['country-name'] . '' : ''); - $location .= '
    '; - - } + $gender = ((x($profile,'gender') == 1) ? t('Gender:') : False); - $gender = ((x($profile,'gender') == 1) ? '
    ' . t('Gender:') . ' ' . $profile['gender'] . '
    ' : ''); + $marital = ((x($profile,'marital') == 1) ? t('Status:') : False); - $pubkey = ((x($profile,'pubkey') == 1) ? '' : ''); - - $marital = ((x($profile,'marital') == 1) ? '
    ' . t('Status:') . ' ' . $profile['marital'] . '
    ' : ''); - - $homepage = ((x($profile,'homepage') == 1) ? '
    ' . t('Homepage:') . ' ' . linkify($profile['homepage']) . '
    ' : ''); + $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); if(($profile['hidewall'] || $block) && (! local_user()) && (! remote_user())) { - $location = $pdesc = $connect = $gender = $marital = $homepage = ''; + $location = $pdesc = $connect = $gender = $marital = $homepage = False; } - $podloc = $a->get_baseurl(); - $searchable = (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ); - $nickname = $profile['nickname']; - $photo300 = $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg'; - $photo100 = $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg'; - $photo50 = $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg'; + $diaspora = array( + 'podloc' => $a->get_baseurl(), + 'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ), + 'nickname ' => $profile['nickname'], + 'fullname' => $profile['name'], + 'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg', + 'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg', + 'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg', + ); - $diaspora_vcard = <<< EOT + if (!$block){ + $contact_block = contact_block(); + } -
    -
    -
    Nickname
    -
    -$nickname -
    -
    -
    -
    Full name
    -
    -$fullname -
    -
    -
    -
    URL
    -
    -$podloc/ -
    -
    -
    -
    Photo
    -
    - -
    -
    -
    -
    Photo
    -
    - -
    -
    -
    -
    Photo
    -
    - -
    -
    -
    -
    Searchable
    -
    -$searchable -
    -
    -
    -EOT; $tpl = get_markup_template('profile_vcard.tpl'); $o .= replace_macros($tpl, array( - '$fullname' => $fullname, - '$pdesc' => $pdesc, - '$tabs' => $tabs, - '$photo' => $photo, + '$profile' => $profile, '$connect' => $connect, '$location' => $location, '$gender' => $gender, - '$pubkey' => $pubkey, + '$pdesc' => $pdesc, '$marital' => $marital, '$homepage' => $homepage, - '$diaspora' => $diaspora_vcard + '$diaspora' => $diaspora, + '$contact_block' => $contact_block, )); diff --git a/database.sql b/database.sql index f6ae4c7c6..ff339929e 100644 --- a/database.sql +++ b/database.sql @@ -58,6 +58,7 @@ CREATE TABLE IF NOT EXISTS `contact` ( `network` char(255) NOT NULL, `name` char(255) NOT NULL, `nick` char(255) NOT NULL, + `attag` char(255) NOT NULL, `photo` text NOT NULL, `thumb` text NOT NULL, `micro` text NOT NULL, @@ -205,6 +206,7 @@ CREATE TABLE IF NOT EXISTS `item` ( `pubmail` tinyint(1) NOT NULL DEFAULT '0', `visible` tinyint(1) NOT NULL DEFAULT '0', `starred` tinyint(1) NOT NULL DEFAULT '0', + `bookmark` tinyint(1) NOT NULL DEFAULT '0', `unseen` tinyint(1) NOT NULL DEFAULT '1', `deleted` tinyint(1) NOT NULL DEFAULT '0', `last-child` tinyint(1) unsigned NOT NULL DEFAULT '1', @@ -606,3 +608,17 @@ INDEX ( `iid` ) ) ENGINE = MyISAM DEFAULT CHARSET=utf8; +CREATE TABLE IF NOT EXISTS `deliverq` ( +`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY , +`cmd` CHAR( 32 ) NOT NULL , +`item` INT NOT NULL , +`contact` INT NOT NULL +) ENGINE = MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `search` ( +`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , +`uid` INT NOT NULL , +`term` CHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, +INDEX ( `uid` ), +INDEX ( `term` ) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; diff --git a/doc/Installing-Connectors.md b/doc/Installing-Connectors.md index c8fc8e790..cb56383ce 100644 --- a/doc/Installing-Connectors.md +++ b/doc/Installing-Connectors.md @@ -12,7 +12,7 @@ All three of these plugins require an account on the target network. In addition **Site Configuration** -Plugins must be installed by the site administrator before they can be use. This is accomplished through the site +Plugins must be installed by the site administrator before they can be used. This is accomplished through the site configuration file ".htconfig.php". The configuration directive looks like: @@ -84,7 +84,7 @@ To get the OAuth Consumer key pair the user has to (a) ask her Friendika admin if a pair already exists or (b) has to register the Friendika server as a client application on the StatusNet server. -This can be done from the account settings under "Settings -> Connections -> Register an OAuth client application -> Register new application". +This can be done from the account settings under "Settings -> Connections -> Register an OAuth client application -> Register a new application". During the registration of the OAuth client remember the following: @@ -133,8 +133,8 @@ d. Navigate to Set Web->Site URL & Domain -> Website Settings. Set Site URL to yoursubdomain.yourdomain.com. Set Site Domain to your yourdomain.com. -Visit the Facebook Settings section of the "Settings->Plugin Settings" page. -and click 'Install Facebook Connector'. +Visit the Facebook Settings section of the "Settings->Plugin Settings" page. +And click 'Install Facebook Connector'. This will ask you to login to Facebook and grant permission to the plugin to do its stuff. Allow it to do so. diff --git a/images/connect-bg.png b/images/connect-bg.png new file mode 100644 index 000000000..0611c73e5 Binary files /dev/null and b/images/connect-bg.png differ diff --git a/images/icons/10/add.png b/images/icons/10/add.png new file mode 100644 index 000000000..f036ac73e Binary files /dev/null and b/images/icons/10/add.png differ diff --git a/images/icons/10/delete.png b/images/icons/10/delete.png new file mode 100644 index 000000000..f6bf31da4 Binary files /dev/null and b/images/icons/10/delete.png differ diff --git a/images/icons/10/edit.png b/images/icons/10/edit.png new file mode 100644 index 000000000..a6af619e2 Binary files /dev/null and b/images/icons/10/edit.png differ diff --git a/images/icons/10/feed.png b/images/icons/10/feed.png new file mode 100644 index 000000000..0e7d02c9b Binary files /dev/null and b/images/icons/10/feed.png differ diff --git a/images/icons/10/gear.png b/images/icons/10/gear.png new file mode 100644 index 000000000..df6f87af5 Binary files /dev/null and b/images/icons/10/gear.png differ diff --git a/images/icons/10/group.png b/images/icons/10/group.png new file mode 100644 index 000000000..23172a027 Binary files /dev/null and b/images/icons/10/group.png differ diff --git a/images/icons/10/info.png b/images/icons/10/info.png new file mode 100644 index 000000000..8097733f3 Binary files /dev/null and b/images/icons/10/info.png differ diff --git a/images/icons/10/notice.png b/images/icons/10/notice.png new file mode 100644 index 000000000..327d5834e Binary files /dev/null and b/images/icons/10/notice.png differ diff --git a/images/icons/10/notify_off.png b/images/icons/10/notify_off.png new file mode 100644 index 000000000..c499de01b Binary files /dev/null and b/images/icons/10/notify_off.png differ diff --git a/images/icons/10/notify_on.png b/images/icons/10/notify_on.png new file mode 100644 index 000000000..5204e097c Binary files /dev/null and b/images/icons/10/notify_on.png differ diff --git a/images/icons/10/star.png b/images/icons/10/star.png new file mode 100644 index 000000000..185761177 Binary files /dev/null and b/images/icons/10/star.png differ diff --git a/images/icons/10/user.png b/images/icons/10/user.png new file mode 100644 index 000000000..419661be6 Binary files /dev/null and b/images/icons/10/user.png differ diff --git a/images/icons/16/add.png b/images/icons/16/add.png new file mode 100644 index 000000000..7ca375325 Binary files /dev/null and b/images/icons/16/add.png differ diff --git a/images/icons/16/delete.png b/images/icons/16/delete.png new file mode 100644 index 000000000..ada2535fc Binary files /dev/null and b/images/icons/16/delete.png differ diff --git a/images/icons/16/edit.png b/images/icons/16/edit.png new file mode 100644 index 000000000..747f5e4e7 Binary files /dev/null and b/images/icons/16/edit.png differ diff --git a/images/icons/16/feed.png b/images/icons/16/feed.png new file mode 100644 index 000000000..9ac7c6677 Binary files /dev/null and b/images/icons/16/feed.png differ diff --git a/images/icons/16/gear.png b/images/icons/16/gear.png new file mode 100644 index 000000000..5af85390f Binary files /dev/null and b/images/icons/16/gear.png differ diff --git a/images/icons/16/group.png b/images/icons/16/group.png new file mode 100644 index 000000000..bab4bcd18 Binary files /dev/null and b/images/icons/16/group.png differ diff --git a/images/icons/16/info.png b/images/icons/16/info.png new file mode 100644 index 000000000..dcd501f93 Binary files /dev/null and b/images/icons/16/info.png differ diff --git a/images/icons/16/notice.png b/images/icons/16/notice.png new file mode 100644 index 000000000..8e551ad05 Binary files /dev/null and b/images/icons/16/notice.png differ diff --git a/images/icons/16/notify_off.png b/images/icons/16/notify_off.png new file mode 100644 index 000000000..f11aa4bde Binary files /dev/null and b/images/icons/16/notify_off.png differ diff --git a/images/icons/16/notify_on.png b/images/icons/16/notify_on.png new file mode 100644 index 000000000..6e91fd995 Binary files /dev/null and b/images/icons/16/notify_on.png differ diff --git a/images/icons/16/star.png b/images/icons/16/star.png new file mode 100644 index 000000000..3130be6f0 Binary files /dev/null and b/images/icons/16/star.png differ diff --git a/images/icons/16/user.png b/images/icons/16/user.png new file mode 100644 index 000000000..df83bc27d Binary files /dev/null and b/images/icons/16/user.png differ diff --git a/images/icons/22/add.png b/images/icons/22/add.png new file mode 100644 index 000000000..ee83da024 Binary files /dev/null and b/images/icons/22/add.png differ diff --git a/images/icons/22/delete.png b/images/icons/22/delete.png new file mode 100644 index 000000000..15713471b Binary files /dev/null and b/images/icons/22/delete.png differ diff --git a/images/icons/22/edit.png b/images/icons/22/edit.png new file mode 100644 index 000000000..6e6bb4f73 Binary files /dev/null and b/images/icons/22/edit.png differ diff --git a/images/icons/22/feed.png b/images/icons/22/feed.png new file mode 100644 index 000000000..15094ce89 Binary files /dev/null and b/images/icons/22/feed.png differ diff --git a/images/icons/22/gear.png b/images/icons/22/gear.png new file mode 100644 index 000000000..16bcf77dd Binary files /dev/null and b/images/icons/22/gear.png differ diff --git a/images/icons/22/group.png b/images/icons/22/group.png new file mode 100644 index 000000000..0505432ca Binary files /dev/null and b/images/icons/22/group.png differ diff --git a/images/icons/22/info.png b/images/icons/22/info.png new file mode 100644 index 000000000..c3cc715dc Binary files /dev/null and b/images/icons/22/info.png differ diff --git a/images/icons/22/notice.png b/images/icons/22/notice.png new file mode 100644 index 000000000..e45b18c4c Binary files /dev/null and b/images/icons/22/notice.png differ diff --git a/images/icons/22/notify_off.png b/images/icons/22/notify_off.png new file mode 100644 index 000000000..f2200bb60 Binary files /dev/null and b/images/icons/22/notify_off.png differ diff --git a/images/icons/22/notify_on.png b/images/icons/22/notify_on.png new file mode 100644 index 000000000..6b3d7fd08 Binary files /dev/null and b/images/icons/22/notify_on.png differ diff --git a/images/icons/22/star.png b/images/icons/22/star.png new file mode 100644 index 000000000..b8829cbfd Binary files /dev/null and b/images/icons/22/star.png differ diff --git a/images/icons/22/user.png b/images/icons/22/user.png new file mode 100644 index 000000000..fad2bee97 Binary files /dev/null and b/images/icons/22/user.png differ diff --git a/images/icons/48/add.png b/images/icons/48/add.png new file mode 100644 index 000000000..61a0b0982 Binary files /dev/null and b/images/icons/48/add.png differ diff --git a/images/icons/48/delete.png b/images/icons/48/delete.png new file mode 100644 index 000000000..1be4c9a21 Binary files /dev/null and b/images/icons/48/delete.png differ diff --git a/images/icons/48/edit.png b/images/icons/48/edit.png new file mode 100644 index 000000000..d09214ec9 Binary files /dev/null and b/images/icons/48/edit.png differ diff --git a/images/icons/48/feed.png b/images/icons/48/feed.png new file mode 100644 index 000000000..9730b4738 Binary files /dev/null and b/images/icons/48/feed.png differ diff --git a/images/icons/48/gear.png b/images/icons/48/gear.png new file mode 100644 index 000000000..16434390d Binary files /dev/null and b/images/icons/48/gear.png differ diff --git a/images/icons/48/group.png b/images/icons/48/group.png new file mode 100644 index 000000000..e624bbfb2 Binary files /dev/null and b/images/icons/48/group.png differ diff --git a/images/icons/48/info.png b/images/icons/48/info.png new file mode 100644 index 000000000..a66ae388b Binary files /dev/null and b/images/icons/48/info.png differ diff --git a/images/icons/48/notice.png b/images/icons/48/notice.png new file mode 100644 index 000000000..a44548527 Binary files /dev/null and b/images/icons/48/notice.png differ diff --git a/images/icons/48/notify_off.png b/images/icons/48/notify_off.png new file mode 100644 index 000000000..0a8854cfe Binary files /dev/null and b/images/icons/48/notify_off.png differ diff --git a/images/icons/48/notify_on.png b/images/icons/48/notify_on.png new file mode 100644 index 000000000..8440018a6 Binary files /dev/null and b/images/icons/48/notify_on.png differ diff --git a/images/icons/48/star.png b/images/icons/48/star.png new file mode 100644 index 000000000..4b2816d15 Binary files /dev/null and b/images/icons/48/star.png differ diff --git a/images/icons/48/user.png b/images/icons/48/user.png new file mode 100644 index 000000000..f73c591e6 Binary files /dev/null and b/images/icons/48/user.png differ diff --git a/images/icons/add.png b/images/icons/add.png new file mode 100644 index 000000000..78497fbc9 Binary files /dev/null and b/images/icons/add.png differ diff --git a/images/icons/delete.png b/images/icons/delete.png new file mode 100644 index 000000000..f0cae5154 Binary files /dev/null and b/images/icons/delete.png differ diff --git a/images/icons/edit.png b/images/icons/edit.png new file mode 100644 index 000000000..aeaf835fe Binary files /dev/null and b/images/icons/edit.png differ diff --git a/images/icons/feed.png b/images/icons/feed.png new file mode 100644 index 000000000..6894257e9 Binary files /dev/null and b/images/icons/feed.png differ diff --git a/images/icons/gear.png b/images/icons/gear.png new file mode 100644 index 000000000..02847ef9d Binary files /dev/null and b/images/icons/gear.png differ diff --git a/images/icons/gear_22.png b/images/icons/gear_22.png deleted file mode 100644 index e363de00d..000000000 Binary files a/images/icons/gear_22.png and /dev/null differ diff --git a/images/icons/group.png b/images/icons/group.png new file mode 100644 index 000000000..de0dc7901 Binary files /dev/null and b/images/icons/group.png differ diff --git a/images/icons/info.png b/images/icons/info.png new file mode 100644 index 000000000..ea2b0ffa4 Binary files /dev/null and b/images/icons/info.png differ diff --git a/images/icons/make.sh b/images/icons/make.sh new file mode 100644 index 000000000..348117411 --- /dev/null +++ b/images/icons/make.sh @@ -0,0 +1,14 @@ +sizes="10 16 22 48" + +for s in $sizes +do + echo "=[ ${s}x${s} ]====" + [ -d $s ] || mkdir $s + for f in *.png + do + convert $f -resize ${s}x${s} $s/$f + echo -n "#" + done + echo +done +echo "Ok." diff --git a/images/icons/notice.png b/images/icons/notice.png new file mode 100644 index 000000000..b6017c8de Binary files /dev/null and b/images/icons/notice.png differ diff --git a/images/icons/notify_off.png b/images/icons/notify_off.png new file mode 100644 index 000000000..e6eac16b8 Binary files /dev/null and b/images/icons/notify_off.png differ diff --git a/images/icons/notify_off_22.png b/images/icons/notify_off_22.png deleted file mode 100644 index 0520af327..000000000 Binary files a/images/icons/notify_off_22.png and /dev/null differ diff --git a/images/icons/notify_on.png b/images/icons/notify_on.png new file mode 100644 index 000000000..b9e07d24e Binary files /dev/null and b/images/icons/notify_on.png differ diff --git a/images/icons/notify_on_22.png b/images/icons/notify_on_22.png deleted file mode 100644 index a8b305245..000000000 Binary files a/images/icons/notify_on_22.png and /dev/null differ diff --git a/images/icons/star.png b/images/icons/star.png new file mode 100644 index 000000000..4a2236c9b Binary files /dev/null and b/images/icons/star.png differ diff --git a/images/icons/user.png b/images/icons/user.png new file mode 100644 index 000000000..f1132b1ae Binary files /dev/null and b/images/icons/user.png differ diff --git a/include/Scrape.php b/include/Scrape.php index cc46af644..bf64c2243 100644 --- a/include/Scrape.php +++ b/include/Scrape.php @@ -332,10 +332,12 @@ function probe_url($url, $mode = PROBE_NORMAL) { if(! $url) return $result; + $network = null; $diaspora = false; $diaspora_base = ''; $diaspora_guid = ''; $diaspora_key = ''; + $has_lrdd = false; $email_conversant = false; $twitter = ((strpos($url,'twitter.com') !== false) ? true : false); @@ -352,6 +354,8 @@ function probe_url($url, $mode = PROBE_NORMAL) { $links = lrdd($url); if(count($links)) { + $has_lrdd = true; + logger('probe_url: found lrdd links: ' . print_r($links,true), LOGGER_DATA); foreach($links as $link) { if($link['@attributes']['rel'] === NAMESPACE_ZOT) @@ -493,7 +497,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { if($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) { if($diaspora) $network = NETWORK_DIASPORA; - else + elseif($has_lrdd) $network = NETWORK_OSTATUS; $priority = 0; @@ -637,7 +641,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { $vcard['nick'] = trim(substr($vcard['nick'],0,strpos($vcard['nick'],' '))); } if(! $network) - $network = 'feed'; + $network = NETWORK_FEED; if(! $priority) $priority = 2; } @@ -651,10 +655,14 @@ function probe_url($url, $mode = PROBE_NORMAL) { if(! $profile) $profile = $url; + // No human could be associated with this link, use the URL as the contact name + + if(($network === NETWORK_FEED) && ($poll) && (! x($vcard,'fn'))) + $vcard['fn'] = $url; + $vcard['fn'] = notags($vcard['fn']); $vcard['nick'] = str_replace(' ','',notags($vcard['nick'])); - - + $result['name'] = $vcard['fn']; $result['nick'] = $vcard['nick']; $result['url'] = $profile; diff --git a/include/api.php b/include/api.php index aa42313b2..1f58a6baa 100644 --- a/include/api.php +++ b/include/api.php @@ -1,6 +1,7 @@ $info){ if (strpos($a->query_string, $p)===0){ + $called_api= explode("/",$p); #unset($_SERVER['PHP_AUTH_USER']); if ($info['auth']===true && local_user()===false) { api_login($a); @@ -131,7 +133,7 @@ return ''."\n".$r; break; case "json": - header ("Content-Type: application/json"); + //header ("Content-Type: application/json"); foreach($r as $rr) return json_encode($rr); break; @@ -193,6 +195,7 @@ * Returns user info array. */ function api_get_user(&$a, $contact_id = Null){ + global $called_api; $user = null; $extra_query = ""; @@ -209,16 +212,20 @@ if(is_null($user) && x($_GET, 'screen_name')) { $user = dbesc($_GET['screen_name']); $extra_query = "AND `contact`.`nick` = '%s' "; + if (local_user()!==false) $extra_query .= "AND `contact`.`uid`=".intval(local_user()); + } - if (is_null($user) && $a->argc > 3){ - list($user, $null) = explode(".",$a->argv[3]); + if (is_null($user) && $a->argc > (count($called_api)-1)){ + $argid = count($called_api); + list($user, $null) = explode(".",$a->argv[$argid]); if(is_numeric($user)){ $user = intval($user); $extra_query = "AND `contact`.`id` = %d "; } else { $user = dbesc($user); $extra_query = "AND `contact`.`nick` = '%s' "; + if (local_user()!==false) $extra_query .= "AND `contact`.`uid`=".intval(local_user()); } } @@ -301,6 +308,7 @@ } $ret = Array( + 'self' => intval($uinfo[0]['self']), 'uid' => intval($uinfo[0]['uid']), 'id' => intval($uinfo[0]['cid']), 'name' => $uinfo[0]['name'], @@ -321,7 +329,7 @@ 'followers_count' => intval($countfollowers), 'favourites_count' => intval($starred), 'contributors_enabled' => false, - 'follow_request_sent' => false, + 'follow_request_sent' => true, 'profile_background_color' => 'cfe8f6', 'profile_text_color' => '000000', 'profile_link_color' => 'FF8500', @@ -616,6 +624,7 @@ $user_info = api_get_user($a); // get last newtork messages + // params $count = (x($_REQUEST,'count')?$_REQUEST['count']:20); $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); @@ -664,6 +673,12 @@ $user_info = api_get_user($a); // get last newtork messages + + logger("api_statuses_user_timeline: local_user: ". local_user() . + "\nuser_info: ".print_r($user_info, true) . + "\n_REQUEST: ".print_r($_REQUEST, true), + LOGGER_DEBUG); + // params $count = (x($_REQUEST,'count')?$_REQUEST['count']:20); $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); @@ -672,6 +687,7 @@ $start = $page*$count; + if ($user_info['self']==1) $sql_extra = "AND `item`.`wall` = 1 "; $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, @@ -679,14 +695,15 @@ `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` FROM `item`, `contact` WHERE `item`.`uid` = %d + AND `item`.`contact-id` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0 - AND `item`.`wall` = 1 AND `contact`.`id` = `item`.`contact-id` AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 $sql_extra AND `item`.`id`>%d ORDER BY `item`.`received` DESC LIMIT %d ,%d ", - intval($user_info['uid']), + intval(local_user()), + intval($user_info['id']), intval($since_id), intval($start), intval($count) ); @@ -711,33 +728,41 @@ if (local_user()===false) return false; $user_info = api_get_user($a); - // get last newtork messages + // in friendika starred item are private + // return favorites only for self + logger('api_favorites: self:' . $user_info['self']); - // params - $count = (x($_GET,'count')?$_GET['count']:20); - $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); - if ($page<0) $page=0; + if ($user_info['self']==0) { + $ret = array(); + } else { + + + // params + $count = (x($_GET,'count')?$_GET['count']:20); + $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); + if ($page<0) $page=0; + + $start = $page*$count; + + $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, + `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, + `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, + `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` + FROM `item`, `contact` + WHERE `item`.`uid` = %d + AND `item`.`visible` = 1 AND `item`.`deleted` = 0 + AND `item`.`starred` = 1 + AND `contact`.`id` = `item`.`contact-id` + AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 + $sql_extra + ORDER BY `item`.`received` DESC LIMIT %d ,%d ", + intval($user_info['uid']), + intval($start), intval($count) + ); + + $ret = api_format_items($r,$user_info); - $start = $page*$count; - - $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, - `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, - `contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, - `contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid` - FROM `item`, `contact` - WHERE `item`.`uid` = %d - AND `item`.`visible` = 1 AND `item`.`deleted` = 0 - AND `item`.`starred` = 1 - AND `contact`.`id` = `item`.`contact-id` - AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 - $sql_extra - ORDER BY `item`.`received` DESC LIMIT %d ,%d ", - intval($user_info['uid']), - intval($start), intval($count) - ); - - $ret = api_format_items($r,$user_info); - + } $data = array('$statuses' => $ret); switch($type){ @@ -762,6 +787,7 @@ $ret = Array(); foreach($r as $item) { + localize_item($item); $status_user = (($item['cid']==$user_info['id'])?$user_info: api_item_get_user($a,$item)); $status = array( 'created_at'=> api_date($item['created']), @@ -819,15 +845,21 @@ if (local_user()===false) return false; $user_info = api_get_user($a); + + // friends and followers only for self + if ($user_info['self']==0){ + return false; + } + if (x($_GET,'cursor') && $_GET['cursor']=='undefined'){ /* this is to stop Hotot to load friends multiple times * I'm not sure if I'm missing return something or * is a bug in hotot. Workaround, meantime */ - $ret=Array(); - $data = array('$users' => $ret); - return api_apply_template("friends", $type, $data); + /*$ret=Array(); + return array('$users' => $ret);*/ + return false; } if($qtype == 'friends') @@ -845,15 +877,18 @@ } - $data = array('$users' => $ret); - return api_apply_template("friends", $type, $data); + return array('$users' => $ret); } function api_statuses_friends(&$a, $type){ - return api_statuses_f($a,$type,"friends"); + $data = api_statuses_f($a,$type,"friends"); + if ($data===false) return false; + return api_apply_template("friends", $type, $data); } function api_statuses_followers(&$a, $type){ - return api_statuses_f($a,$type,"followers"); + $data = api_statuses_f($a,$type,"followers"); + if ($data===false) return false; + return api_apply_template("friends", $type, $data); } api_register_func('api/statuses/friends','api_statuses_friends',true); api_register_func('api/statuses/followers','api_statuses_followers',true); diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index 7f7b8748d..ca0c961b3 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -16,7 +16,10 @@ function diaspora2bb($s) { $s = preg_replace("/\*(.+?)\*/", '[i]$1[/i]', $s); $s = preg_replace("/\_(.+?)\_/", '[i]$1[/i]', $s); $s = str_replace(array('-^doublestar^-','-^doublescore-^','-^star^-','-^score^-'), array('**','__','*','_'), $s); + $s = preg_replace('/\!\[(.+?)\]\((.+?)\)/','[img]$2[/img]',$s); $s = preg_replace('/\[(.+?)\]\((.+?)\)/','[url=$2]$1[/url]',$s); + $s = preg_replace('/\@\{(.+?)\; (.+?)\@(.+?)\}/','@[url=https://$3/u/$2]$1[/url]',$s); + $s = escape_tags($s); return $s; @@ -40,6 +43,11 @@ function bb2diaspora($Text,$preserve_nl = false) { $Text = str_replace("<", "<", $Text); $Text = str_replace(">", ">", $Text); + // If we find any event code, turn it into an event. + // After we're finished processing the bbcode we'll + // replace all of the event code with a reformatted version. + + $ev = bbtoevent($Text); if($preserve_nl) $Text = str_replace(array("\n","\r"), array('',''),$Text); @@ -54,8 +62,9 @@ function bb2diaspora($Text,$preserve_nl = false) { // [img]pathtoimage[/img] - $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/", '[$1]($1)', $Text); - $Text = preg_replace("(\[url\=([$URLSearchString]*)\](.*?)\[/url\])", '[$2]($1)', $Text); + $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '[$1]($1)', $Text); + $Text = preg_replace("/\#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[#$2]($1)', $Text); + $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[$2]($1)', $Text); // $Text = preg_replace("/\[img\](.*?)\[\/img\]/", t('Image/photo: ') . '$1', $Text); // $Text = preg_replace("/\[img\](.*?)\[\/img\]/", t('image/photo'), $Text); @@ -156,19 +165,20 @@ function bb2diaspora($Text,$preserve_nl = false) { // oembed tag -// $Text = oembed_bbcode2html($Text); + // $Text = oembed_bbcode2html($Text); // If we found an event earlier, strip out all the event code and replace with a reformatted version. -// if(x($ev,'desc') && x($ev,'start')) { -// $sub = format_event_html($ev); + if(x($ev,'desc') && x($ev,'start')) { - // $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/is",$sub,$Text); - //$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/is",'',$Text); -// $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/is",'',$Text); -// $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/is",'',$Text); -// $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",'',$Text); -// } + $sub = format_event_diaspora($ev); + + $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/is",$sub,$Text); + $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/is",'',$Text); + $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/is",'',$Text); + $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/is",'',$Text); + $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",'',$Text); + } @@ -176,3 +186,37 @@ function bb2diaspora($Text,$preserve_nl = false) { return $Text; } + +function format_event_diaspora($ev) { + + if(! ((is_array($ev)) && count($ev))) + return ''; + + $bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM + + $o = 'Friendika event notification:' . "\n"; + + $o .= '**' . bb2diaspora($ev['desc']) . '**' . "\n"; + + $o .= t('Starts:') . ' ' + . (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC', + $ev['start'] , $bd_format )) + : day_translate(datetime_convert('UTC', 'UTC', + $ev['start'] , $bd_format))) + . "\n"; + + if(! $ev['nofinish']) + $o .= t('Finishes:') . ' ' + . (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC', + $ev['finish'] , $bd_format )) + : day_translate(datetime_convert('UTC', 'UTC', + $ev['finish'] , $bd_format ))) + . "\n"; + + if(strlen($ev['location'])) + $o .= t('Location:') . bb2diaspora($ev['location']) + . "\n"; + + $o .= "\n"; + return $o; +} diff --git a/include/bbcode.php b/include/bbcode.php index a3f2971e5..86b7fdb4b 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -43,65 +43,65 @@ function bbcode($Text,$preserve_nl = false) { $Text = preg_replace("/([^\]\=]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\.\=\_\~\#\%\$\!\+\,]+)/", '$1$2', $Text); - $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/", '$1', $Text); - $Text = preg_replace("(\[url\=([$URLSearchString]*)\](.*?)\[/url\])", '$2', $Text); - //$Text = preg_replace("(\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[/url\])", '$2', $Text); + $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/m", '$1', $Text); + $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/m", '$2', $Text); + //$Text = preg_replace("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/m", '$2', $Text); // Perform MAIL Search - $Text = preg_replace("(\[mail\]([$MAILSearchString]*)\[/mail\])", '$1', $Text); + $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '$1', $Text); $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '$2', $Text); // Check for bold text - $Text = preg_replace("(\[b\](.*?)\[\/b\])is",'$1',$Text); + $Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'$1',$Text); // Check for Italics text - $Text = preg_replace("(\[i\](.*?)\[\/i\])is",'$1',$Text); + $Text = preg_replace("(\[i\](.*?)\[\/i\])ism",'$1',$Text); // Check for Underline text - $Text = preg_replace("(\[u\](.*?)\[\/u\])is",'$1',$Text); + $Text = preg_replace("(\[u\](.*?)\[\/u\])ism",'$1',$Text); // Check for strike-through text - $Text = preg_replace("(\[s\](.*?)\[\/s\])is",'$1',$Text); + $Text = preg_replace("(\[s\](.*?)\[\/s\])ism",'$1',$Text); // Check for over-line text - $Text = preg_replace("(\[o\](.*?)\[\/o\])is",'$1',$Text); + $Text = preg_replace("(\[o\](.*?)\[\/o\])ism",'$1',$Text); // Check for colored text - $Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])is","$2",$Text); + $Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism","$2",$Text); // Check for sized text - $Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])is","$2",$Text); + $Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism","$2",$Text); // Check for list text - $Text = preg_replace("/\[list\](.*?)\[\/list\]/is", '' ,$Text); - $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/is", '' ,$Text); - $Text = preg_replace("/\[list=i\](.*?)\[\/list\]/s",'' ,$Text); - $Text = preg_replace("/\[list=I\](.*?)\[\/list\]/s", '' ,$Text); - $Text = preg_replace("/\[list=a\](.*?)\[\/list\]/s", '' ,$Text); - $Text = preg_replace("/\[list=A\](.*?)\[\/list\]/s", '' ,$Text); - $Text = preg_replace("/\[li\](.*?)\[\/li\]/s", '
  • $1
  • ' ,$Text); + $Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '' ,$Text); + $Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '' ,$Text); + $Text = preg_replace("/\[list=i\](.*?)\[\/list\]/sm",'' ,$Text); + $Text = preg_replace("/\[list=I\](.*?)\[\/list\]/sm", '' ,$Text); + $Text = preg_replace("/\[list=a\](.*?)\[\/list\]/sm", '' ,$Text); + $Text = preg_replace("/\[list=A\](.*?)\[\/list\]/sm", '' ,$Text); + $Text = preg_replace("/\[li\](.*?)\[\/li\]/sm", '
  • $1
  • ' ,$Text); - $Text = preg_replace("/\[td\](.*?)\[\/td\]/s", '$1' ,$Text); - $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/s", '$1' ,$Text); - $Text = preg_replace("/\[table\](.*?)\[\/table\]/s", '$1
    ' ,$Text); + $Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '$1' ,$Text); + $Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '$1' ,$Text); + $Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '$1
    ' ,$Text); - $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/s", '$1
    ' ,$Text); - $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/s", '$1
    ' ,$Text); + $Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '$1
    ' ,$Text); + $Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '$1
    ' ,$Text); // $Text = str_replace("[*]", "
  • ", $Text); // Check for font change text - $Text = preg_replace("(\[font=(.*?)\](.*?)\[\/font\])","$2",$Text); + $Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/m","$2",$Text); // Declare the format for [code] layout - $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/is",'stripcode_br_cb',$Text); + $Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism",'stripcode_br_cb',$Text); $CodeLayout = '$1'; // Check for [code] text - $Text = preg_replace("/\[code\](.*?)\[\/code\]/is","$CodeLayout", $Text); + $Text = preg_replace("/\[code\](.*?)\[\/code\]/ism","$CodeLayout", $Text); @@ -109,22 +109,22 @@ function bbcode($Text,$preserve_nl = false) { // Declare the format for [quote] layout $QuoteLayout = '
    $1
    '; // Check for [quote] text - $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/is","$QuoteLayout", $Text); + $Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism","$QuoteLayout", $Text); // Images // [img]pathtoimage[/img] - $Text = preg_replace("/\[img\](.*?)\[\/img\]/", '' . t('Image/photo') . '', $Text); + $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '' . t('Image/photo') . '', $Text); // html5 video and audio - $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '', $Text); + $Text = preg_replace("/\[video\](.*?)\[\/video\]/ism", '', $Text); - $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '', $Text); + $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/ism", '', $Text); - $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/", '', $Text); + $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '', $Text); // [img=widthxheight]image source[/img] - $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/", '', $Text); + $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '', $Text); if (get_pconfig(local_user(), 'oembed', 'use_for_youtube' )==1){ // use oembed for youtube links @@ -132,13 +132,15 @@ function bbcode($Text,$preserve_nl = false) { $Text = preg_replace("/\[\/youtube\]/",'[/embed]',$Text); } else { // Youtube extensions - $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/",'[youtube]$1[/youtube]',$Text); - $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/",'[youtube]$1[/youtube]',$Text); - $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '', $Text); + $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text); + $Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text); + $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text); + $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '', $Text); } -// $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '', $Text); +// $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '', $Text); + // oembed tag $Text = oembed_bbcode2html($Text); @@ -148,11 +150,11 @@ function bbcode($Text,$preserve_nl = false) { if(x($ev,'desc') && x($ev,'start')) { $sub = format_event_html($ev); - $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/is",$sub,$Text); - $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/is",'',$Text); - $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/is",'',$Text); - $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/is",'',$Text); - $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",'',$Text); + $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",$sub,$Text); + $Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",'',$Text); + $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text); + $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text); + $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text); } diff --git a/include/conversation.php b/include/conversation.php index 0d901a3c0..6b5bf8d7c 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -80,6 +80,7 @@ function localize_item(&$item){ } + } /** diff --git a/include/crypto.php b/include/crypto.php index a20606db5..0feb45c24 100644 --- a/include/crypto.php +++ b/include/crypto.php @@ -225,3 +225,71 @@ function pkcs5_unpad($text) if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false; return substr($text, 0, -1 * $pad); } + +function AES256CBC_encrypt($data,$key,$iv) { + return mcrypt_encrypt( + MCRYPT_RIJNDAEL_128, + str_pad($key,32,"\0"), + pkcs5_pad($data,16), + MCRYPT_MODE_CBC, + str_pad($iv,16,"\0")); +} + +function AES256CBC_decrypt($data,$key,$iv) { + return pkcs5_unpad(mcrypt_decrypt( + MCRYPT_RIJNDAEL_128, + str_pad($key,32,"\0"), + $data, + MCRYPT_MODE_CBC, + str_pad($iv,16,"\0"))); +} + +function aes_encapsulate($data,$pubkey) { + $key = random_string(32,RANDOM_STRING_TEXT); + $iv = random_string(16,RANDOM_STRING_TEXT); + $result['data'] = base64url_encode(AES256CBC_encrypt($data,$key,$iv),true); + openssl_public_encrypt($key,$k,$pubkey); + $result['key'] = base64url_encode($k,true); + openssl_public_encrypt($iv,$i,$pubkey); + $result['iv'] = base64url_encode($i,true); + return $result; +} + +function aes_unencapsulate($data,$prvkey) { + openssl_private_decrypt(base64url_decode($data['key']),$k,$prvkey); + openssl_private_decrypt(base64url_decode($data['iv']),$i,$prvkey); + return AES256CBC_decrypt(base64url_decode($data['data']),$k,$i); +} + + +// This has been superceded. + +function zot_encapsulate($data,$envelope,$pubkey) { +$res = aes_encapsulate($data,$pubkey); + +return <<< EOT + + + {$res['key']} + {$res['iv']} + $s1 + $sig + AES-256-CBC + {$res['data']} + +EOT; + +} + +// so has this + +function zot_unencapsulate($data,$prvkey) { + $ret = array(); + $c = array(); + $x = parse_xml_string($data); + $c = array('key' => $x->key,'iv' => $x->iv,'data' => $x->data); + openssl_private_decrypt(base64url_decode($x->sender),$s,$prvkey); + $ret['sender'] = $s; + $ret['data'] = aes_unencapsulate($x,$prvkey); + return $ret; +} \ No newline at end of file diff --git a/include/delivery.php b/include/delivery.php new file mode 100644 index 000000000..18ef09a31 --- /dev/null +++ b/include/delivery.php @@ -0,0 +1,447 @@ +set_baseurl(get_config('system','url')); + + logger('delivery: invoked: ' . print_r($argv,true)); + + $cmd = $argv[1]; + $item_id = intval($argv[2]); + $contact_id = intval($argv[3]); + + // Some other process may have delivered this item already. + + $r = q("select * from deliverq where cmd = '%s' and item = %d and contact = %d limit 1", + dbesc($cmd), + dbesc($item_id), + dbesc($contact_id) + ); + if(! count($r)) { + return; + } + + // It's ours to deliver. Remove it from the queue. + + q("delete from deliverq where cmd = '%s' and item = %d and contact = %d limit 1", + dbesc($cmd), + dbesc($item_id), + dbesc($contact_id) + ); + + if((! $item_id) || (! $contact_id)) + return; + + $expire = false; + $top_level = false; + $recipients = array(); + $url_recipients = array(); + + $normal_mode = true; + + $recipients[] = $contact_id; + + if($cmd === 'expire') { + $normal_mode = false; + $expire = true; + $items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1 + AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP - INTERVAL 30 MINUTE", + intval($item_id) + ); + $uid = $item_id; + $item_id = 0; + if(! count($items)) + return; + } + else { + + // find ancestors + $r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", + intval($item_id) + ); + + if((! count($r)) || (! intval($r[0]['parent']))) { + return; + } + + $target_item = $r[0]; + $parent_id = intval($r[0]['parent']); + $uid = $r[0]['uid']; + $updated = $r[0]['edited']; + + + + $items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer` + FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d ORDER BY `id` ASC", + intval($parent_id) + ); + + if(! count($items)) { + return; + } + + $icontacts = q("SELECT * FROM `contact` WHERE `id` IN ( SELECT distinct(`contact-id`) FROM `item` where `parent` = %d ) ", + intval($parent_id) + ); + if(! count($icontacts)) + return; + + + // avoid race condition with deleting entries + + if($items[0]['deleted']) { + foreach($items as $item) + $item['deleted'] = 1; + } + + if((count($items) == 1) && ($items[0]['uri'] === $items[0]['parent-uri'])) { + logger('delivery: top level post'); + $top_level = true; + } + } + + $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`, + `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, + `user`.`page-flags`, `user`.`prvnets` + FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid` + WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1", + intval($uid) + ); + + if(! count($r)) + return; + + $owner = $r[0]; + + $walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false); + + $public_message = true; + + // fill this in with a single salmon slap if applicable + $slap = ''; + + require_once('include/group.php'); + + $parent = $items[0]; + + // This is IMPORTANT!!!! + + // We will only send a "notify owner to relay" or followup message if the referenced post + // originated on our system by virtue of having our hostname somewhere + // in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere. + // if $parent['wall'] == 1 we will already have the parent message in our array + // and we will relay the whole lot. + + // expire sends an entire group of expire messages and cannot be forwarded. + // However the conversation owner will be a part of the conversation and will + // be notified during this run. + // Other DFRN conversation members will be alerted during polled updates. + + // Diaspora members currently are not notified of expirations, and other networks have + // either limited or no ability to process deletions. We should at least fix Diaspora + // by stringing togther an array of retractions and sending them onward. + + + $localhost = $a->get_hostname(); + if(strpos($localhost,':')) + $localhost = substr($localhost,0,strpos($localhost,':')); + + /** + * + * Be VERY CAREFUL if you make any changes to the following line. Seemingly innocuous changes + * have been known to cause runaway conditions which affected several servers, along with + * permissions issues. + * + */ + + if((! $top_level) && ($parent['wall'] == 0) && (! $expire) && (stristr($target_item['uri'],$localhost))) { + logger('relay denied for delivery agent.'); + + /* no relay allowed for direct contact delivery */ + return; + } + + if((strlen($parent['allow_cid'])) + || (strlen($parent['allow_gid'])) + || (strlen($parent['deny_cid'])) + || (strlen($parent['deny_gid']))) { + $public_message = false; // private recipients, not public + } + + $conversant_str = intval($contact_id); + + $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `blocked` = 0 AND `pending` = 0", + intval($contact_id) + ); + + if(count($r)) + $contact = $r[0]; + + + $feed_template = get_markup_template('atom_feed.tpl'); + $mail_template = get_markup_template('atom_mail.tpl'); + + $atom = ''; + $slaps = array(); + + $hubxml = feed_hublinks(); + + $birthday = feed_birthday($owner['uid'],$owner['timezone']); + + if(strlen($birthday)) + $birthday = '' . xmlify($birthday) . ''; + + $atom .= replace_macros($feed_template, array( + '$version' => xmlify(FRIENDIKA_VERSION), + '$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner['nickname'] ), + '$feed_title' => xmlify($owner['name']), + '$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) , + '$hub' => $hubxml, + '$salmon' => '', // private feed, we don't use salmon here + '$name' => xmlify($owner['name']), + '$profile_page' => xmlify($owner['url']), + '$photo' => xmlify($owner['photo']), + '$thumb' => xmlify($owner['thumb']), + '$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) , + '$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) , + '$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) , + '$birthday' => $birthday + )); + + foreach($items as $item) { + if(! $item['parent']) + continue; + + // private emails may be in included in public conversations. Filter them. + if(($public_message) && $item['private']) + continue; + + $item_contact = get_item_contact($item,$icontacts); + if(! $item_contact) + continue; + + $atom .= atom_entry($item,'text',$item_contact,$owner,true); + + if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire)) + $slaps[] = atom_entry($item,'html',$item_contact,$owner,true); + } + + $atom .= '' . "\r\n"; + + logger('notifier: ' . $atom, LOGGER_DATA); + + logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA); + + + require_once('include/salmon.php'); + + if($contact['self']) + return; + + $deliver_status = 0; + + switch($contact['network']) { + + case NETWORK_DFRN : + logger('notifier: dfrndelivery: ' . $contact['name']); + $deliver_status = dfrn_deliver($owner,$contact,$atom); + + logger('notifier: dfrn_delivery returns ' . $deliver_status); + + if($deliver_status == (-1)) { + logger('notifier: delivery failed: queuing message'); + // queue message for redelivery + q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`) + VALUES ( %d, '%s', '%s', '%s') ", + intval($contact['id']), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($atom) + ); + } + break; + + case NETWORK_OSTATUS : + + // Do not send to otatus if we are not configured to send to public networks + if($owner['prvnets']) + break; + if(get_config('system','ostatus_disabled') || get_config('system','dfrn_only')) + break; + + // only send salmon if public - e.g. if it's ok to notify + // a public hub, it's ok to send a salmon + + if((count($slaps)) && ($public_message) && (! $expire)) { + logger('notifier: slapdelivery: ' . $contact['name']); + foreach($slaps as $slappy) { + if($contact['notify']) { + $deliver_status = slapper($owner,$contact['notify'],$slappy); + if($deliver_status == (-1)) { + // queue message for redelivery + q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`) + VALUES ( %d, '%s', '%s', '%s') ", + intval($contact['id']), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc($slappy) + ); + } + } + } + } + + break; + + case NETWORK_MAIL : + + if(get_config('system','dfrn_only')) + break; + // WARNING: does not currently convert to RFC2047 header encodings, etc. + + $addr = $contact['addr']; + if(! strlen($addr)) + break; + + if($cmd === 'wall-new' || $cmd === 'comment-new') { + + $it = null; + if($cmd === 'wall-new') + $it = $items[0]; + else { + $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($argv[2]), + intval($uid) + ); + if(count($r)) + $it = $r[0]; + } + if(! $it) + break; + + + $local_user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", + intval($uid) + ); + if(! count($local_user)) + break; + + $reply_to = ''; + $r1 = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1", + intval($uid) + ); + if($r1 && $r1[0]['reply_to']) + $reply_to = $r1[0]['reply_to']; + + $subject = (($it['title']) ? $it['title'] : t("\x28no subject\x29")) ; + $headers = 'From: ' . $local_user[0]['username'] . ' <' . $local_user[0]['email'] . '>' . "\n"; + if($reply_to) + $headers .= 'Reply-to: ' . $reply_to . "\n"; + $headers .= 'Message-id: <' . $it['uri'] . '>' . "\n"; + if($it['uri'] !== $it['parent-uri']) { + $header .= 'References: <' . $it['parent-uri'] . '>' . "\n"; + if(! strlen($it['title'])) { + $r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1", + dbesc($it['parent-uri']) + ); + if(count($r)) { + $subtitle = $r[0]['title']; + if($subtitle) { + if(strncasecmp($subtitle,'RE:',3)) + $subject = $subtitle; + else + $subject = 'Re: ' . $subtitle; + } + } + } + } + $headers .= 'MIME-Version: 1.0' . "\n"; + $headers .= 'Content-Type: text/html; charset=UTF-8' . "\n"; + $headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n"; + $html = prepare_body($it); + $message = '' . $html . ''; + logger('notifier: email delivery to ' . $addr); + mail($addr, $subject, $message, $headers); + } + break; + + case NETWORK_DIASPORA : + logger('delivery: diaspora deliver: ' . $contact['name']); + + if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode)) + break; + + if(! $contact['pubkey']) + break; + + if($target_item['verb'] === ACTIVITY_DISLIKE) { + // unsupported + break; + } + elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) { + logger('delivery: diaspora retract: ' . $contact['name']); + // diaspora delete, + diaspora_send_retraction($target_item,$owner,$contact); + break; + } + elseif($target_item['parent'] != $target_item['id']) { + + logger('delivery: diaspora relay: ' . $contact['name']); + + // we are the relay - send comments, likes and unlikes to our conversants + diaspora_send_relay($target_item,$owner,$contact); + break; + } + elseif(($top_level) && (! $walltowall)) { + // currently no workable solution for sending walltowall + logger('delivery: diaspora status: ' . $contact['name']); + diaspora_send_status($target_item,$owner,$contact); + break; + } + + logger('delivery: diaspora unknown mode: ' . $contact['name']); + + break; + + case NETWORK_FEED : + case NETWORK_FACEBOOK : + if(get_config('system','dfrn_only')) + break; + default: + break; + } + + return; +} + +if (array_search(__file__,get_included_files())===0){ + delivery_run($argv,$argc); + killme(); +} diff --git a/include/diaspora.php b/include/diaspora.php index 90c802363..6d070ecba 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -3,6 +3,7 @@ require_once('include/crypto.php'); require_once('include/items.php'); require_once('include/bb2diaspora.php'); +require_once('include/contact_selectors.php'); function diaspora_dispatch($importer,$msg) { @@ -139,10 +140,9 @@ EOT; $encrypted_outer_key_bundle = ''; openssl_public_encrypt($outer_json,$encrypted_outer_key_bundle,$pubkey); - logger('outer_bundle_encrypt: ' . openssl_error_string()); $b64_encrypted_outer_key_bundle = base64_encode($encrypted_outer_key_bundle); - logger('outer_bundle: ' . $b64_encrypted_outer_key_bundle . ' key: ' . $pubkey); + logger('outer_bundle: ' . $b64_encrypted_outer_key_bundle . ' key: ' . $pubkey, LOGGER_DATA); $encrypted_header_json_object = json_encode(array('aes_key' => base64_encode($encrypted_outer_key_bundle), 'ciphertext' => base64_encode($ciphertext))); @@ -222,7 +222,7 @@ function diaspora_decode($importer,$xml) { * */ - logger('decrypted: ' . $decrypted); + logger('decrypted: ' . $decrypted, LOGGER_DEBUG); $idom = parse_xml_string($decrypted,false); $inner_iv = base64_decode($idom->iv); @@ -398,6 +398,7 @@ function diaspora_request($importer,$xml) { function diaspora_post($importer,$xml) { + $a = get_app(); $guid = notags(unxmlify($xml->guid)); $diaspora_handle = notags(unxmlify($xml->diaspora_handle)); @@ -417,8 +418,10 @@ function diaspora_post($importer,$xml) { dbesc($message_id), dbesc($guid) ); - if(count($r)) + if(count($r)) { + logger('diaspora_post: message exists: ' . $guid); return; + } // allocate a guid on our system - we aren't fixing any collisions. // we're ignoring them @@ -453,8 +456,16 @@ function diaspora_post($importer,$xml) { $datarray['author-link'] = $contact['url']; $datarray['author-avatar'] = $contact['thumb']; $datarray['body'] = $body; + $datarray['app'] = 'Diaspora'; - item_store($datarray); + $message_id = item_store($datarray); + + if($message_id) { + q("update item set plink = '%s' where id = %d limit 1", + dbesc($a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $message_id), + intval($message_id) + ); + } return; @@ -462,6 +473,7 @@ function diaspora_post($importer,$xml) { function diaspora_comment($importer,$xml,$msg) { + $a = get_app(); $guid = notags(unxmlify($xml->guid)); $parent_guid = notags(unxmlify($xml->parent_guid)); $diaspora_handle = notags(unxmlify($xml->diaspora_handle)); @@ -474,8 +486,10 @@ function diaspora_comment($importer,$xml,$msg) { $text = $xml->text; $contact = diaspora_get_contact_by_handle($importer['uid'],$msg['author']); - if(! $contact) + if(! $contact) { + logger('diaspora_comment: cannot find contact: ' . $msg['author']); return; + } if(($contact['rel'] == CONTACT_IS_FOLLOWER) || ($contact['blocked']) || ($contact['readonly'])) { logger('diaspora_comment: Ignoring this author.'); @@ -483,6 +497,15 @@ function diaspora_comment($importer,$xml,$msg) { // NOTREACHED } + $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1", + intval($importer['uid']), + dbesc($guid) + ); + if(count($r)) { + logger('diaspora_comment: our comment just got relayed back to us (or there was a guid collision) : ' . $guid); + return; + } + $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1", intval($importer['uid']), dbesc($parent_guid) @@ -558,9 +581,17 @@ function diaspora_comment($importer,$xml,$msg) { $datarray['author-link'] = $person['url']; $datarray['author-avatar'] = ((x($person,'thumb')) ? $person['thumb'] : $person['photo']); $datarray['body'] = $body; + $datarray['app'] = 'Diaspora'; $message_id = item_store($datarray); + if($message_id) { + q("update item set plink = '%s' where id = %d limit 1", + dbesc($a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $message_id), + intval($message_id) + ); + } + if(! $parent_author_signature) { q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", intval($message_id), @@ -580,6 +611,7 @@ function diaspora_comment($importer,$xml,$msg) { function diaspora_photo($importer,$xml,$msg) { + $a = get_app(); $remote_photo_path = notags(unxmlify($xml->remote_photo_path)); $remote_photo_name = notags(unxmlify($xml->remote_photo_name)); @@ -647,8 +679,10 @@ function diaspora_like($importer,$xml,$msg) { return; $contact = diaspora_get_contact_by_handle($importer['uid'],$msg['author']); - if(! $contact) + if(! $contact) { + logger('diaspora_like: cannot find contact: ' . $msg['author']); return; + } if(($contact['rel'] == CONTACT_IS_FOLLOWER) || ($contact['blocked']) || ($contact['readonly'])) { logger('diaspora_like: Ignoring this author.'); @@ -715,8 +749,8 @@ function diaspora_like($importer,$xml,$msg) { } if($parent_author_signature) { -// $owner_signed_data = $guid . ';' . $parent_guid . ';' . $target_type . ';' . $positive . ';' . $msg['author']; - $owner_signed_data = $guid . ';' . $parent_guid . ';' . $target_type . ';' . $positive . ';' . $diaspora_handle; + + $owner_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle; $parent_author_signature = base64_decode($parent_author_signature); @@ -776,6 +810,8 @@ EOT; $plink = '[url=' . $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $parent_item['id'] . ']' . $post_type . '[/url]'; $arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink ); + $arr['app'] = 'Diaspora'; + $arr['private'] = $parent_item['private']; $arr['verb'] = $activity; $arr['object-type'] = $objtype; @@ -786,6 +822,14 @@ EOT; $message_id = item_store($arr); + + if($message_id) { + q("update item set plink = '%s' where id = %d limit 1", + dbesc($a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $message_id), + intval($message_id) + ); + } + if(! $parent_author_signature) { q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", intval($message_id), @@ -897,11 +941,12 @@ function diaspora_send_status($item,$owner,$contact) { } } - $body = xmlify(bb2diaspora($body)); + $body = xmlify(html_entity_decode(bb2diaspora($body))); + $public = (($item['private']) ? 'false' : 'true'); require_once('include/datetime.php'); - $created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d h:i:s \U\T\C'); + $created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C'); $tpl = get_markup_template('diaspora_post.tpl'); $msg = replace_macros($tpl, array( @@ -953,7 +998,7 @@ function diaspora_send_images($item,$owner,$contact,$images) { '$guid' => xmlify($r[0]['guid']), '$handle' => xmlify($image['handle']), '$public' => xmlify($public), - '$created_at' => xmlify(datetime_convert('UTC','UTC',$r[0]['created'],'Y-m-d h:i:s \U\T\C')) + '$created_at' => xmlify(datetime_convert('UTC','UTC',$r[0]['created'],'Y-m-d H:i:s \U\T\C')) )); @@ -990,7 +1035,7 @@ function diaspora_send_followup($item,$owner,$contact) { $like = false; } - $text = bb2diaspora($item['body']); + $text = html_entity_decode(bb2diaspora($item['body'])); // sign it @@ -1035,14 +1080,6 @@ function diaspora_send_relay($item,$owner,$contact) { else return; - // fetch the original signature - $r = q("select * from sign where iid = %d limit 1", - intval($item['id']) - ); - if(! count($r)) - return; - $orig_sign = $r[0]; - if($item['verb'] === ACTIVITY_LIKE) { $tpl = get_markup_template('diaspora_like_relay.tpl'); $like = true; @@ -1054,15 +1091,60 @@ function diaspora_send_relay($item,$owner,$contact) { $like = false; } - $text = bb2diaspora($item['body']); + $body = $item['body']; + + $text = html_entity_decode(bb2diaspora($body)); + + // fetch the original signature if somebody sent the post to us to relay + // If we are relaying for a reply originating on our own account, there wasn't a 'send to relay' + // action. It wasn't needed. In that case create the original signature and the + // owner (parent author) signature + // comments from other networks will be relayed under our name, with a brief + // preamble to describe what's happening and noting the real author + + $r = q("select * from sign where iid = %d limit 1", + intval($item['id']) + ); + if(count($r)) { + $orig_sign = $r[0]; + $signed_text = $orig_sign['signed_text']; + $authorsig = $orig_sign['signature']; + $handle = $orig_sign['signer']; + } + else { + + $itemcontact = q("select * from contact where `id` = %d limit 1", + intval($item['contact-id']) + ); + if(count($itemcontact)) { + if(! $itemcontact[0]['self']) { + $prefix = sprintf( t('[Relayed] Comment authored by %s from network %s'), + '['. $item['author-name'] . ']' . '(' . $item['author-link'] . ')', + network_to_name($itemcontact['network'])) . "\n"; + $body = $prefix . $body; + } + } + else { + + if($like) + $signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $myaddr; + else + $signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $myaddr; + + $authorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha')); + + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($item['id']), + dbesc($signed_text), + dbesc(base64_encode($authorsig)), + dbesc($myaddr) + ); + $handle = $myaddr; + } + } // sign it - if($like) - $parent_signed_text = $orig_sign['signed_text']; - else - $parent_signed_text = $orig_sign['signed_text']; - $parentauthorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha')); $msg = replace_macros($tpl,array( @@ -1071,18 +1153,11 @@ function diaspora_send_relay($item,$owner,$contact) { '$target_type' =>xmlify($target_type), '$authorsig' => xmlify($orig_sign['signature']), '$parentsig' => xmlify($parentauthorsig), - '$text' => xmlify($text), + '$body' => xmlify($text), '$positive' => xmlify($positive), - '$diaspora_handle' => xmlify($myaddr) + '$handle' => xmlify($handle) )); - // fetch the original signature - $r = q("select * from sign where iid = %d limit 1", - intval($item['id']) - ); - if(! count($r)) - return; - logger('diaspora_relay_comment: base message: ' . $msg, LOGGER_DATA); $slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey']))); diff --git a/include/group.php b/include/group.php index f21ce42e0..8798adf5a 100644 --- a/include/group.php +++ b/include/group.php @@ -154,7 +154,7 @@ $o .= <<< EOT "; diff --git a/include/items.php b/include/items.php index 150be2707..facd8b2d4 100644 --- a/include/items.php +++ b/include/items.php @@ -20,6 +20,8 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) for($x = 2; $x < $a->argc; $x++) { if($a->argv[$x] == 'converse') $converse = true; + if($a->argv[$x] == 'starred') + $starred = true; } } @@ -112,8 +114,10 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`, - `contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid` + `contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`, + `sign`.`signed_text`, `sign`.`signature`, `sign`.`signer` FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` + LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`parent` != 0 AND `item`.`wall` = 1 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' ) @@ -363,6 +367,22 @@ function get_atom_elements($feed,$item) { $res['app'] = 'OStatus'; } + // base64 encoded json structure representing Diaspora signature + + $dsig = $item->get_item_tags(NAMESPACE_DFRN,'diaspora_signature'); + if($dsig) { + $res['dsprsig'] = unxmlify($dsig[0]['data']); + } + + $dguid = $item->get_item_tags(NAMESPACE_DFRN,'diaspora_guid'); + if($dguid) + $res['guid'] = unxmlify($dguid[0]['data']); + + $bm = $item->get_item_tags(NAMESPACE_DFRN,'bookmark'); + if($bm) + $res['bookmark'] = ((unxmlify($bm[0]['data']) === 'true') ? 1 : 0); + + /** * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. */ @@ -659,6 +679,15 @@ function encode_rel_links($links) { function item_store($arr,$force_parent = false) { + // If a Diaspora signature structure was passed in, pull it out of the + // item array and set it aside for later storage. + + $dsprsig = null; + if(x($arr,'dsprsig')) { + $dsprsig = json_decode(base64_decode($arr['dsprsig'])); + unset($arr['dsprsig']); + } + if($arr['gravity']) $arr['gravity'] = intval($arr['gravity']); elseif($arr['parent-uri'] == $arr['uri']) @@ -708,6 +737,7 @@ function item_store($arr,$force_parent = false) { $arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : ''); $arr['deny_gid'] = ((x($arr,'deny_gid')) ? trim($arr['deny_gid']) : ''); $arr['private'] = ((x($arr,'private')) ? intval($arr['private']) : 0 ); + $arr['bookmark'] = ((x($arr,'bookmark')) ? intval($arr['bookmark']) : 0 ); $arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : ''); $arr['tag'] = ((x($arr,'tag')) ? notags(trim($arr['tag'])) : ''); $arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : ''); @@ -835,6 +865,16 @@ function item_store($arr,$force_parent = false) { intval($current_post) ); + if($dsprsig) { + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($current_post), + dbesc($dsprsig->signed_text), + dbesc($dsprsig->signature), + dbesc($dsprsig->signer) + ); + } + + /** * If this is now the last-child, force all _other_ children of this parent to *not* be last-child */ @@ -894,7 +934,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if(! $curl_stat) return(-1); // timed out - logger('dfrn_deliver: ' . $xml); + logger('dfrn_deliver: ' . $xml, LOGGER_DATA); if(! $xml) return 3; @@ -958,7 +998,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { $key = substr(random_string(),0,16); $data = bin2hex(aes_encrypt($postvars['data'],$key)); $postvars['data'] = $data; - logger('rino: sent key = ' . $key); + logger('rino: sent key = ' . $key, LOGGER_DEBUG); if($dfrn_version >= 2.1) { @@ -1670,10 +1710,21 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { $o .= '1' . "\r\n"; if($item['extid']) - $o .= '' . $item['extid'] . '' . "\r\n"; + $o .= '' . xmlify($item['extid']) . '' . "\r\n"; + if($item['bookmark']) + $o .= 'true' . "\r\n"; if($item['app']) - $o .= ''; + $o .= '' . "\r\n"; + + if($item['guid']) + $o .= '' . $item['guid'] . '' . "\r\n"; + + if($item['signed_text']) { + $sign = base64_encode(json_encode(array('signed_text' => $item['signed_text'],'signature' => $item['signature'],'signer' => $item['signer']))); + $o .= '' . xmlify($sign) . '' . "\r\n"; + } + $verb = construct_verb($item); $o .= '' . xmlify($verb) . '' . "\r\n"; $actobj = construct_activity_object($item); diff --git a/include/nav.php b/include/nav.php index f9e72bda7..b290a8da2 100644 --- a/include/nav.php +++ b/include/nav.php @@ -81,7 +81,7 @@ function nav(&$a) { if(! get_config('system','hide_help')) $nav['help'] = array($help_url, t('Help'), "", t('Help and documentation')); - if($a->apps) + if(count($a->apps)>0) $nav['apps'] = array('apps', t('Apps'), "", t('Addon applications, utilities, games')); $nav['search'] = array('search', t('Search'), "", t('Search site content')); @@ -158,6 +158,7 @@ function nav(&$a) { '$emptynotifications' => t('Nothing new here'), '$userinfo' => $userinfo, '$sel' => $a->nav_sel, + '$apps' => $a->apps, )); call_hooks('page_header', $a->page['nav']); diff --git a/include/network.php b/include/network.php index 691a8c9f9..2832ae2d3 100644 --- a/include/network.php +++ b/include/network.php @@ -9,37 +9,37 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0) { $a = get_app(); - $ch = curl_init($url); + $ch = @curl_init($url); if(($redirects > 8) || (! $ch)) return false; - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); - curl_setopt($ch, CURLOPT_USERAGENT, "Friendika"); + @curl_setopt($ch, CURLOPT_HEADER, true); + @curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); + @curl_setopt($ch, CURLOPT_USERAGENT, "Friendika"); if(intval($timeout)) { - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); + @curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); } else { $curl_time = intval(get_config('system','curl_timeout')); - curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60)); + @curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60)); } // by default we will allow self-signed certs // but you can override this $check_cert = get_config('system','verifyssl'); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false)); + @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false)); $prx = get_config('system','proxy'); if(strlen($prx)) { - curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); - curl_setopt($ch, CURLOPT_PROXY, $prx); - $prxusr = get_config('system','proxyuser'); + @curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); + @curl_setopt($ch, CURLOPT_PROXY, $prx); + $prxusr = @get_config('system','proxyuser'); if(strlen($prxusr)) - curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr); + @curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr); } if($binary) - curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); + @curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); $a->set_curl_code(0); @@ -49,7 +49,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0) { $s = @curl_exec($ch); $base = $s; - $curl_info = curl_getinfo($ch); + $curl_info = @curl_getinfo($ch); $http_code = $curl_info['http_code']; $header = ''; @@ -80,7 +80,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0) { $a->set_curl_headers($header); - curl_close($ch); + @curl_close($ch); return($body); }} diff --git a/include/notifier.php b/include/notifier.php index e92a4f6a8..6ac882c19 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -1,6 +1,21 @@ $birthday )); - if($cmd === 'mail') { + if($mail) { $public_message = false; // mail is not public $body = fix_private_photos($item['body'],$owner['uid']); @@ -286,7 +310,7 @@ function notifier_run($argv, $argc){ '$parent_id' => xmlify($item['parent-uri']) )); } - elseif($cmd === 'suggest') { + elseif($fsuggest) { $public_message = false; // suggestions are not public $sugg_template = get_markup_template('atom_suggest.tpl'); @@ -374,17 +398,43 @@ function notifier_run($argv, $argc){ dbesc($recip_str) ); - // delivery loop require_once('include/salmon.php'); + $interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval'))); + + // delivery loop + if(count($r)) { + + foreach($r as $contact) { + if((! $mail) && (! $fsuggest) && (! $followup) && (! $contact['self'])) { + q("insert into deliverq ( `cmd`,`item`,`contact` ) values ('%s', %d, %d )", + dbesc($cmd), + intval($item_id), + intval($contact['id']) + ); + } + } + foreach($r as $contact) { if($contact['self']) continue; + // potentially more than one recipient. Start a new process and space them out a bit. + // we will deliver single recipient types of message and email receipients here. + + if((! $mail) && (! $fsuggest) && (! $followup)) { + proc_run('php','include/delivery.php',$cmd,$item_id,$contact['id']); + if($interval) + @time_sleep_until(microtime(true) + (float) $interval); + continue; + } + $deliver_status = 0; + logger("main delivery by notifier: followup=$followup mail=$mail fsuggest=$fsuggest"); + switch($contact['network']) { case NETWORK_DFRN: logger('notifier: dfrndelivery: ' . $contact['name']); @@ -558,7 +608,8 @@ function notifier_run($argv, $argc){ diaspora_send_relay($target_item,$owner,$contact); break; } - elseif($top_level) { + elseif(($top_level) && (! $walltowall)) { + // currently no workable solution for sending walltowall diaspora_send_status($target_item,$owner,$contact); break; } @@ -589,54 +640,33 @@ function notifier_run($argv, $argc){ } } - if((strlen($hub)) && ($public_message)) { - $hubs = explode(',', $hub); - if(count($hubs)) { - foreach($hubs as $h) { - $h = trim($h); - if(! strlen($h)) - continue; - $params = 'hub.mode=publish&hub.url=' . urlencode($a->get_baseurl() . '/dfrn_poll/' . $owner['nickname'] ); - post_url($h,$params); - logger('pubsub: publish: ' . $h . ' ' . $params . ' returned ' . $a->get_curl_code()); - if(count($hubs) > 1) - sleep(7); // try and avoid multiple hubs responding at precisely the same time - } - } - } if($public_message) { - /** - * - * If you have less than 999 dfrn friends and it's a public message, - * we'll just go ahead and push them out securely with dfrn/rino or Diaspora. - * If you've got more than that, you'll have to rely on PuSH delivery. - * - */ - - $max_allowed = ((get_config('system','maxpubdeliver') === false) ? 999 : intval(get_config('system','maxpubdeliver'))); - - /** - * - * Only get the bare essentials and go back for the full record. - * If you've got a lot of friends and we grab all the details at once it could exhaust memory. - * - */ - $r = q("SELECT `id`, `name` FROM `contact` WHERE `network` in ('%s','%s') AND `uid` = %d AND `blocked` = 0 AND `pending` = 0 - AND `rel` != %d ", + AND `rel` != %d order by rand() ", dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), intval($owner['uid']), intval(CONTACT_IS_SHARING) ); - if((count($r)) && (($max_allowed == 0) || (count($r) < $max_allowed))) { - + if(count($r)) { logger('pubdeliver: ' . print_r($r,true)); + // throw everything into the queue in case we get killed + + foreach($r as $rr) { + if((! $mail) && (! $fsuggest) && (! $followup)) { + q("insert into deliverq ( `cmd`,`item`,`contact` ) values ('%s', %d, %d )", + dbesc($cmd), + intval($item_id), + intval($rr['id']) + ); + } + } + foreach($r as $rr) { /* Don't deliver to folks who have already been delivered to */ @@ -646,63 +676,32 @@ function notifier_run($argv, $argc){ continue; } - $n = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", - intval($rr['id']) - ); - - if(count($n)) { - $contact = $n[0]; - logger('pubdeliver: network: ' . $contact['network']); - - switch($contact['network']) { - case NETWORK_DFRN : - logger('notifier: dfrnpubdelivery: ' . $contact['name']); - $deliver_status = dfrn_deliver($owner,$contact,$atom); - break; - case NETWORK_DIASPORA : - require_once('include/diaspora.php'); - - logger('notifier: diaspora pubdelivery: ' . $contact['name']); - - if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode)) { - logger('notifier: diaspora pubdelivery not allowed at this time'); - break; - } - - if(! $contact['pubkey']) { - logger('notifier: diaspora pubdelivery: no pubkey'); - break; - } - - if($target_item['verb'] === ACTIVITY_DISLIKE) { - // unsupported - break; - } - elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) { - // diaspora delete, - diaspora_send_retraction($target_item,$owner,$contact); - break; - } - elseif($followup) { - // send comments, likes and retractions of likes to owner to relay - diaspora_send_followup($target_item,$owner,$contact); - break; - } - elseif($target_item['parent'] != $target_item['id']) { - // we are the relay - send comments, likes and unlikes to our conversants - diaspora_send_relay($target_item,$owner,$contact); - break; - } - elseif($top_level) { - diaspora_send_status($target_item,$owner,$contact); - break; - } - default: - break; - } + if((! $mail) && (! $fsuggest) && (! $followup)) { + logger('notifier: delivery agent: ' . $rr['name'] . ' ' . $rr['id']); + proc_run('php','include/delivery.php',$cmd,$item_id,$rr['id']); + if($interval) + @time_sleep_until(microtime(true) + (float) $interval); } } } + + + if(strlen($hub)) { + $hubs = explode(',', $hub); + if(count($hubs)) { + foreach($hubs as $h) { + $h = trim($h); + if(! strlen($h)) + continue; + $params = 'hub.mode=publish&hub.url=' . urlencode($a->get_baseurl() . '/dfrn_poll/' . $owner['nickname'] ); + post_url($h,$params); + logger('pubsub: publish: ' . $h . ' ' . $params . ' returned ' . $a->get_curl_code()); + if(count($hubs) > 1) + sleep(7); // try and avoid multiple hubs responding at precisely the same time + } + } + } + } return; diff --git a/include/queue.php b/include/queue.php index f1bcf2e9f..5119a65d8 100644 --- a/include/queue.php +++ b/include/queue.php @@ -3,18 +3,18 @@ require_once("boot.php"); require_once('include/queue_fn.php'); function queue_run($argv, $argc){ - global $a, $db; + global $a, $db; - if(is_null($a)){ - $a = new App; - } + if(is_null($a)){ + $a = new App; + } - if(is_null($db)){ - @include(".htconfig.php"); - require_once("dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; + if(is_null($db)){ + @include(".htconfig.php"); + require_once("dba.php"); + $db = new dba($db_host, $db_user, $db_pass, $db_data); + unset($db_host, $db_user, $db_pass, $db_data); + }; require_once("session.php"); @@ -38,6 +38,18 @@ function queue_run($argv, $argc){ logger('queue: start'); + $interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval'))); + + $r = q("select * from deliverq where 1"); + if(count($r)) { + foreach($r as $rr) { + logger('queue: deliverq'); + proc_run('php','include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']); + if($interval) + @time_sleep_until(microtime(true) + (float) $interval); + } + } + $r = q("SELECT `queue`.*, `contact`.`name`, `contact`.`uid` FROM `queue` LEFT JOIN `contact` ON `queue`.`cid` = `contact`.`id` WHERE `queue`.`created` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); diff --git a/include/text.php b/include/text.php index 66447069e..78eae145e 100644 --- a/include/text.php +++ b/include/text.php @@ -539,22 +539,30 @@ function contact_block() { $total = intval($r[0]['total']); } if(! $total) { - $o .= '

    ' . t('No contacts') . '

    '; - return $o; - } - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 ORDER BY RAND() LIMIT %d", - intval($a->profile['uid']), - intval($shown) - ); - if(count($r)) { - $o .= '

    ' . sprintf( tt('%d Contact','%d Contacts', $total),$total) . '

    '; - foreach($r as $rr) { - $o .= micropro($rr,true,'mpfriend'); - } - $o .= '
    '; - $o .= '
    ' . t('View Contacts') . '
    '; + $contacts = t('No contacts'); + $micropro = Null; + } else { + $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 ORDER BY RAND() LIMIT %d", + intval($a->profile['uid']), + intval($shown) + ); + if(count($r)) { + $contacts = sprintf( tt('%d Contact','%d Contacts', $total),$total); + $micropro = Array(); + foreach($r as $rr) { + $micropro[] = micropro($rr,true,'mpfriend'); + } + } } + + $tpl = get_markup_template('contact_block.tpl'); + $o = replace_macros($tpl, array( + '$contacts' => $contacts, + '$nickname' => $a->profile['nickname'], + '$viewcontacts' => t('View Contacts'), + '$micropro' => $micropro, + )); $arr = array('contacts' => $r, 'output' => $o); @@ -602,12 +610,14 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) { if(! function_exists('search')) { -function search($s,$id='search-box',$url='/search') { +function search($s,$id='search-box',$url='/search',$save = false) { $a = get_app(); $o = '
    '; $o .= '
    '; $o .= ''; $o .= ''; + if($save) + $o .= ''; $o .= '
    '; return $o; }} diff --git a/index.php b/index.php index 51c87cae6..3db8170ef 100644 --- a/index.php +++ b/index.php @@ -112,10 +112,10 @@ if(! x($_SESSION,'authenticated')) header('X-Account-Management-Status: none'); if(! x($_SESSION,'sysmsg')) - $_SESSION['sysmsg'] = ''; + $_SESSION['sysmsg'] = array(); if(! x($_SESSION,'sysmsg_info')) - $_SESSION['sysmsg_info'] = ''; + $_SESSION['sysmsg_info'] = array(); /* * check_config() is responsible for running update scripts. These automatically @@ -262,7 +262,7 @@ if(isset($homebase)) // now that we've been through the module content, see if the page reported // a permission problem and if so, a 403 response would seem to be in order. -if(stristr($_SESSION['sysmsg'], t('Permission denied'))) { +if(stristr( implode("",$_SESSION['sysmsg']), t('Permission denied'))) { header($_SERVER["SERVER_PROTOCOL"] . ' 403 ' . t('Permission denied.')); } @@ -272,7 +272,7 @@ if(stristr($_SESSION['sysmsg'], t('Permission denied'))) { * */ -if(x($_SESSION,'sysmsg')) { +/*if(x($_SESSION,'sysmsg')) { $a->page['content'] = "
    {$_SESSION['sysmsg']}
    \r\n" . ((x($a->page,'content')) ? $a->page['content'] : ''); $_SESSION['sysmsg']=""; @@ -283,7 +283,7 @@ if(x($_SESSION,'sysmsg_info')) { . ((x($a->page,'content')) ? $a->page['content'] : ''); $_SESSION['sysmsg_info']=""; unset($_SESSION['sysmsg_info']); -} +}*/ diff --git a/include/acl.js b/js/acl.js similarity index 100% rename from include/acl.js rename to js/acl.js diff --git a/include/ajaxupload.js b/js/ajaxupload.js similarity index 100% rename from include/ajaxupload.js rename to js/ajaxupload.js diff --git a/include/country.js b/js/country.js similarity index 100% rename from include/country.js rename to js/country.js diff --git a/include/jquery.htmlstream.js b/js/jquery.htmlstream.js similarity index 100% rename from include/jquery.htmlstream.js rename to js/jquery.htmlstream.js diff --git a/include/jquery.js b/js/jquery.js similarity index 100% rename from include/jquery.js rename to js/jquery.js diff --git a/include/main.js b/js/main.js similarity index 95% rename from include/main.js rename to js/main.js index 83dcc720c..328b1f231 100644 --- a/include/main.js +++ b/js/main.js @@ -34,7 +34,16 @@ msie = $.browser.msie ; - /* setup navbar menus */ + /* setup tooltips */ + $("a,.tt").each(function(){ + var e = $(this); + var pos="bottom"; + if (e.hasClass("tttop")) pos="top"; + if (e.hasClass("ttbottom")) pos="bottom"; + if (e.hasClass("ttleft")) pos="left"; + if (e.hasClass("ttright")) pos="right"; + e.tipTip({defaultPosition: pos}); + }); @@ -103,6 +112,16 @@ if(notif == 0) { notif = ''; $('#notify-update').removeClass('show') } else { $('#notify-update').addClass('show') } $('#notify-update').html(notif); + var eSysmsg = $(data).find('sysmsgs'); + eSysmsg.children("notice").each(function(){ + text = $(this).text(); + $.jGrowl(text, { sticky: true, theme: 'notice' }); + }); + eSysmsg.children("info").each(function(){ + text = $(this).text(); + $.jGrowl(text, { sticky: false, theme: 'info' }); + }); + }); diff --git a/library/jgrowl/README b/library/jgrowl/README new file mode 100644 index 000000000..3c94f7508 --- /dev/null +++ b/library/jgrowl/README @@ -0,0 +1,3 @@ +http://stanlemon.net/projects/jgrowl.html + +jGrowl is free and open source, it's distributed under the MIT and GPL licenses diff --git a/library/jgrowl/jquery.jgrowl.css b/library/jgrowl/jquery.jgrowl.css new file mode 100755 index 000000000..b4deb978c --- /dev/null +++ b/library/jgrowl/jquery.jgrowl.css @@ -0,0 +1,136 @@ + +div.jGrowl { + z-index: 9999; + color: #fff; + font-size: 12px; +} + +/** Special IE6 Style Positioning **/ +div.ie6 { + position: absolute; +} + +div.ie6.top-right { + right: auto; + bottom: auto; + left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); +} + +div.ie6.top-left { + left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); +} + +div.ie6.bottom-right { + left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); +} + +div.ie6.bottom-left { + left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); +} + +div.ie6.center { + left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' ); + top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' ); + width: 100%; +} + +/** Normal Style Positions **/ +div.jGrowl { + position: absolute; +} + +body > div.jGrowl { + position: fixed; +} + +div.jGrowl.top-left { + left: 0px; + top: 0px; +} + +div.jGrowl.top-right { + right: 0px; + top: 0px; +} + +div.jGrowl.bottom-left { + left: 0px; + bottom: 0px; +} + +div.jGrowl.bottom-right { + right: 0px; + bottom: 0px; +} + +div.jGrowl.center { + top: 0px; + width: 50%; + left: 25%; +} + +/** Cross Browser Styling **/ +div.center div.jGrowl-notification, div.center div.jGrowl-closer { + margin-left: auto; + margin-right: auto; +} + +div.jGrowl div.jGrowl-notification, div.jGrowl div.jGrowl-closer { + background-color: #000; + opacity: .85; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=85); + zoom: 1; + width: 235px; + padding: 10px; + margin-top: 5px; + margin-bottom: 5px; + font-family: Tahoma, Arial, Helvetica, sans-serif; + font-size: 1em; + text-align: left; + display: none; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +div.jGrowl div.jGrowl-notification { + min-height: 40px; +} + +div.jGrowl div.jGrowl-notification, +div.jGrowl div.jGrowl-closer { + margin: 10px; +} + +div.jGrowl div.jGrowl-notification div.jGrowl-header { + font-weight: bold; + font-size: .85em; +} + +div.jGrowl div.jGrowl-notification div.jGrowl-close { + z-index: 99; + float: right; + font-weight: bold; + font-size: 1em; + cursor: pointer; +} + +div.jGrowl div.jGrowl-closer { + padding-top: 4px; + padding-bottom: 4px; + cursor: pointer; + font-size: .9em; + font-weight: bold; + text-align: center; +} + +/** Hide jGrowl when printing **/ +@media print { + div.jGrowl { + display: none; + } +} diff --git a/library/jgrowl/jquery.jgrowl_minimized.js b/library/jgrowl/jquery.jgrowl_minimized.js new file mode 100644 index 000000000..782898098 --- /dev/null +++ b/library/jgrowl/jquery.jgrowl_minimized.js @@ -0,0 +1,11 @@ +(function($){$.jGrowl=function(m,o){if($('#jGrowl').size()==0) +$('
    ').addClass((o&&o.position)?o.position:$.jGrowl.defaults.position).appendTo('body');$('#jGrowl').jGrowl(m,o);};$.fn.jGrowl=function(m,o){if($.isFunction(this.each)){var args=arguments;return this.each(function(){var self=this;if($(this).data('jGrowl.instance')==undefined){$(this).data('jGrowl.instance',$.extend(new $.fn.jGrowl(),{notifications:[],element:null,interval:null}));$(this).data('jGrowl.instance').startup(this);} +if($.isFunction($(this).data('jGrowl.instance')[m])){$(this).data('jGrowl.instance')[m].apply($(this).data('jGrowl.instance'),$.makeArray(args).slice(1));}else{$(this).data('jGrowl.instance').create(m,o);}});};};$.extend($.fn.jGrowl.prototype,{defaults:{pool:0,header:'',group:'',sticky:false,position:'top-right',glue:'after',theme:'default',themeState:'highlight',corners:'10px',check:250,life:3000,closeDuration:'normal',openDuration:'normal',easing:'swing',closer:true,closeTemplate:'×',closerTemplate:'
    [ close all ]
    ',log:function(e,m,o){},beforeOpen:function(e,m,o){},afterOpen:function(e,m,o){},open:function(e,m,o){},beforeClose:function(e,m,o){},close:function(e,m,o){},animateOpen:{opacity:'show'},animateClose:{opacity:'hide'}},notifications:[],element:null,interval:null,create:function(message,o){var o=$.extend({},this.defaults,o);if(typeof o.speed!=='undefined'){o.openDuration=o.speed;o.closeDuration=o.speed;} +this.notifications.push({message:message,options:o});o.log.apply(this.element,[this.element,message,o]);},render:function(notification){var self=this;var message=notification.message;var o=notification.options;var notification=$('
    '+'
    '+o.closeTemplate+'
    '+'
    '+o.header+'
    '+'
    '+message+'
    ').data("jGrowl",o).addClass(o.theme).children('div.jGrowl-close').bind("click.jGrowl",function(){$(this).parent().trigger('jGrowl.close');}).parent();$(notification).bind("mouseover.jGrowl",function(){$('div.jGrowl-notification',self.element).data("jGrowl.pause",true);}).bind("mouseout.jGrowl",function(){$('div.jGrowl-notification',self.element).data("jGrowl.pause",false);}).bind('jGrowl.beforeOpen',function(){if(o.beforeOpen.apply(notification,[notification,message,o,self.element])!=false){$(this).trigger('jGrowl.open');}}).bind('jGrowl.open',function(){if(o.open.apply(notification,[notification,message,o,self.element])!=false){if(o.glue=='after'){$('div.jGrowl-notification:last',self.element).after(notification);}else{$('div.jGrowl-notification:first',self.element).before(notification);} +$(this).animate(o.animateOpen,o.openDuration,o.easing,function(){if($.browser.msie&&(parseInt($(this).css('opacity'),10)===1||parseInt($(this).css('opacity'),10)===0)) +this.style.removeAttribute('filter');if($(this).data("jGrowl")!=null) +$(this).data("jGrowl").created=new Date();$(this).trigger('jGrowl.afterOpen');});}}).bind('jGrowl.afterOpen',function(){o.afterOpen.apply(notification,[notification,message,o,self.element]);}).bind('jGrowl.beforeClose',function(){if(o.beforeClose.apply(notification,[notification,message,o,self.element])!=false) +$(this).trigger('jGrowl.close');}).bind('jGrowl.close',function(){$(this).data('jGrowl.pause',true);$(this).animate(o.animateClose,o.closeDuration,o.easing,function(){if($.isFunction(o.close)){if(o.close.apply(notification,[notification,message,o,self.element])!==false) +$(this).remove();}else{$(this).remove();}});}).trigger('jGrowl.beforeOpen');if(o.corners!=''&&$.fn.corner!=undefined)$(notification).corner(o.corners);if($('div.jGrowl-notification:parent',self.element).size()>1&&$('div.jGrowl-closer',self.element).size()==0&&this.defaults.closer!=false){$(this.defaults.closerTemplate).addClass('jGrowl-closer ui-state-highlight ui-corner-all').addClass(this.defaults.theme).appendTo(self.element).animate(this.defaults.animateOpen,this.defaults.speed,this.defaults.easing).bind("click.jGrowl",function(){$(this).siblings().trigger("jGrowl.beforeClose");if($.isFunction(self.defaults.closer)){self.defaults.closer.apply($(this).parent()[0],[$(this).parent()[0]]);}});};},update:function(){$(this.element).find('div.jGrowl-notification:parent').each(function(){if($(this).data("jGrowl")!=undefined&&$(this).data("jGrowl").created!=undefined&&($(this).data("jGrowl").created.getTime()+parseInt($(this).data("jGrowl").life))<(new Date()).getTime()&&$(this).data("jGrowl").sticky!=true&&($(this).data("jGrowl.pause")==undefined||$(this).data("jGrowl.pause")!=true)){$(this).trigger('jGrowl.beforeClose');}});if(this.notifications.length>0&&(this.defaults.pool==0||$(this.element).find('div.jGrowl-notification:parent').size()');this.interval=setInterval(function(){$(e).data('jGrowl.instance').update();},parseInt(this.defaults.check));if($.browser.msie&&parseInt($.browser.version)<7&&!window["XMLHttpRequest"]){$(this.element).addClass('ie6');}},shutdown:function(){$(this.element).removeClass('jGrowl').find('div.jGrowl-notification').remove();clearInterval(this.interval);},close:function(){$(this.element).find('div.jGrowl-notification').each(function(){$(this).trigger('jGrowl.beforeClose');});}});$.jGrowl.defaults=$.fn.jGrowl.prototype.defaults;})(jQuery); \ No newline at end of file diff --git a/library/stanlemon-jgrowl-tip.tar.gz b/library/stanlemon-jgrowl-tip.tar.gz new file mode 100644 index 000000000..07a5fb097 Binary files /dev/null and b/library/stanlemon-jgrowl-tip.tar.gz differ diff --git a/library/tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin_src.js b/library/tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin_src.js index db676cd90..789e75c39 100644 --- a/library/tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin_src.js +++ b/library/tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin_src.js @@ -70,6 +70,7 @@ // example: to [b] + rep(/(.*?)<\/a>/gi,"[bookmark=$1]$2[/bookmark]"); rep(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"); rep(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"); rep(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"); @@ -119,6 +120,7 @@ rep(/\[\/i\]/gi,""); rep(/\[u\]/gi,""); rep(/\[\/u\]/gi,""); + rep(/\[bookmark=([^\]]+)\](.*?)\[\/bookmark\]/gi,"$2"); rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,"$2"); rep(/\[url\](.*?)\[\/url\]/gi,"$1"); rep(/\[img=(.*?)x(.*?)\](.*?)\[\/img\]/gi,""); diff --git a/library/tiptip/README b/library/tiptip/README new file mode 100644 index 000000000..a83cfba3e --- /dev/null +++ b/library/tiptip/README @@ -0,0 +1,30 @@ +http://code.drewwilson.com/entry/tiptip-jquery-plugin + +License +This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses. + + +ChangeLog +Version 1.3 (Mar. 23, 2010) + + Added defaultPoistion option that enables you to set the default orientation TipTip should show up as. + Added attribute option that enables you to set the HTML attribute that TipTip should pull it's content from. + Added content option. This will be used as the content for the TipTip and will overwrite any content pulled form any HTML attribute. + Added activation option enables you to specify the jQuery method TipTip is activated with: hover, focus or click. Now you can use TipTip on forms and for validation! + Added keepAlive option that when set to true the TipTip will only fadeout when you hover over the actual TipTip and then hover off of it. Allowing for hyperlinks inside your TipTip content to be accessible. + +Version 1.2 (Jan. 13, 2010) + + Added HTML support with Tip Tip. You can now add HTML into the Title attribute (though this is not recommended if you want strictly valid code). + Tightened up spacing margins in JS. + Updated margins in CSS file. + +Version 1.1 (Jan. 03, 2010) + + Swapped dynamically added orientation CSS class names ('_left' & '_right') to make better sense. + Added in some tighter spacing for the tooltip in JS. + +Version 1.0 (Jan. 02, 2010) + + Initial release. + diff --git a/library/tiptip/jquery.tipTip.minified.js b/library/tiptip/jquery.tipTip.minified.js new file mode 100644 index 000000000..cdf3a892b --- /dev/null +++ b/library/tiptip/jquery.tipTip.minified.js @@ -0,0 +1,21 @@ + /* + * TipTip + * Copyright 2010 Drew Wilson + * www.drewwilson.com + * code.drewwilson.com/entry/tiptip-jquery-plugin + * + * Version 1.3 - Updated: Mar. 23, 2010 + * + * This Plug-In will create a custom tooltip to replace the default + * browser tooltip. It is extremely lightweight and very smart in + * that it detects the edges of the browser window and will make sure + * the tooltip stays within the current window size. As a result the + * tooltip will adjust itself to be displayed above, below, to the left + * or to the right depending on what is necessary to stay within the + * browser window. It is completely customizable as well via CSS. + * + * This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function($){$.fn.tipTip=function(options){var defaults={activation:"hover",keepAlive:false,maxWidth:"200px",edgeOffset:3,defaultPosition:"bottom",delay:400,fadeIn:200,fadeOut:200,attribute:"title",content:false,enter:function(){},exit:function(){}};var opts=$.extend(defaults,options);if($("#tiptip_holder").length<=0){var tiptip_holder=$('
    ');var tiptip_content=$('
    ');var tiptip_arrow=$('
    ');$("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('
    ')))}else{var tiptip_holder=$("#tiptip_holder");var tiptip_content=$("#tiptip_content");var tiptip_arrow=$("#tiptip_arrow")}return this.each(function(){var org_elem=$(this);if(opts.content){var org_title=opts.content}else{var org_title=org_elem.attr(opts.attribute)}if(org_title!=""){if(!opts.content){org_elem.removeAttr(opts.attribute)}var timeout=false;if(opts.activation=="hover"){org_elem.hover(function(){active_tiptip()},function(){if(!opts.keepAlive){deactive_tiptip()}});if(opts.keepAlive){tiptip_holder.hover(function(){},function(){deactive_tiptip()})}}else if(opts.activation=="focus"){org_elem.focus(function(){active_tiptip()}).blur(function(){deactive_tiptip()})}else if(opts.activation=="click"){org_elem.click(function(){active_tiptip();return false}).hover(function(){},function(){if(!opts.keepAlive){deactive_tiptip()}});if(opts.keepAlive){tiptip_holder.hover(function(){},function(){deactive_tiptip()})}}function active_tiptip(){opts.enter.call(this);tiptip_content.html(org_title);tiptip_holder.hide().removeAttr("class").css("margin","0");tiptip_arrow.removeAttr("style");var top=parseInt(org_elem.offset()['top']);var left=parseInt(org_elem.offset()['left']);var org_width=parseInt(org_elem.outerWidth());var org_height=parseInt(org_elem.outerHeight());var tip_w=tiptip_holder.outerWidth();var tip_h=tiptip_holder.outerHeight();var w_compare=Math.round((org_width-tip_w)/2);var h_compare=Math.round((org_height-tip_h)/2);var marg_left=Math.round(left+w_compare);var marg_top=Math.round(top+org_height+opts.edgeOffset);var t_class="";var arrow_top="";var arrow_left=Math.round(tip_w-12)/2;if(opts.defaultPosition=="bottom"){t_class="_bottom"}else if(opts.defaultPosition=="top"){t_class="_top"}else if(opts.defaultPosition=="left"){t_class="_left"}else if(opts.defaultPosition=="right"){t_class="_right"}var right_compare=(w_compare+left)parseInt($(window).width());if((right_compare&&w_compare<0)||(t_class=="_right"&&!left_compare)||(t_class=="_left"&&left<(tip_w+opts.edgeOffset+5))){t_class="_right";arrow_top=Math.round(tip_h-13)/2;arrow_left=-12;marg_left=Math.round(left+org_width+opts.edgeOffset);marg_top=Math.round(top+h_compare)}else if((left_compare&&w_compare<0)||(t_class=="_left"&&!right_compare)){t_class="_left";arrow_top=Math.round(tip_h-13)/2;arrow_left=Math.round(tip_w);marg_left=Math.round(left-(tip_w+opts.edgeOffset+5));marg_top=Math.round(top+h_compare)}var top_compare=(top+org_height+opts.edgeOffset+tip_h+8)>parseInt($(window).height()+$(window).scrollTop());var bottom_compare=((top+org_height)-(opts.edgeOffset+tip_h+8))<0;if(top_compare||(t_class=="_bottom"&&top_compare)||(t_class=="_top"&&!bottom_compare)){if(t_class=="_top"||t_class=="_bottom"){t_class="_top"}else{t_class=t_class+"_top"}arrow_top=tip_h;marg_top=Math.round(top-(tip_h+5+opts.edgeOffset))}else if(bottom_compare|(t_class=="_top"&&bottom_compare)||(t_class=="_bottom"&&!top_compare)){if(t_class=="_top"||t_class=="_bottom"){t_class="_bottom"}else{t_class=t_class+"_bottom"}arrow_top=-12;marg_top=Math.round(top+org_height+opts.edgeOffset)}if(t_class=="_right_top"||t_class=="_left_top"){marg_top=marg_top+5}else if(t_class=="_right_bottom"||t_class=="_left_bottom"){marg_top=marg_top-5}if(t_class=="_left_top"||t_class=="_left_bottom"){marg_left=marg_left+5}tiptip_arrow.css({"margin-left":arrow_left+"px","margin-top":arrow_top+"px"});tiptip_holder.css({"margin-left":marg_left+"px","margin-top":marg_top+"px"}).attr("class","tip"+t_class);if(timeout){clearTimeout(timeout)}timeout=setTimeout(function(){tiptip_holder.stop(true,true).fadeIn(opts.fadeIn)},opts.delay)}function deactive_tiptip(){opts.exit.call(this);if(timeout){clearTimeout(timeout)}tiptip_holder.fadeOut(opts.fadeOut)}}})}})(jQuery); \ No newline at end of file diff --git a/library/tiptip/tipTip.css b/library/tiptip/tipTip.css new file mode 100644 index 000000000..4fb95d376 --- /dev/null +++ b/library/tiptip/tipTip.css @@ -0,0 +1,113 @@ +/* TipTip CSS - Version 1.2 */ + +#tiptip_holder { + display: none; + position: absolute; + top: 0; + left: 0; + z-index: 99999; +} + +#tiptip_holder.tip_top { + padding-bottom: 5px; +} + +#tiptip_holder.tip_bottom { + padding-top: 5px; +} + +#tiptip_holder.tip_right { + padding-left: 5px; +} + +#tiptip_holder.tip_left { + padding-right: 5px; +} + +#tiptip_content { + font-size: 11px; + color: #fff; + text-shadow: 0 0 2px #000; + padding: 4px 8px; + border: 1px solid rgba(255,255,255,0.25); + background-color: rgb(25,25,25); + background-color: rgba(25,25,25,0.92); + background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(transparent), to(#000)); + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + box-shadow: 0 0 3px #555; + -webkit-box-shadow: 0 0 3px #555; + -moz-box-shadow: 0 0 3px #555; +} + +#tiptip_arrow, #tiptip_arrow_inner { + position: absolute; + border-color: transparent; + border-style: solid; + border-width: 6px; + height: 0; + width: 0; +} + +#tiptip_holder.tip_top #tiptip_arrow { + border-top-color: #fff; + border-top-color: rgba(255,255,255,0.35); +} + +#tiptip_holder.tip_bottom #tiptip_arrow { + border-bottom-color: #fff; + border-bottom-color: rgba(255,255,255,0.35); +} + +#tiptip_holder.tip_right #tiptip_arrow { + border-right-color: #fff; + border-right-color: rgba(255,255,255,0.35); +} + +#tiptip_holder.tip_left #tiptip_arrow { + border-left-color: #fff; + border-left-color: rgba(255,255,255,0.35); +} + +#tiptip_holder.tip_top #tiptip_arrow_inner { + margin-top: -7px; + margin-left: -6px; + border-top-color: rgb(25,25,25); + border-top-color: rgba(25,25,25,0.92); +} + +#tiptip_holder.tip_bottom #tiptip_arrow_inner { + margin-top: -5px; + margin-left: -6px; + border-bottom-color: rgb(25,25,25); + border-bottom-color: rgba(25,25,25,0.92); +} + +#tiptip_holder.tip_right #tiptip_arrow_inner { + margin-top: -6px; + margin-left: -5px; + border-right-color: rgb(25,25,25); + border-right-color: rgba(25,25,25,0.92); +} + +#tiptip_holder.tip_left #tiptip_arrow_inner { + margin-top: -6px; + margin-left: -7px; + border-left-color: rgb(25,25,25); + border-left-color: rgba(25,25,25,0.92); +} + +/* Webkit Hacks */ +@media screen and (-webkit-min-device-pixel-ratio:0) { + #tiptip_content { + padding: 4px 8px 5px 8px; + background-color: rgba(45,45,45,0.88); + } + #tiptip_holder.tip_bottom #tiptip_arrow_inner { + border-bottom-color: rgba(45,45,45,0.88); + } + #tiptip_holder.tip_top #tiptip_arrow_inner { + border-top-color: rgba(20,20,20,0.92); + } +} \ No newline at end of file diff --git a/mod/admin.php b/mod/admin.php index 7799e64ab..da561d554 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -344,7 +344,7 @@ function admin_page_site(&$a) { * Users admin page */ function admin_page_users_post(&$a){ - $pending = ( x(£_POST, 'pending') ? $_POST['pending'] : Array() ); + $pending = ( x($_POST, 'pending') ? $_POST['pending'] : Array() ); $users = ( x($_POST, 'user') ? $_POST['user'] : Array() ); if (x($_POST,'page_users_block')){ @@ -540,7 +540,7 @@ function admin_page_plugins(&$a){ } $admin_form=""; - if (in_array($plugin, $a->plugins_admin)){ + if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)){ @require_once("addon/$plugin/$plugin.php"); $func = $plugin.'_plugin_admin'; $func($a, $admin_form); @@ -632,7 +632,7 @@ function admin_page_logs(&$a){ $f = get_config('system','logfile'); $size = filesize($f); - if($size > 5000000) + if($size > 5000000 || $size < 0) $size = 5000000; $data = ''; diff --git a/mod/apps.php b/mod/apps.php index 7a0a3f59e..8049b45fb 100644 --- a/mod/apps.php +++ b/mod/apps.php @@ -1,15 +1,18 @@ ' . t('Applications') . ''; - - if($a->apps) - $o .= $a->apps; - else + if(count($a->apps)==0) notice( t('No installed applications.') . EOL); - return $o; -} \ No newline at end of file + $tpl = get_markup_template("apps.tpl"); + return replace_macros($tpl, array( + '$title' => $title, + '$apps' => $a->apps, + )); + + + +} diff --git a/mod/contacts.php b/mod/contacts.php index 3b2b16acf..4decc5042 100644 --- a/mod/contacts.php +++ b/mod/contacts.php @@ -87,25 +87,15 @@ function contacts_post(&$a) { $priority = intval($_POST['poll']); - if($priority == (-1)) - if($priority > 5 || $priority < 0) $priority = 0; - $rating = intval($_POST['reputation']); - if($rating > 5 || $rating < 0) - $rating = 0; - - $reason = notags(trim($_POST['reason'])); - $info = escape_tags(trim($_POST['info'])); - $r = q("UPDATE `contact` SET `profile-id` = %d, `priority` = %d , `rating` = %d, `reason` = '%s', `info` = '%s' + $r = q("UPDATE `contact` SET `profile-id` = %d, `priority` = %d , `info` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($profile_id), intval($priority), - intval($rating), - dbesc($reason), dbesc($info), intval($contact_id), intval(local_user()) @@ -277,8 +267,6 @@ function contacts_content(&$a) { $sparkle = ''; } - $grps = ''; - $insecure = '

    ' . t('Privacy Unavailable') . ' ' . t('Private communications are not available for this contact.') . '

    '; @@ -313,7 +301,6 @@ function contacts_content(&$a) { '$lblcrepair' => t("Repair contact URL settings \x28WARNING: Advanced\x29"), '$lblrecent' => t('View conversations'), '$lblsuggest' => $lblsuggest, - '$grps' => $grps, '$delete' => t('Delete contact'), '$nettype' => $nettype, '$poll_interval' => contact_poll_interval($r[0]['priority'],(! $poll_enabled)), @@ -330,9 +317,6 @@ function contacts_content(&$a) { '$info' => $r[0]['info'], '$blocked' => (($r[0]['blocked']) ? '
    ' . t('Currently blocked') . '
    ' : ''), '$ignored' => (($r[0]['readonly']) ? '
    ' . t('Currently ignored') . '
    ' : ''), - '$rating' => contact_reputation($r[0]['rating']), - '$reason' => $r[0]['reason'], - '$groups' => '', // group_selector(), '$photo' => $r[0]['photo'], '$name' => $r[0]['name'], '$dir_icon' => $dir_icon, diff --git a/mod/crepair.php b/mod/crepair.php index 4babd6bf7..afa45e881 100644 --- a/mod/crepair.php +++ b/mod/crepair.php @@ -18,15 +18,16 @@ function crepair_post(&$a) { $contact = $r[0]; - $nick = ((x($_POST,'nick')) ? $_POST['nick'] : null); - $url = ((x($_POST,'url')) ? $_POST['url'] : null); - $request = ((x($_POST,'request')) ? $_POST['request'] : null); - $confirm = ((x($_POST,'confirm')) ? $_POST['confirm'] : null); - $notify = ((x($_POST,'notify')) ? $_POST['notify'] : null); - $poll = ((x($_POST,'poll')) ? $_POST['poll'] : null); + $nick = ((x($_POST,'nick')) ? $_POST['nick'] : ''); + $url = ((x($_POST,'url')) ? $_POST['url'] : ''); + $request = ((x($_POST,'request')) ? $_POST['request'] : ''); + $confirm = ((x($_POST,'confirm')) ? $_POST['confirm'] : ''); + $notify = ((x($_POST,'notify')) ? $_POST['notify'] : ''); + $poll = ((x($_POST,'poll')) ? $_POST['poll'] : ''); + $attag = ((x($_POST,'attag')) ? $_POST['attag'] : ''); - $r = q("UPDATE `contact` SET `nick` = '%s', `url` = '%s', `request` = '%s', `confirm` = '%s', `notify` = '%s', `poll` = '%s' + $r = q("UPDATE `contact` SET `nick` = '%s', `url` = '%s', `request` = '%s', `confirm` = '%s', `notify` = '%s', `poll` = '%s', `attag` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1", dbesc($nick), dbesc($url), @@ -34,6 +35,7 @@ function crepair_post(&$a) { dbesc($confirm), dbesc($notify), dbesc($poll), + dbesc($attag), intval($contact['id']), local_user() ); @@ -84,6 +86,7 @@ function crepair_content(&$a) { $o .= replace_macros($tpl, array( '$label_name' => t('Name'), '$label_nick' => t('Account Nickname'), + '$label_attag' => t('@Tagname - overrides Name/Nickname'), '$label_url' => t('Account URL'), '$label_request' => t('Friend Request URL'), '$label_confirm' => t('Friend Confirm URL'), @@ -97,6 +100,7 @@ function crepair_content(&$a) { '$confirm' => $contact['confirm'], '$notify' => $contact['notify'], '$poll' => $contact['poll'], + '$contact_attag' => $contact['attag'], '$lbl_submit' => t('Submit') )); diff --git a/mod/item.php b/mod/item.php index ef0b232d5..b4ec7666f 100644 --- a/mod/item.php +++ b/mod/item.php @@ -15,6 +15,8 @@ * */ +require_once('include/crypto.php'); + function item_post(&$a) { if((! local_user()) && (! remote_user())) @@ -330,6 +332,15 @@ function item_post(&$a) { } } + // embedded bookmark in post? convert to regular url and set bookmark flag + + $bookmark = 0; + if(preg_match_all("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/m",$body,$match)) { + $bookmark = 1; + $body = preg_replace("/\[bookmark\=([^\]]*)\](.*?)\[\/bookmark\]/m",'[url=$1]$2[/url]',$body); + } + + /** * Fold multi-line [code] sequences */ @@ -351,7 +362,7 @@ function item_post(&$a) { * and we are replying, and there isn't one already */ - if(($parent_contact) && ($parent_contact['network'] === 'stat') + if(($parent_contact) && ($parent_contact['network'] === NETWORK_OSTATUS) && ($parent_contact['nick']) && (! in_array('@' . $parent_contact['nick'],$tags))) { $body = '@' . $parent_contact['nick'] . ' ' . $body; $tags[] = '@' . $parent_contact['nick']; @@ -402,7 +413,8 @@ function item_post(&$a) { ); } else { - $r = q("SELECT * FROM `contact` WHERE `nick` = '%s' AND `uid` = %d LIMIT 1", + $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", + dbesc($name), dbesc($name), intval($profile_uid) ); @@ -506,6 +518,7 @@ function item_post(&$a) { $datarray['private'] = $private; $datarray['pubmail'] = $pubmail_enable; $datarray['attach'] = $attachments; + $datarray['bookmark'] = intval($bookmark); $datarray['thr-parent'] = $thr_parent; /** @@ -548,8 +561,8 @@ function item_post(&$a) { $r = q("INSERT INTO `item` (`guid`, `uid`,`type`,`wall`,`gravity`,`contact-id`,`owner-name`,`owner-link`,`owner-avatar`, `author-name`, `author-link`, `author-avatar`, `created`, `edited`, `received`, `changed`, `uri`, `thr-parent`, `title`, `body`, `app`, `location`, `coord`, - `tag`, `inform`, `verb`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private`, `pubmail`, `attach` ) - VALUES( '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s' )", + `tag`, `inform`, `verb`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private`, `pubmail`, `attach`, `bookmark` ) + VALUES( '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d )", dbesc($datarray['guid']), intval($datarray['uid']), dbesc($datarray['type']), @@ -582,7 +595,8 @@ function item_post(&$a) { dbesc($datarray['deny_gid']), intval($datarray['private']), intval($datarray['pubmail']), - dbesc($datarray['attach']) + dbesc($datarray['attach']), + intval($datarray['bookmark']) ); $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' LIMIT 1", @@ -674,6 +688,27 @@ function item_post(&$a) { pop_lang(); } + + // We won't be able to sign Diaspora comments for authenticated visitors - we don't have their private key + + if($self) { + require_once('include/bb2diaspora.php'); + $signed_body = html_entity_decode(bb2diaspora($datarray['body'])); + $myaddr = $a->user['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3); + if($datarray['verb'] === ACTIVITY_LIKE) + $signed_text = $datarray['guid'] . ';' . 'Post' . ';' . $parent_item['guid'] . ';' . 'true' . ';' . $myaddr; + else + $signed_text = $datarray['guid'] . ';' . $parent_item['guid'] . ';' . $signed_body . ';' . $myaddr; + + $authorsig = base64_encode(rsa_sign($signed_text,$a->user['prvkey'],'sha')); + + q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ", + intval($post_id), + dbesc($signed_text), + dbesc(base64_encode($authorsig)), + dbesc($myaddr) + ); + } } else { $parent = $post_id; @@ -799,6 +834,12 @@ function item_post(&$a) { } } + + + + + + logger('post_complete'); // figure out how to return, depending on from whence we came diff --git a/mod/localtime.php b/mod/localtime.php new file mode 100644 index 000000000..f5ecf3a96 --- /dev/null +++ b/mod/localtime.php @@ -0,0 +1,44 @@ +data['mod-localtime'] = datetime_convert('UTC',$_POST['timezone'],$t,$bd_format); + +} + +function localtime_content(&$a) { + $t = $_REQUEST['time']; + if(! $t) + $t = 'now'; + + $o .= '

    ' . t('Time Conversion') . '

    '; + + $o .= '

    ' . t('Friendika provides this service for sharing events with other networks and friends in unknown timezones.') . '

    '; + + + if(x($a->data,'mod-localtime')) + $o .= '

    ' . sprintf( t('Converted localtime: %s'),$a->data['mod-localtime']) . '

    '; + + $o .= '

    ' . sprintf( t('UTC time: %s'), $t) . '

    '; + + $o .= '
    '; + + $o .= '

    ' . t('Please select your timezone:') . '

    '; + + $o .= select_timezone(); + + $o .= '
    '; + + return $o; + +} \ No newline at end of file diff --git a/mod/network.php b/mod/network.php index cf4c994f0..3c8125303 100644 --- a/mod/network.php +++ b/mod/network.php @@ -14,10 +14,31 @@ function network_init(&$a) { $a->page['aside'] = ''; $search = ((x($_GET,'search')) ? escape_tags($_GET['search']) : ''); - $srchurl = '/network' . ((x($_GET,'cid')) ? '?cid=' . $_GET['cid'] : '') . ((x($_GET,'star')) ? '?star=' . $_GET['star'] : ''); + $srchurl = '/network' + . ((x($_GET,'cid')) ? '?cid=' . $_GET['cid'] : '') + . ((x($_GET,'star')) ? '?star=' . $_GET['star'] : '') + . ((x($_GET,'bmark')) ? '?bmark=' . $_GET['bmark'] : ''); + if(x($_GET,'save')) { + $r = q("select * from `search` where `uid` = %d and `term` = '%s' limit 1", + intval(local_user()), + dbesc($search) + ); + if(! count($r)) { + q("insert into `search` ( `uid`,`term` ) values ( %d, '%s') ", + intval(local_user()), + dbesc($search) + ); + } + } + if(x($_GET,'remove')) { + q("delete from `search` where `uid` = %d and `term` = '%s' limit 1", + intval(local_user()), + dbesc($search) + ); + } - $a->page['aside'] .= search($search,'netsearch-box',$srchurl); + $a->page['aside'] .= search($search,'netsearch-box',$srchurl,true); $a->page['aside'] .= ''; $a->page['aside'] .= group_side('network','network',true,$group_id); + + $a->page['aside'] .= saved_searches(); + } +function saved_searches() { + + $o = ''; + + $r = q("select `term` from `search` WHERE `uid` = %d", + intval(local_user()) + ); + + if(count($r)) { + $o .= '

    ' . t('Saved Searches') . '

    ' . "\r\n"; + $o .= '
    ' . "\r\n"; + } + + return $o; + +} + + + function network_content(&$a, $update = 0) { @@ -70,6 +117,7 @@ function network_content(&$a, $update = 0) { $cid = ((x($_GET['cid'])) ? intval($_GET['cid']) : 0); $star = ((x($_GET['star'])) ? intval($_GET['star']) : 0); + $bmark = ((x($_GET['bmark'])) ? intval($_GET['bmark']) : 0); if(($a->argc > 2) && $a->argv[2] === 'new') $nouveau = true; @@ -130,6 +178,7 @@ function network_content(&$a, $update = 0) { . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : '') . ((x($_GET,'search')) ? '&search=' . $_GET['search'] : '') . ((x($_GET,'star')) ? '&star=' . $_GET['star'] : '') + . ((x($_GET,'bmark')) ? '&bmark=' . $_GET['bmark'] : '') . "'; var profile_page = " . $a->pager['page'] . "; \r\n"; } @@ -151,6 +200,9 @@ function network_content(&$a, $update = 0) { $star_sql = (($star) ? " AND `starred` = 1 " : ''); + if($bmark) + $star_sql .= " AND `bookmark` = 1 "; + $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` $star_sql ) "; if($group) { @@ -188,7 +240,7 @@ function network_content(&$a, $update = 0) { if(count($r)) { $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` $star_sql AND `contact-id` IN ( " . intval($cid) . " )) "; $o = '

    ' . t('Contact: ') . $r[0]['name'] . '

    ' . $o; - if($r[0]['network'] !== NETWORK_MAIL && $r[0]['network'] !== NETWORK_DFRN && $r[0]['network'] !== NETWORK_FACEBOOK && $r[0]['writable'] && (! get_pconfig(local_user(),'system','nowarn_insecure'))) { + if($r[0]['network'] !== NETWORK_MAIL && $r[0]['network'] !== NETWORK_DFRN && $r[0]['network'] !== NETWORK_FACEBOOK && $r[0]['network'] !== NETWORK_DIASPORA && $r[0]['writable'] && (! get_pconfig(local_user(),'system','nowarn_insecure'))) { notice( t('Private messages to this person are at risk of public disclosure.') . EOL); } diff --git a/mod/parse_url.php b/mod/parse_url.php index 9bb0bc464..79c336ddc 100644 --- a/mod/parse_url.php +++ b/mod/parse_url.php @@ -13,7 +13,7 @@ function parse_url_content(&$a) { $text = null; - $template = "
    %s%s
    "; + $template = "
    %s%s
    "; $arr = array('url' => $url, 'text' => ''); @@ -119,6 +119,12 @@ function parse_url_content(&$a) { $text = '

    ' . $text . '

    '; } - echo sprintf($template,$url,($title) ? $title : $url,$text); + $title = str_replace("\n",'',$title); + + $result = sprintf($template,$url,($title) ? $title : $url,$text); + + logger('parse_url: returns: ' . $result); + + echo $result; killme(); } diff --git a/mod/photos.php b/mod/photos.php index cb13b7603..b74ca85d7 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -414,7 +414,8 @@ function photos_post(&$a) { ); } else { - $r = q("SELECT * FROM `contact` WHERE `nick` = '%s' AND `uid` = %d LIMIT 1", + $r = q("SELECT * FROM `contact` WHERE `attag` = '%s' OR `nick` = '%s' AND `uid` = %d ORDER BY `attag` DESC LIMIT 1", + dbesc($name), dbesc($name), intval($page_owner_uid) ); diff --git a/mod/ping.php b/mod/ping.php index 8a3d284af..38a32744d 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -159,8 +159,26 @@ function ping_init(&$a) { } - echo " - + echo " "; + + echo " "; + if(x($_SESSION,'sysmsg')){ + foreach ($_SESSION['sysmsg'] as $m){ + echo "".($m).""; + } + $_SESSION['sysmsg']=array(); + unset($_SESSION['sysmsg']); + } + if(x($_SESSION,'sysmsg_info')){ + foreach ($_SESSION['sysmsg_info'] as $m){ + echo "".($m).""; + } + $_SESSION['sysmsg_info']=array(); + unset($_SESSION['sysmsg_info']); + } + + echo " "; + echo" "; killme(); diff --git a/update.php b/update.php index ef036008f..f94e78d72 100644 --- a/update.php +++ b/update.php @@ -1,6 +1,6 @@ + + + + - - + + - + - + - +