diff --git a/.gitignore b/.gitignore index 9b3b23a0..41ec4238 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,9 @@ favicon.* .htconfig.php \#* -wip/* include/jquery-1.4.2.min.js *.log *.out *.version* -push* -langup +favicon.* home.html diff --git a/.htaccess b/.htaccess index 9cd6fa34..73031b96 100644 --- a/.htaccess +++ b/.htaccess @@ -9,12 +9,13 @@ Deny from all RewriteEngine on -# RewriteRule api.* - [E=REMOTE_USER:%{HTTP:Authorization},L] - - # Protect repo directory from browsing + # Protect repository directory from browsing RewriteRule "(^|/)\.git" - [F] # Rewrite current-style URLs of the form 'index.php?q=x'. + # Also place auth information into REMOTE_USER for sites running + # in CGI mode. + RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA] diff --git a/INSTALL.txt b/INSTALL.txt index dfc08f12..dd4c747e 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -113,3 +113,95 @@ $a->config['system']['addon'] = 'js_upload,poormancron'; and save your changes. + + +##################################################################### + + If things don't work... + +##################################################################### + + +##################################################################### +- If you get the message + "System is currently unavailable. Please try again later" +##################################################################### + + Check your database settings. It usually means your database could not +be opened or accessed. If the database resides on the same machine, check that +the database server name is "localhost". + +##################################################################### +- 500 Internal Error +##################################################################### + + This could be the result of one of our Apache directives not being +supported by your version of Apache. Examine your apache server logs. + You might remove the line "Options -Indexes" from the .htaccess file if +you are using a Windows server as this has been known to cause problems. +Also check your file permissions. Your website and all contents must generally +be world-readable. + + It is likely that your web server reported the source of the problem in +its error log files. Please review these system error logs to determine what +caused the problem. Often this will need to be resolved with your hosting +provider or (if self-hosted) your web server configuration. + +##################################################################### +- 400 and 4xx "File not found" errors +##################################################################### + + First check your file permissions. Your website and all contents must +generally be world-readable. + + Ensure that mod-rewite is installed and working, and that your +.htaccess file is being used. To verify the latter, create a file test.out +containing the word "test" in the top directory of Friendika, make it world +readable and point your web browser to + +http://yoursitenamehere.com/test.out + + This file should be blocked. You should get a permission denied message. + + If you see the word "test" your Apache configuration is not allowing +your .htaccess file to be used (there are rules in this file to block access +to any file with .out at the end, as these are typically used for system logs). + + Make certain the .htaccess file exists and is readable by everybody, then +look for the existence of "AllowOverride None" in the Apache server +configuration for your site. This will need to be changed to +"AllowOverride All". + + If you do not see the word "test", your .htaccess is working, but it is +likely that mod-rewrite is not installed in your web server or is not working. + + On most flavour of Linux, + +% a2enmod rewrite +% /etc/init.d/apache2 restart + + Consult your hosting provider, experts on your particular Linux +distribution or (if Windows) the provider of your Apache server software if +you need to change either of these and can not figure out how. There is +a lot of help available on the web. Google "mod-rewrite" along with the +name of your operating system distribution or Apache package (if using +Windows). + + +##################################################################### +- If you are unable to write the file .htconfig.php during installation +due to permissions issues: +##################################################################### + + create an empty file with that name and give it world-write permission. +For Linux: + +% touch .htconfig.php +% chmod 777 .htconfig.php + +Retry the installation. As soon as the database has been created, + +******* this is important ********* + +% chmod 755 .htconfig.php + diff --git a/addon/facebook/facebook.php b/addon/facebook/facebook.php index 15dffa59..c54d5b5f 100644 --- a/addon/facebook/facebook.php +++ b/addon/facebook/facebook.php @@ -43,6 +43,25 @@ define('FACEBOOK_MAXPOSTLEN', 420); + +function facebook_install() { + register_hook('post_local_end', 'addon/facebook/facebook.php', 'facebook_post_hook'); + register_hook('jot_networks', 'addon/facebook/facebook.php', 'facebook_jot_nets'); + register_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings'); + register_hook('cron', 'addon/facebook/facebook.php', 'facebook_cron'); + register_hook('queue_predeliver', 'addon/facebook/facebook.php', 'fb_queue_hook'); +} + + +function facebook_uninstall() { + unregister_hook('post_local_end', 'addon/facebook/facebook.php', 'facebook_post_hook'); + unregister_hook('jot_networks', 'addon/facebook/facebook.php', 'facebook_jot_nets'); + unregister_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings'); + unregister_hook('cron', 'addon/facebook/facebook.php', 'facebook_cron'); + unregister_hook('queue_predeliver', 'addon/facebook/facebook.php', 'fb_queue_hook'); +} + + /* declare the facebook_module function so that /facebook url requests will land here */ function facebook_module() {} @@ -339,22 +358,6 @@ function facebook_content(&$a) { return $o; } -function facebook_install() { - register_hook('post_local_end', 'addon/facebook/facebook.php', 'facebook_post_hook'); - register_hook('jot_networks', 'addon/facebook/facebook.php', 'facebook_jot_nets'); - register_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings'); - register_hook('cron', 'addon/facebook/facebook.php', 'facebook_cron'); - register_hook('queue_predeliver', 'addon/facebook/facebook.php', 'fb_queue_hook'); -} - - -function facebook_uninstall() { - unregister_hook('post_local_end', 'addon/facebook/facebook.php', 'facebook_post_hook'); - unregister_hook('jot_networks', 'addon/facebook/facebook.php', 'facebook_jot_nets'); - unregister_hook('plugin_settings', 'addon/facebook/facebook.php', 'facebook_plugin_settings'); - unregister_hook('cron', 'addon/facebook/facebook.php', 'facebook_cron'); - unregister_hook('queue_predeliver', 'addon/facebook/facebook.php', 'fb_queue_hook'); -} function facebook_cron($a,$b) { @@ -373,9 +376,12 @@ function facebook_cron($a,$b) { logger('facebook_cron'); - set_config('facebook','last_poll', time()); - $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'facebook' AND `k` = 'post' AND `v` = '1' "); + // Find the FB users on this site and randomize in case one of them + // uses an obscene amount of memory. It may kill this queue run + // but hopefully we'll get a few others through on each run. + + $r = q("SELECT * FROM `pconfig` WHERE `cat` = 'facebook' AND `k` = 'post' AND `v` = '1' ORDER BY RAND() "); if(count($r)) { foreach($r as $rr) { // check for new friends once a day @@ -389,6 +395,9 @@ function facebook_cron($a,$b) { fb_consume_all($rr['uid']); } } + + set_config('facebook','last_poll', time()); + } @@ -431,6 +440,10 @@ function facebook_post_hook(&$a,&$b) { if((local_user()) && (local_user() == $b['uid'])) { + // Facebook is not considered a private network + if($b['prvnets'] && $b['private']) + return; + if($b['parent']) { $r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($b['parent']), @@ -817,7 +830,7 @@ function fb_consume_stream($uid,$j,$wall = false) { $datarray['owner-avatar'] = $self[0]['thumb']; } if(isset($entry->application) && isset($entry->application->name) && strlen($entry->application->name)) - $datarray['app'] = $entry->application->name; + $datarray['app'] = strip_tags($entry->application->name); else $datarray['app'] = 'facebook'; $datarray['author-name'] = $from->name; diff --git a/addon/oembed/oembed.php b/addon/oembed/oembed.php index 7e677fd6..880e4992 100644 --- a/addon/oembed/oembed.php +++ b/addon/oembed/oembed.php @@ -25,9 +25,9 @@ function oembed_uninstall() { function oembed_settings_post($a,$b){ if(! local_user()) return; - if (isset($_POST['oembed-submit'])){ - set_pconfig(local_user(), 'oembed', 'use_for_youtube', (isset($_POST['oembed_use_for_youtube'])? intval($_POST['oembed_use_for_youtube']):0)); - notice( t('OEmbed settings updated') . EOL); + if (x($_POST,'oembed-submit')){ + set_pconfig(local_user(), 'oembed', 'use_for_youtube', (x($_POST,'oembed_use_for_youtube')? intval($_POST['oembed_use_for_youtube']):0)); + info( t('OEmbed settings updated') . EOL); } } @@ -36,21 +36,13 @@ function oembed_settings(&$a,&$o) { return; $uofy = intval(get_pconfig(local_user(), 'oembed', 'use_for_youtube' )); - $o.=' -
-

OEmbed

-
- -
-
-
- -
-
'; + $t = file_get_contents( dirname(__file__). "/settings.tpl" ); + $o .= replace_macros($t, array( + '$submit' => t('Submit'), + '$title' => "OEmbed", + '$useoembed' => array('oembed_use_for_youtube', t('Use OEmbed for YouTube videos'), $uofy, ""), + )); + } diff --git a/addon/oembed/settings.tpl b/addon/oembed/settings.tpl new file mode 100644 index 00000000..5a65ef8e --- /dev/null +++ b/addon/oembed/settings.tpl @@ -0,0 +1,7 @@ +
+

$title

+ {{ inc field_checkbox.tpl with $field=$useoembed }}{{ endinc }} +
+ +
+
diff --git a/addon/piwik/admin.tpl b/addon/piwik/admin.tpl new file mode 100644 index 00000000..0edd0621 --- /dev/null +++ b/addon/piwik/admin.tpl @@ -0,0 +1,4 @@ +{{ inc field_input.tpl with $field=$baseurl }}{{ endinc }} +{{ inc field_input.tpl with $field=$siteid }}{{ endinc }} +{{ inc field_checkbox.tpl with $field=$optout }}{{ endinc }} +
diff --git a/addon/piwik/piwik.php b/addon/piwik/piwik.php index 032f84f4..3cc136d2 100644 --- a/addon/piwik/piwik.php +++ b/addon/piwik/piwik.php @@ -18,10 +18,10 @@ * Add the following two lines to your .htconfig.php file: * * $a->config['piwik']['baseurl'] = 'www.example.com/piwik/'; - * $a->config['piwik']['sideid'] = '1'; + * $a->config['piwik']['siteid'] = '1'; * $a->config['piwik']['optout'] = true; // set to false to disable * - * Change the sideid to the ID that the Piwik tracker for your Friendika + * Change the siteid to the ID that the Piwik tracker for your Friendika * installation has. Alter the baseurl to fit your needs, don't care * about http/https but beware to put the trailing / at the end of your * setting. @@ -54,13 +54,13 @@ function piwik_analytics($a,&$b) { * Get the configuration variables from the .htconfig file. */ $baseurl = get_config('piwik','baseurl'); - $sideod = get_config('piwik','sideid'); + $siteid = get_config('piwik','siteid'); $optout = get_config('piwik','optout'); /* - * Add the Piwik code for the side. + * Add the Piwik code for the site. */ - $b .= "
\r\n \r\n\r\n\r\n
"; + $b .= "
\r\n \r\n\r\n\r\n
"; /* * If the optout variable is set to true then display the notice * otherwise just include the above code into the page. @@ -70,4 +70,21 @@ function piwik_analytics($a,&$b) { } } - +function piwik_plugin_admin (&$a, &$o) { + $t = file_get_contents( dirname(__file__)."/admin.tpl"); + $o = replace_macros( $t, array( + '$submit' => t('Submit'), + '$baseurl' => array('baseurl', t('Piwik Base URL'), get_config('piwik','baseurl' ), ''), + '$siteid' => array('siteid', t('Site ID'), get_config('piwik','siteid' ), ''), + '$optout' => array('optout', t('Show opt-out cookie link?'), get_config('piwik','optout' ), ''), + )); +} +function piwik_plugin_admin_post (&$a) { + $url = ((x($_POST, 'baseurl')) ? notags(trim($_POST['baseurl'])) : ''); + $id = ((x($_POST, 'siteid')) ? trim($_POST['siteid']) : ''); + $optout = ((x($_POST, 'optout')) ? trim($_POST['optout']) : ''); + set_config('piwik', 'baseurl', $url); + set_config('piwik', 'siteid', $id); + set_config('piwik', 'optout', $optout); + info( t('Settings updated.'). EOL); +} diff --git a/addon/statusnet/statusnet.php b/addon/statusnet/statusnet.php index 85024631..9357b0eb 100644 --- a/addon/statusnet/statusnet.php +++ b/addon/statusnet/statusnet.php @@ -89,6 +89,9 @@ function statusnet_jot_nets(&$a,&$b) { function statusnet_settings_post ($a,$post) { if(! local_user()) return; + // don't check statusnet settings if statusnet submit button is not clicked + if (!x($_POST,'statusnet-submit')) return; + if (isset($_POST['statusnet-disconnect'])) { /*** * if the statusnet-disconnect checkbox is set, clear the statusnet configuration @@ -152,28 +155,28 @@ function statusnet_settings_post ($a,$post) { goaway($a->get_baseurl().'/settings/addon'); } else { if (isset($_POST['statusnet-pin'])) { - // if the user supplied us with a PIN from Twitter, let the magic of OAuth happen - logger('got a StatusNet security code'); + // if the user supplied us with a PIN from Twitter, let the magic of OAuth happen + logger('got a StatusNet security code'); $api = get_pconfig(local_user(), 'statusnet', 'baseapi'); - $ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' ); - $csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' ); - // the token and secret for which the PIN was generated were hidden in the settings - // form as token and token2, we need a new connection to Twitter using these token - // and secret to request a Access Token with the PIN - $connection = new StatusNetOAuth($api, $ckey, $csecret, $_POST['statusnet-token'], $_POST['statusnet-token2']); - $token = $connection->getAccessToken( $_POST['statusnet-pin'] ); - // ok, now that we have the Access Token, save them in the user config - set_pconfig(local_user(),'statusnet', 'oauthtoken', $token['oauth_token']); - set_pconfig(local_user(),'statusnet', 'oauthsecret', $token['oauth_token_secret']); + $ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' ); + $csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' ); + // the token and secret for which the PIN was generated were hidden in the settings + // form as token and token2, we need a new connection to Twitter using these token + // and secret to request a Access Token with the PIN + $connection = new StatusNetOAuth($api, $ckey, $csecret, $_POST['statusnet-token'], $_POST['statusnet-token2']); + $token = $connection->getAccessToken( $_POST['statusnet-pin'] ); + // ok, now that we have the Access Token, save them in the user config + set_pconfig(local_user(),'statusnet', 'oauthtoken', $token['oauth_token']); + set_pconfig(local_user(),'statusnet', 'oauthsecret', $token['oauth_token_secret']); set_pconfig(local_user(),'statusnet', 'post', 1); // reload the Addon Settings page, if we don't do it see Bug #42 goaway($a->get_baseurl().'/settings/addon'); - } else { - // if no PIN is supplied in the POST variables, the user has changed the setting - // to post a tweet for every new __public__ posting to the wall - set_pconfig(local_user(),'statusnet','post',intval($_POST['statusnet-enable'])); - set_pconfig(local_user(),'statusnet','post_by_default',intval($_POST['statusnet-default'])); - info( t('StatusNet settings updated.') . EOL); + } else { + // if no PIN is supplied in the POST variables, the user has changed the setting + // to post a tweet for every new __public__ posting to the wall + set_pconfig(local_user(),'statusnet','post',intval($_POST['statusnet-enable'])); + set_pconfig(local_user(),'statusnet','post_by_default',intval($_POST['statusnet-default'])); + info( t('StatusNet settings updated.') . EOL); }}}} } function statusnet_settings(&$a,&$s) { @@ -217,7 +220,7 @@ function statusnet_settings(&$a,&$s) { $s .= ''. $asn['sitename'] .'
'; } $s .= '

'; - $s .= '
'; + $s .= '
'; } $s .= '

' . t('Provide your own OAuth Credentials') . '

'; $s .= '

'. t('No consumer key pair for StatusNet found. Register your Friendika Account as an desktop client on your StatusNet account, copy the consumer key pair here and enter the API base root.
Before you register your own OAuth key pair ask the administrator if there is already a key pair for this Friendika installation at your favorited StatusNet installation.') .'

'; @@ -231,7 +234,7 @@ function statusnet_settings(&$a,&$s) { $s .= ''; $s .= '
'; $s .= '

'; - $s .= '
'; + $s .= '
'; } else { /*** * ok we have a consumer key pair now look into the OAuth stuff @@ -256,15 +259,15 @@ function statusnet_settings(&$a,&$s) { $s .= ''; $s .= ''; $s .= ''; - $s .= '
'; - $s .= '
'; - $s .= '

'.t('Cancel Connection Process').'

'; - $s .= '
'; - $s .= '

'.t('Current StatusNet API is').': '.$api.'

'; - $s .= ''; - $s .= ''; - $s .= '
'; - $s .= '
'; + $s .= '
'; + $s .= '
'; + $s .= '

'.t('Cancel Connection Process').'

'; + $s .= '
'; + $s .= '

'.t('Current StatusNet API is').': '.$api.'

'; + $s .= ''; + $s .= ''; + $s .= '
'; + $s .= '
'; } else { /*** * we have an OAuth key / secret pair for the user @@ -286,7 +289,7 @@ function statusnet_settings(&$a,&$s) { $s .= ''; $s .= ''; $s .= '
'; - $s .= '
'; + $s .= '
'; } } $s .= '
'; @@ -303,10 +306,14 @@ function statusnet_post_hook(&$a,&$b) { if((local_user()) && (local_user() == $b['uid']) && (! $b['private']) && (!$b['parent']) ) { - load_pconfig(local_user(), 'statusnet'); + // Status.Net is not considered a private network + if($b['prvnets']) + return; + + load_pconfig(local_user(), 'statusnet'); - $api = get_pconfig(local_user(), 'statusnet', 'baseapi'); - $ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' ); + $api = get_pconfig(local_user(), 'statusnet', 'baseapi'); + $ckey = get_pconfig(local_user(), 'statusnet', 'consumerkey' ); $csecret = get_pconfig(local_user(), 'statusnet', 'consumersecret' ); $otoken = get_pconfig(local_user(), 'statusnet', 'oauthtoken' ); $osecret = get_pconfig(local_user(), 'statusnet', 'oauthsecret' ); diff --git a/addon/twitter/twitter.php b/addon/twitter/twitter.php index aeb9cc93..183c7112 100644 --- a/addon/twitter/twitter.php +++ b/addon/twitter/twitter.php @@ -76,6 +76,9 @@ function twitter_jot_nets(&$a,&$b) { function twitter_settings_post ($a,$post) { if(! local_user()) return; + // don't check twitter settings if twitter submit button is not clicked + if (!x($_POST,'twitter-submit')) return; + if (isset($_POST['twitter-disconnect'])) { /*** * if the twitter-disconnect checkbox is set, clear the OAuth key/secret pair @@ -159,7 +162,7 @@ function twitter_settings(&$a,&$s) { $s .= ''; $s .= ''; $s .= '
'; - $s .= '
'; + $s .= '
'; } else { /*** * we have an OAuth key / secret pair for the user @@ -178,7 +181,7 @@ function twitter_settings(&$a,&$s) { $s .= ''; $s .= ''; $s .= '
'; - $s .= '
'; + $s .= '
'; } } $s .= '
'; @@ -195,6 +198,11 @@ function twitter_post_hook(&$a,&$b) { if((local_user()) && (local_user() == $b['uid']) && (! $b['private']) && (! $b['parent']) ) { + // Twitter is not considered a private network + if($b['prvnets']) + return; + + load_pconfig(local_user(), 'twitter'); $ckey = get_config('twitter', 'consumerkey' ); diff --git a/addon/widgets/settings.tpl b/addon/widgets/settings.tpl new file mode 100644 index 00000000..9d0f21d2 --- /dev/null +++ b/addon/widgets/settings.tpl @@ -0,0 +1,19 @@ +
+

$title

+
+ + $key +
+ +
+ +
+ +

$widgets_h

+ + +
diff --git a/addon/widgets/widgets.php b/addon/widgets/widgets.php index f5f86822..13c4f93b 100644 --- a/addon/widgets/widgets.php +++ b/addon/widgets/widgets.php @@ -33,34 +33,32 @@ function widgets_settings(&$a,&$o) { $key = get_pconfig(local_user(), 'widgets', 'key' ); if ($key=='') { $key = mt_rand(); set_pconfig(local_user(), 'widgets', 'key', $key); } - - $o .='

Widgets

'; - - - $o.=' -
- '. t('Widgets key: ') .''.$key.' -
-
-
- -
'; - - - $o.='

Widgets:

'; - $o .= ''; - + + + $t = file_get_contents( dirname(__file__). "/settings.tpl" ); + $o .= replace_macros($t, array( + '$submit' => t('Generate new key'), + '$baseurl' => $a->get_baseurl(), + '$title' => "Widgets", + '$label' => t('Widgets key'), + '$key' => $key, + '$widgets_h' => t('Widgets available'), + '$widgets' => $widgets, + )); + } function widgets_module() { diff --git a/boot.php b/boot.php index c5751da3..855a67df 100644 --- a/boot.php +++ b/boot.php @@ -4,9 +4,9 @@ set_time_limit(0); ini_set('pcre.backtrack_limit', 250000); -define ( 'FRIENDIKA_VERSION', '2.2.1019' ); +define ( 'FRIENDIKA_VERSION', '2.2.1030' ); define ( 'DFRN_PROTOCOL_VERSION', '2.21' ); -define ( 'DB_UPDATE_VERSION', 1066 ); +define ( 'DB_UPDATE_VERSION', 1073 ); define ( 'EOL', "
\r\n" ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); @@ -56,9 +56,9 @@ define ( 'REGISTER_OPEN', 2 ); * this relationship with contact['name'] */ -define ( 'REL_VIP', 1); -define ( 'REL_FAN', 2); -define ( 'REL_BUD', 3); +define ( 'REL_VIP', 1); // other person is 'following' us +define ( 'REL_FAN', 2); // we are 'following' other person +define ( 'REL_BUD', 3); // mutual relationship /** * Hook array order @@ -296,6 +296,8 @@ class App { $this->module = str_replace(".", "_", $this->argv[0]); } else { + $this->argc = 1; + $this->argv = array('home'); $this->module = 'home'; } @@ -498,9 +500,6 @@ function install_plugin($plugin){ if(! function_exists('check_config')) { function check_config(&$a) { - - load_config('system'); - $build = get_config('system','build'); if(! x($build)) $build = set_config('system','build',DB_UPDATE_VERSION); @@ -674,7 +673,7 @@ function fetch_url($url,$binary = false, &$redirects = 0) { curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); - + curl_setopt($ch, CURLOPT_USERAGENT, "Friendika"); $curl_time = intval(get_config('system','curl_timeout')); curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60)); @@ -703,13 +702,21 @@ function fetch_url($url,$binary = false, &$redirects = 0) { $s = @curl_exec($ch); - $http_code = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); - $header = substr($s,0,strpos($s,"\r\n\r\n")); - if(stristr($header,'100') && (strlen($header) < 30)) { - // 100 Continue has two headers, get the real one - $s = substr($s,strlen($header)+4); - $header = substr($s,0,strpos($s,"\r\n\r\n")); + $base = $s; + $curl_info = curl_getinfo($ch); + $http_code = $curl_info['http_code']; + + $header = ''; + + // Pull out multiple headers, e.g. proxy and continuation headers + // allow for HTTP/2.x without fixing code + + while(preg_match('/^HTTP\/[1-2].+? [1-5][0-9][0-9]/',$base)) { + $chunk = substr($base,0,strpos($base,"\r\n\r\n")+4); + $header .= $chunk; + $base = substr($base,strlen($chunk)); } + if($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307) { $matches = array(); preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); @@ -720,16 +727,10 @@ function fetch_url($url,$binary = false, &$redirects = 0) { return fetch_url($url,$binary,$redirects); } } + $a->set_curl_code($http_code); - $body = substr($s,strlen($header)+4); - - /* one more try to make sure there are no more headers */ - - if(strpos($body,'HTTP/') === 0) { - $header = substr($body,0,strpos($body,"\r\n\r\n")); - $body = substr($body,strlen($header)+4); - } + $body = substr($s,strlen($header)); $a->set_curl_headers($header); @@ -750,6 +751,7 @@ function post_url($url,$params, $headers = null, &$redirects = 0) { curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch, CURLOPT_POSTFIELDS,$params); + curl_setopt($ch, CURLOPT_USERAGENT, "Friendika"); $curl_time = intval(get_config('system','curl_timeout')); curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60)); @@ -775,13 +777,21 @@ function post_url($url,$params, $headers = null, &$redirects = 0) { $s = @curl_exec($ch); - $http_code = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); - $header = substr($s,0,strpos($s,"\r\n\r\n")); - if(stristr($header,'100') && (strlen($header) < 30)) { - // 100 Continue has two headers, get the real one - $s = substr($s,strlen($header)+4); - $header = substr($s,0,strpos($s,"\r\n\r\n")); + $base = $s; + $curl_info = curl_getinfo($ch); + $http_code = $curl_info['http_code']; + + $header = ''; + + // Pull out multiple headers, e.g. proxy and continuation headers + // allow for HTTP/2.x without fixing code + + while(preg_match('/^HTTP\/[1-2].+? [1-5][0-9][0-9]/',$base)) { + $chunk = substr($base,0,strpos($base,"\r\n\r\n")+4); + $header .= $chunk; + $base = substr($base,strlen($chunk)); } + if($http_code == 301 || $http_code == 302 || $http_code == 303) { $matches = array(); preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); @@ -793,14 +803,7 @@ function post_url($url,$params, $headers = null, &$redirects = 0) { } } $a->set_curl_code($http_code); - $body = substr($s,strlen($header)+4); - - /* one more try to make sure there are no more headers */ - - if(strpos($body,'HTTP/') === 0) { - $header = substr($body,0,strpos($body,"\r\n\r\n")); - $body = substr($body,strlen($header)+4); - } + $body = substr($s,strlen($header)); $a->set_curl_headers($header); @@ -1218,7 +1221,11 @@ function load_config($family) { if(count($r)) { foreach($r as $rr) { $k = $rr['k']; - $a->config[$family][$k] = $rr['v']; + if ($rr['cat'] === 'config') { + $a->config[$k] = $rr['v']; + } else { + $a->config[$family][$k] = $rr['v']; + } } } }} @@ -1685,8 +1692,10 @@ function fetch_lrdd_template($host) { $url1 = 'https://' . $host . '/.well-known/host-meta' ; $url2 = 'http://' . $host . '/.well-known/host-meta' ; $links = fetch_xrd_links($url1); + logger('fetch_lrdd_template from: ' . $url1); logger('template (https): ' . print_r($links,true)); if(! count($links)) { + logger('fetch_lrdd_template from: ' . $url2); $links = fetch_xrd_links($url2); logger('template (http): ' . print_r($links,true)); } @@ -2015,7 +2024,7 @@ function get_tags($s) { $s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s); - if(preg_match_all('/([@#][^ \x0D\x0A,:?]+)([ \x0D\x0A,:?]|$)/',$s,$match)) { + if(preg_match_all('/([@#][^ \x0D\x0A,:?]+ [^ \x0D\x0A,:?]+)([ \x0D\x0A,:?]|$)/',$s,$match)) { foreach($match[1] as $mtch) { if(strstr($mtch,"]")) { // we might be inside a bbcode color tag - leave it alone @@ -2028,6 +2037,18 @@ function get_tags($s) { } } + if(preg_match_all('/([@#][^ \x0D\x0A,:?]+)([ \x0D\x0A,:?]|$)/',$s,$match)) { + foreach($match[1] as $mtch) { + if(strstr($mtch,"]")) { + // we might be inside a bbcode color tag - leave it alone + continue; + } + if(substr($mtch,-1,1) === '.') + $ret[] = substr($mtch,0,-1); + else + $ret[] = $mtch; + } + } return $ret; }} @@ -2415,7 +2436,7 @@ function profile_sidebar($profile) { )); - $arr = array('profile' => $profile, 'entry' => $o); + $arr = array('profile' => &$profile, 'entry' => &$o); call_hooks('profile_sidebar', $arr); @@ -2891,3 +2912,15 @@ function get_plugin_info($plugin){ } return $info; }} + +if(! function_exists('return_bytes')) { +function return_bytes ($size_str) { + switch (substr ($size_str, -1)) + { + case 'M': case 'm': return (int)$size_str * 1048576; + case 'K': case 'k': return (int)$size_str * 1024; + case 'G': case 'g': return (int)$size_str * 1073741824; + default: return $size_str; + } +}} + diff --git a/database.sql b/database.sql index 284ab0af..4952e7c6 100644 --- a/database.sql +++ b/database.sql @@ -169,9 +169,10 @@ CREATE TABLE IF NOT EXISTS `item` ( `parent-uri` char(255) NOT NULL, `extid` char(255) NOT NULL, `thr-parent` char(255) NOT NULL, - `created` datetime NOT NULL, - `edited` datetime NOT NULL, - `changed` datetime NOT NULL, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `received` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `changed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `owner-name` char(255) NOT NULL, `owner-link` char(255) NOT NULL, `owner-avatar` char(255) NOT NULL, @@ -201,6 +202,7 @@ CREATE TABLE IF NOT EXISTS `item` ( `private` tinyint(1) NOT NULL DEFAULT '0', `pubmail` tinyint(1) NOT NULL DEFAULT '0', `visible` tinyint(1) NOT NULL DEFAULT '0', + `starred` 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', @@ -215,7 +217,9 @@ CREATE TABLE IF NOT EXISTS `item` ( KEY `extid` (`extid`), KEY `created` (`created`), KEY `edited` (`edited`), + KEY `received` (`received`), KEY `visible` (`visible`), + KEY `starred` (`starred`), KEY `deleted` (`deleted`), KEY `last-child` (`last-child`), KEY `unseen` (`unseen`), @@ -241,7 +245,7 @@ CREATE TABLE IF NOT EXISTS `mail` ( `from-url` char(255) NOT NULL, `contact-id` char(255) NOT NULL, `title` char(255) NOT NULL, - `body` text NOT NULL, + `body` mediumtext NOT NULL, `seen` tinyint(1) NOT NULL, `replied` tinyint(1) NOT NULL, `uri` char(255) NOT NULL, @@ -276,7 +280,12 @@ CREATE TABLE IF NOT EXISTS `photo` ( `allow_gid` mediumtext NOT NULL, `deny_cid` mediumtext NOT NULL, `deny_gid` mediumtext NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + KEY `uid` (`uid`), + KEY `resource-id` (`resource-id`), + KEY `album` (`album`), + KEY `scale` (`scale`), + KEY `profile` (`profile`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- @@ -507,7 +516,8 @@ CREATE TABLE IF NOT EXISTS `fcontact` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY , `url` CHAR( 255 ) NOT NULL , `name` CHAR( 255 ) NOT NULL , -`photo` CHAR( 255 ) NOT NULL +`photo` CHAR( 255 ) NOT NULL , +`request` CHAR( 255 ) NOT NULL ) ENGINE = MYISAM DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `ffinder` ( @@ -518,6 +528,19 @@ CREATE TABLE IF NOT EXISTS `ffinder` ( ) ENGINE = MYISAM DEFAULT CHARSET=utf8; +CREATE TABLE IF NOT EXISTS `fsuggest` ( +`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , +`uid` INT NOT NULL , +`cid` INT NOT NULL , +`name` CHAR( 255 ) NOT NULL , +`url` CHAR( 255 ) NOT NULL , +`request` CHAR( 255 ) NOT NULL, +`photo` CHAR( 255 ) NOT NULL , +`note` TEXT NOT NULL , +`created` DATETIME NOT NULL +) ENGINE = MYISAM DEFAULT CHARSET=utf8; + + CREATE TABLE IF NOT EXISTS `mailacct` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `uid` INT NOT NULL, diff --git a/favicon.gif b/favicon.gif deleted file mode 100644 index e69de29b..00000000 diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index e69de29b..00000000 diff --git a/images/icons.png b/images/icons.png index fee7781c..494555aa 100644 Binary files a/images/icons.png and b/images/icons.png differ diff --git a/include/Photo.php b/include/Photo.php index 707b0de5..de4c3d9e 100644 --- a/include/Photo.php +++ b/include/Photo.php @@ -230,21 +230,21 @@ function import_profile_photo($photo,$uid,$cid) { $hash = photo_new_resource(); - $r = $img->store($uid, $cid, $hash, $filename, t('Contact Photos'), 4 ); + $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 4 ); if($r === false) $photo_failure = true; $img->scaleImage(80); - $r = $img->store($uid, $cid, $hash, $filename, t('Contact Photos'), 5 ); + $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 5 ); if($r === false) $photo_failure = true; $img->scaleImage(48); - $r = $img->store($uid, $cid, $hash, $filename, t('Contact Photos'), 6 ); + $r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6 ); if($r === false) $photo_failure = true; diff --git a/include/Scrape.php b/include/Scrape.php index 505d2bf9..698ec9cf 100644 --- a/include/Scrape.php +++ b/include/Scrape.php @@ -423,7 +423,7 @@ function probe_url($url) { $poll = $tapi . '?user_id=' . $tid; else $poll = $tapi . '?screen_name=' . $tid; - $profile = 'http://twitter.com/!#/' . $tid; + $profile = 'http://twitter.com/#!/' . $tid; } if(! x($vcard,'fn')) @@ -442,7 +442,7 @@ function probe_url($url) { if(x($feedret,'photo')) $vcard['photo'] = $feedret['photo']; - require_once('simplepie/simplepie.inc'); + require_once('library/simplepie/simplepie.inc'); $feed = new SimplePie(); $xml = fetch_url($poll); diff --git a/include/acl_selectors.php b/include/acl_selectors.php index 90fdf9c1..c3e26082 100644 --- a/include/acl_selectors.php +++ b/include/acl_selectors.php @@ -41,6 +41,115 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) { } +function contact_selector($selname, $selclass, $preselected = false, $options) { + + $a = get_app(); + + $mutual = false; + $networks = null; + $single = false; + $exclude = false; + $size = 4; + + if(is_array($options)) { + if(x($options,'size')) + $size = $options['size']; + + if(x($options,'mutual_friends')) + $mutual = true; + if(x($options,'single')) + $single = true; + if(x($options,'multiple')) + $single = false; + if(x($options,'exclude')) + $exclude = $options['exclude']; + + if(x($options,'networks')) { + switch($options['networks']) { + case 'DFRN_ONLY': + $networks = array('dfrn'); + break; + case 'PRIVATE': + if(is_array($a->user) && $a->user['prvnets']) + $networks = array('dfrn','mail','dspr'); + else + $networks = array('dfrn','face','mail', 'dspr'); + break; + case 'TWO_WAY': + if(is_array($a->user) && $a->user['prvnets']) + $networks = array('dfrn','mail','dspr'); + else + $networks = array('dfrn','face','mail','dspr','stat'); + break; + default: + break; + } + } + } + + $x = array('options' => $options, 'size' => $size, 'single' => $single, 'mutual' => $mutual, 'exclude' => $exclude, 'networks' => $networks); + + call_hooks('contact_select_options', $x); + + $o = ''; + + $sql_extra = ''; + + if($x['mutual']) { + $sql_extra .= sprintf(" AND `rel` = %d ", intval(REL_BUD)); + } + + if(intval($x['exclude'])) + $sql_extra .= sprintf(" AND `id` != %d ", intval($x['exclude'])); + + if(is_array($x['networks']) && count($x['networks'])) { + for($y = 0; $y < count($x['networks']) ; $y ++) + $x['networks'][$y] = "'" . dbesc($x['networks'][$y]) . "'"; + $str_nets = implode(',',$x['networks']); + $sql_extra .= " AND `network` IN ( $str_nets ) "; + } + + if($x['single']) + $o .= "\r\n"; + + $r = q("SELECT `id`, `name`, `url`, `network` FROM `contact` + WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `notify` != '' + $sql_extra + ORDER BY `name` ASC ", + intval(local_user()) + ); + + + $arr = array('contact' => $r, 'entry' => $o); + + // e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow' + + call_hooks($a->module . '_pre_' . $selname, $arr); + + if(count($r)) { + foreach($r as $rr) { + if((is_array($preselected)) && in_array($rr['id'], $preselected)) + $selected = " selected=\"selected\" "; + else + $selected = ''; + + $trimmed = mb_substr($rr['name'],0,20); + + $o .= "\r\n"; + } + + } + + $o .= "\r\n"; + + call_hooks($a->module . '_post_' . $selname, $o); + + return $o; +} + + function contact_select($selname, $selclass, $preselected = false, $size = 4, $privmail = false, $celeb = false, $privatenet = false) { @@ -64,6 +173,8 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p $sql_extra .= " AND `network` IN ( 'dfrn', 'mail', 'face' ) "; } + + if($privmail) $o .= "'; + $o .= ''; + + return $o; +} \ No newline at end of file diff --git a/mod/group.php b/mod/group.php index 2d7ea8c1..981796f6 100644 --- a/mod/group.php +++ b/mod/group.php @@ -7,7 +7,7 @@ function validate_members(&$item) { function group_init(&$a) { if(local_user()) { require_once('include/group.php'); - $a->page['aside'] = group_side(); + $a->page['aside'] = group_side('contacts','group',false,(($a->argc > 1) ? intval($a->argv[1]) : 0)); } } @@ -68,6 +68,14 @@ function group_content(&$a) { return; } + // Switch to text mod interface if we have more than 'n' contacts or group members + + $switchtotext = get_pconfig(local_user(),'system','groupedit_image_limit'); + if($switchtotext === false) + $switchtotext = get_config('system','groupedit_image_limit'); + if($switchtotext === false) + $switchtotext = 400; + if(($a->argc == 2) && ($a->argv[1] === 'new')) { $tpl = get_markup_template('group_new.tpl'); $o .= replace_macros($tpl,array( @@ -170,10 +178,11 @@ function group_content(&$a) { $o .= '
'; $o .= '

' . t('Members') . '

'; + $textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : false); foreach($members as $member) { if($member['url']) { $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . '); return true;'; - $o .= micropro($member,true,'mpgroup'); + $o .= micropro($member,true,'mpgroup', $textmode); } else group_rmv_member(local_user(),$group['name'],$member['id']); @@ -189,10 +198,11 @@ function group_content(&$a) { ); if(count($r)) { + $textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : false); foreach($r as $member) { if(! in_array($member['id'],$preselected)) { $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . '); return true;'; - $o .= micropro($member,true,'mpall'); + $o .= micropro($member,true,'mpall', $textmode); } } } diff --git a/mod/item.php b/mod/item.php index 84fe237b..8a4f8293 100644 --- a/mod/item.php +++ b/mod/item.php @@ -61,7 +61,7 @@ function item_post(&$a) { $profile_uid = ((x($_POST,'profile_uid')) ? intval($_POST['profile_uid']) : 0); $post_id = ((x($_POST['post_id'])) ? intval($_POST['post_id']) : 0); - $app = ((x($_POST['source'])) ? notags($_POST['source']) : ''); + $app = ((x($_POST['source'])) ? strip_tags($_POST['source']) : ''); if(! can_write_wall($a,$profile_uid)) { notice( t('Permission denied.') . EOL) ; @@ -244,6 +244,10 @@ function item_post(&$a) { } + /** + * Next link in any attachment references we find in the post. + */ + $match = false; if(preg_match_all("/\[attachment\](.*?)\[\/attachment\]/",$body,$match)) { @@ -265,10 +269,6 @@ function item_post(&$a) { } } - - - - /** * Fold multi-line [code] sequences */ @@ -285,13 +285,21 @@ function item_post(&$a) { $tags = get_tags($body); - if(($parent_contact) && ($parent_contact['network'] === 'stat') && ($parent_contact['nick']) && (! in_array('@' . $parent_contact['nick'],$tags))) { + /** + * add a statusnet style reply tag if the original post was from there + * and we are replying, and there isn't one already + */ + + if(($parent_contact) && ($parent_contact['network'] === 'stat') + && ($parent_contact['nick']) && (! in_array('@' . $parent_contact['nick'],$tags))) { $body = '@' . $parent_contact['nick'] . ' ' . $body; $tags[] = '@' . $parent_contact['nick']; } if(count($tags)) { foreach($tags as $tag) { + if(isset($profile)) + unset($profile); if(strpos($tag,'#') === 0) { if(strpos($tag,'[url=')) continue; @@ -325,7 +333,7 @@ function item_post(&$a) { else { $newname = $name; $alias = ''; - if(strstr($name,'_')) { + if(strstr($name,'_') || strstr($name,' ')) { $newname = str_replace('_',' ',$name); $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `uid` = %d LIMIT 1", dbesc($newname), @@ -419,6 +427,7 @@ function item_post(&$a) { $datarray['author-avatar'] = $author['thumb']; $datarray['created'] = datetime_convert(); $datarray['edited'] = datetime_convert(); + $datarray['received'] = datetime_convert(); $datarray['changed'] = datetime_convert(); $datarray['uri'] = $uri; $datarray['title'] = $title; @@ -445,6 +454,7 @@ function item_post(&$a) { $datarray['parent'] = $parent; $datarray['self'] = $self; + $datarray['prvnets'] = $user['prvnets']; if($orig_post) $datarray['edit'] = true; @@ -472,9 +482,9 @@ function item_post(&$a) { $r = q("INSERT INTO `item` (`uid`,`type`,`wall`,`gravity`,`contact-id`,`owner-name`,`owner-link`,`owner-avatar`, - `author-name`, `author-link`, `author-avatar`, `created`, `edited`, `changed`, `uri`, `title`, `body`, `app`, `location`, `coord`, + `author-name`, `author-link`, `author-avatar`, `created`, `edited`, `received`, `changed`, `uri`, `title`, `body`, `app`, `location`, `coord`, `tag`, `inform`, `verb`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`, `private`, `pubmail`, `attach` ) - VALUES( %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', %d, %d, '%s' )", + VALUES( %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', %d, %d, '%s' )", intval($datarray['uid']), dbesc($datarray['type']), intval($datarray['wall']), @@ -488,6 +498,7 @@ function item_post(&$a) { dbesc($datarray['author-avatar']), dbesc($datarray['created']), dbesc($datarray['edited']), + dbesc($datarray['received']), dbesc($datarray['changed']), dbesc($datarray['uri']), dbesc($datarray['title']), diff --git a/mod/lostpass.php b/mod/lostpass.php index e0bf6eed..3453a0db 100644 --- a/mod/lostpass.php +++ b/mod/lostpass.php @@ -7,12 +7,16 @@ function lostpass_post(&$a) { if(! $email) goaway($a->get_baseurl()); - $r = q("SELECT * FROM `user` WHERE ( `email` = '%s' OR `nickname` = '%s' ) LIMIT 1", + $r = q("SELECT * FROM `user` WHERE ( `email` = '%s' OR `nickname` = '%s' ) AND `verified` = 1 AND `blocked` = 0 LIMIT 1", dbesc($email), dbesc($email) ); - if(! count($r)) + + if(! count($r)) { + notice( t('No valid account found.') . EOL); goaway($a->get_baseurl()); + } + $uid = $r[0]['uid']; $username = $r[0]['username']; diff --git a/mod/match.php b/mod/match.php index 2d6456b5..5dd80fe3 100644 --- a/mod/match.php +++ b/mod/match.php @@ -15,7 +15,7 @@ function match_content(&$a) { if(! count($r)) return; if(! $r[0]['pub_keywords'] && (! $r[0]['prv_keywords'])) { - notice('No keywords to match. Please add keywords to your default profile.'); + notice( t('No keywords to match. Please add keywords to your default profile.') . EOL); return; } @@ -27,7 +27,10 @@ function match_content(&$a) { if($a->pager['page'] != 1) $params['p'] = $a->pager['page']; - $x = post_url('http://dir.friendika.com/msearch', $params); + if(strlen(get_config('system','directory_submit_url'))) + $x = post_url('http://dir.friendika.com/msearch', $params); + else + $x = post_url($a->get_baseurl() . '/msearch', $params); $j = json_decode($x); @@ -40,7 +43,7 @@ function match_content(&$a) { foreach($j->results as $jj) { $o .= '
'; - $o .= '' . '' . $jj->name . '
'; + $o .= '' . '' . $jj->name . '
'; $o .= '
'; $o .= ''; $o .= '
'; diff --git a/mod/msearch.php b/mod/msearch.php index dc949629..7d9bbe9e 100644 --- a/mod/msearch.php +++ b/mod/msearch.php @@ -16,7 +16,7 @@ function msearch_post(&$a) { if(count($r)) $total = $r[0]['total']; - $r = q("SELECT `username`, `nickname`, `user`.`uid` FROM `user` LEFT JOIN `profile` ON `user`.`uid` = `profile`.`uid` WHERE `is-default` = 1 AND `hidewall` = 0 AND MATCH `pub_keywords` AGAINST ('%s') LIMIT %d , %d ", + $r = q("SELECT `pub_keywords`, `username`, `nickname`, `user`.`uid` FROM `user` LEFT JOIN `profile` ON `user`.`uid` = `profile`.`uid` WHERE `is-default` = 1 AND `hidewall` = 0 AND MATCH `pub_keywords` AGAINST ('%s') LIMIT %d , %d ", dbesc($search), intval($startrec), intval($perpage) @@ -28,7 +28,8 @@ function msearch_post(&$a) { $results[] = array( 'name' => $rr['name'], 'url' => $a->get_baseurl() . '/profile/' . $rr['nickname'], - 'photo' => $a->get_baseurl() . '/photo/avatar/' . $rr['uid'] . 'jpg' + 'photo' => $a->get_baseurl() . '/photo/avatar/' . $rr['uid'] . 'jpg', + 'tags' => str_replace(array(',',' '),array(' ',' '),$rr['pub_keywords']) ); } diff --git a/mod/network.php b/mod/network.php index 75775ba5..28e54028 100644 --- a/mod/network.php +++ b/mod/network.php @@ -7,13 +7,14 @@ function network_init(&$a) { return; } - + $group_id = (($a->argc > 1 && intval($a->argv[1])) ? intval($a->argv[1]) : 0); + require_once('include/group.php'); if(! x($a->page,'aside')) $a->page['aside'] = ''; $search = ((x($_GET,'search')) ? escape_tags($_GET['search']) : ''); - $srchurl = '/network' . ((x($_GET,'cid')) ? '?cid=' . $_GET['cid'] : ''); + $srchurl = '/network' . ((x($_GET,'cid')) ? '?cid=' . $_GET['cid'] : '') . ((x($_GET,'star')) ? '?star=' . $_GET['star'] : ''); $a->page['aside'] .= search($search,'netsearch-box',$srchurl); @@ -21,15 +22,33 @@ function network_init(&$a) { $a->page['aside'] .= ''; + + if(x($_GET,'star')) + $a->page['aside'] .= ''; + else + $a->page['aside'] .= ''; + + } $a->page['aside'] .= ''; - $a->page['aside'] .= group_side('network','network',true); + $a->page['aside'] .= group_side('network','network',true,$group_id); } @@ -50,6 +69,7 @@ function network_content(&$a, $update = 0) { require_once('include/acl_selectors.php'); $cid = ((x($_GET['cid'])) ? intval($_GET['cid']) : 0); + $star = ((x($_GET['star'])) ? intval($_GET['star']) : 0); if(($a->argc > 2) && $a->argv[2] === 'new') $nouveau = true; @@ -108,6 +128,7 @@ function network_content(&$a, $update = 0) { . "; var netargs = '" . substr($a->cmd,8) . ((x($_GET,'cid')) ? '?cid=' . $_GET['cid'] : '') . ((x($_GET,'search')) ? '?search=' . $_GET['search'] : '') + . ((x($_GET,'star')) ? '?star=' . $_GET['star'] : '') . "'; var profile_page = " . $a->pager['page'] . "; \r\n"; } @@ -116,7 +137,7 @@ function network_content(&$a, $update = 0) { // level which items you've seen and which you haven't. If you're looking // at the top level network page just mark everything seen. - if((! $group) && (! $cid)) { + if((! $group) && (! $cid) && (! $star)) { $r = q("UPDATE `item` SET `unseen` = 0 WHERE `unseen` = 1 AND `uid` = %d", intval($_SESSION['uid']) @@ -127,7 +148,9 @@ function network_content(&$a, $update = 0) { // that belongs to you, hence you can see all of it. We will filter by group if // desired. - $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` ) "; + $star_sql = (($star) ? " AND `starred` = 1 " : ''); + + $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` $star_sql ) "; if($group) { $r = q("SELECT `name`, `id` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", @@ -151,7 +174,8 @@ function network_content(&$a, $update = 0) { info( t('Group is empty')); } - $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` AND ( `contact-id` IN ( $contact_str ) OR `allow_gid` REGEXP '<" . intval($group) . ">' )) "; + + $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` $star_sql AND ( `contact-id` IN ( $contact_str ) OR `allow_gid` REGEXP '<" . intval($group) . ">' )) "; $o = '

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

' . $o; } elseif($cid) { @@ -161,7 +185,7 @@ function network_content(&$a, $update = 0) { intval($cid) ); if(count($r)) { - $sql_extra = " AND `item`.`parent` IN ( SELECT `parent` FROM `item` WHERE `id` = `parent` AND `contact-id` IN ( " . intval($cid) . " )) "; + $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'))) { notice( t('Private messages to this person are at risk of public disclosure.') . EOL); @@ -183,6 +207,7 @@ function network_content(&$a, $update = 0) { if(x($_GET,'search')) $sql_extra .= " AND `item`.`body` REGEXP '" . dbesc(escape_tags($_GET['search'])) . "' "; + $r = q("SELECT COUNT(*) AS `total` FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id` @@ -212,7 +237,7 @@ function network_content(&$a, $update = 0) { AND `contact`.`id` = `item`.`contact-id` AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 $sql_extra - ORDER BY `item`.`created` DESC LIMIT %d ,%d ", + ORDER BY `item`.`received` DESC LIMIT %d ,%d ", intval($_SESSION['uid']), intval($a->pager['start']), intval($a->pager['itemspage']) diff --git a/mod/notifications.php b/mod/notifications.php index a3339199..c6f07305 100644 --- a/mod/notifications.php +++ b/mod/notifications.php @@ -13,11 +13,9 @@ function notifications_post(&$a) { if($request_id) { - $r = q("SELECT * FROM `intro` - WHERE `id` = %d - AND `uid` = %d LIMIT 1", - intval($request_id), - intval(local_user()) + $r = q("SELECT * FROM `intro` WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($request_id), + intval(local_user()) ); if(count($r)) { @@ -28,14 +26,22 @@ function notifications_post(&$a) { notice( t('Invalid request identifier.') . EOL); return; } + + // If it is a friend suggestion, the contact is not a new friend but an existing friend + // that should not be deleted. + + $fid = $r[0]['fid']; + if($_POST['submit'] == t('Discard')) { $r = q("DELETE FROM `intro` WHERE `id` = %d LIMIT 1", intval($intro_id) ); - $r = q("DELETE FROM `contact` WHERE `id` = %d AND `uid` = %d AND `self` = 0 LIMIT 1", - intval($contact_id), - intval(local_user()) - ); + if(! $fid) { + $r = q("DELETE FROM `contact` WHERE `id` = %d AND `uid` = %d AND `self` = 0 LIMIT 1", + intval($contact_id), + intval(local_user()) + ); + } return; } if($_POST['submit'] == t('Ignore')) { @@ -81,18 +87,41 @@ function notifications_content(&$a) { $a->set_pager_itemspage(20); } - $r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.* - FROM `intro` LEFT JOIN `contact` ON `intro`.`contact-id` = `contact`.`id` + $r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, `fcontact`.`name` AS `fname`,`fcontact`.`url` AS `furl`,`fcontact`.`photo` AS `fphoto`,`fcontact`.`request` AS `frequest` + FROM `intro` LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id` LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id` WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ", intval($_SESSION['uid'])); if(($r !== false) && (count($r))) { - + $sugg = get_markup_template('suggestions.tpl'); $tpl = get_markup_template("intros.tpl"); foreach($r as $rr) { + if($rr['fid']) { + $return_addr = bin2hex($a->user['nickname'] . '@' . $a->get_hostname() . (($a->path) ? '/' . $a->path : '')); + $o .= replace_macros($sugg,array( + '$str_notifytype' => t('Notification type: '), + '$notify_type' => t('Friend Suggestion'), + '$intro_id' => $rr['intro_id'], + '$madeby' => sprintf( t('suggested by %s'),$rr['name']), + '$contact_id' => $rr['contact-id'], + '$photo' => ((x($rr,'fphoto')) ? $rr['fphoto'] : "images/default-profile.jpg"), + '$fullname' => $rr['fname'], + '$url' => $rr['furl'], + '$knowyou' => $knowyou, + '$approve' => t('Approve'), + '$note' => $rr['note'], + '$request' => $rr['frequest'] . '?addr=' . $return_addr, + '$ignore' => t('Ignore'), + '$discard' => t('Discard') + + )); + + continue; + + } $friend_selected = (($rr['network'] !== 'stat') ? ' checked="checked" ' : ' disabled '); $fan_selected = (($rr['network'] === 'stat') ? ' checked="checked" disabled ' : ''); $dfrn_tpl = get_markup_template('netfriend.tpl'); @@ -138,28 +167,6 @@ function notifications_content(&$a) { else info( t('No notifications.') . EOL); - if ($a->config['register_policy'] == REGISTER_APPROVE && - $a->config['admin_email'] === $a->user['email']){ - $o .= '

' . t('User registrations waiting for confirm') . '

' . "\r\n"; - - $r = q("SELECT `register`.*, `contact`.`name`, `user`.`email` - FROM `register` - LEFT JOIN `contact` ON `register`.`uid` = `contact`.`uid` - LEFT JOIN `user` ON `register`.`uid` = `user`.`uid`;"); - if(($r !== false) && (count($r))) { - $o .= '"; - } - else - info( t('No registrations.') . EOL); - - } - $o .= paginate($a); return $o; } diff --git a/mod/photo.php b/mod/photo.php index 3bea7e72..9809aa41 100644 --- a/mod/photo.php +++ b/mod/photo.php @@ -1,5 +1,7 @@ argc) { @@ -73,39 +75,7 @@ function photo_init(&$a) { ); if(count($r)) { - $owner = $r[0]['uid']; - - $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = '' "; - - if(local_user() && ($owner == $_SESSION['uid'])) { - - // Owner can always see his/her photos - $sql_extra = ''; - - } - elseif(remote_user()) { - - // authenticated visitor - here lie dragons - - $groups = init_groups_visitor($_SESSION['visitor_id']); - $gs = '<<>>'; // should be impossible to match - if(count($groups)) { - foreach($groups as $g) - $gs .= '|<' . intval($g) . '>'; - } - - $sql_extra = sprintf( - " AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' ) - AND ( `deny_cid` = '' OR NOT `deny_cid` REGEXP '<%d>' ) - AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' ) - AND ( `deny_gid` = '' OR NOT `deny_gid` REGEXP '%s') ", - - intval($_SESSION['visitor_id']), - intval($_SESSION['visitor_id']), - dbesc($gs), - dbesc($gs) - ); - } + $sql_extra = permissions_sql($r[0]['uid']); // Now we'll see if we can access the photo diff --git a/mod/photos.php b/mod/photos.php index bbdb8b7e..3e0ec580 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -3,6 +3,7 @@ require_once('include/Photo.php'); require_once('include/items.php'); require_once('include/acl_selectors.php'); require_once('include/bbcode.php'); +require_once('include/security.php'); function photos_init(&$a) { @@ -23,7 +24,9 @@ function photos_init(&$a) { $a->data['user'] = $r[0]; - $albums = q("SELECT distinct(`album`) AS `album` FROM `photo` WHERE `uid` = %d", + $sql_extra = permissions_sql($a->data['user']['uid']); + + $albums = q("SELECT distinct(`album`) AS `album` FROM `photo` WHERE `uid` = %d $sql_extra ", intval($a->data['user']['uid']) ); @@ -35,7 +38,11 @@ function photos_init(&$a) { $o .= '