diff --git a/.gitignore b/.gitignore index 9b3b23a002..41ec42389f 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 9cd6fa34c7..73031b962e 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 dfc08f1290..dd4c747e2a 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 15dffa594c..c54d5b5f09 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 7e677fd6f5..880e4992f5 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 0000000000..5a65ef8e5d --- /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 0000000000..0edd062104 --- /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 032f84f4bb..3cc136d299 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 85024631ce..9357b0ebd9 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 aeb9cc9376..183c71126f 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 0000000000..9d0f21d296 --- /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 f5f8682223..13c4f93bb2 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 c5751da373..855a67dfd2 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 284ab0afc8..4952e7c623 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 e69de29bb2..0000000000 diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/images/icons.png b/images/icons.png index fee7781c84..494555aa69 100644 Binary files a/images/icons.png and b/images/icons.png differ diff --git a/include/Photo.php b/include/Photo.php index 707b0de5d8..de4c3d9e04 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 505d2bf99e..698ec9cf04 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 90fdf9c1c9..c3e26082e3 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 2d7ea8c113..981796f67e 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 84fe237b3d..8a4f8293c8 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 e0bf6eed77..3453a0db43 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 2d6456b54b..5dd80fe3ef 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 dc94962954..7d9bbe9e73 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 75775ba502..28e5402834 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 a3339199ef..c6f073058d 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 3bea7e72de..9809aa418d 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 bbdb8b7e9e..3e0ec5802e 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 .= '