diff --git a/.htaccess b/.htaccess
index 83d67e8f8..1b63f9ad6 100644
--- a/.htaccess
+++ b/.htaccess
@@ -12,7 +12,7 @@ Deny from all
# Protect repository directory from browsing
RewriteRule "(^|/)\.git" - [F]
- # Rewrite current-style URLs of the form 'index.php?q=x'.
+ # Rewrite current-style URLs of the form 'index.php?pagename=x'.
# Also place auth information into REMOTE_USER for sites running
# in CGI mode.
@@ -28,7 +28,7 @@ Deny from all
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
- RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
+ RewriteRule ^(.*)$ index.php?pagename=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 000000000..165695f8f
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,29 @@
+Version 3.3.1
+
+ JSONP support for API (fabrixxm)
+ Fixed small bug in direct messages API (fabrixxm)
+ More filter for direct messages API (fabrixxm)
+ New hooks "getsiteinfo", "page_info_data" (annando)
+ Better loop post prevention (annando)
+ Via API, replace data: uri images in plain text version with link to post. (issue #1134) (fabrixxm)
+ Set default location to empty for new users. Suppress warning on user creation (issue #1193) (fabrixxm)
+ Correctly build urls with queries (issue #1190) (fabrixxm)
+ Optionally use keywords in feed as post tags with "remote self" (annando)
+ A blacklist of keywords to not use can be defined (annando)
+ "remote self" works also with Friendica and Diaspora contacts (annando)
+ Show exact post time after 12 hours (FX7)
+ Optionally redirect from non-SSL to SSL (annando)
+ Translation updates
+ Added CHANGELOG
+
+Version 3.3
+
+ See http://friendica.com/node/64
+
+Version 3.2
+
+ See http://friendica.com/node/61
+
+Version 3.1
+
+ See http://friendica.com/node/58
\ No newline at end of file
diff --git a/Vagrantfile b/Vagrantfile
index 033cb230c..48af4ae51 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -1,78 +1,21 @@
-# -*- mode: ruby -*-
-# vi: set ft=ruby :
-# Config Github Settings
-github_username = "fideloper"
-github_repo = "Vaprobash"
-github_branch = "1.0.0"
-github_url = "https://raw.githubusercontent.com/#{github_username}/#{github_repo}/#{github_branch}"
-
-# Server Configuration
-
-hostname = "vaprobash.dev"
-
-# Set a local private network IP address.
-# See http://en.wikipedia.org/wiki/Private_network for explanation
-# You can use the following IP ranges:
-# 10.0.0.1 - 10.255.255.254
-# 172.16.0.1 - 172.31.255.254
-# 192.168.0.1 - 192.168.255.254
server_ip = "192.168.22.10"
server_memory = "384" # MB
-server_swap = "768" # Options: false | int (MB) - Guideline: Between one or two times the server_memory
server_timezone = "UTC"
-# Database Configuration
-mysql_root_password = "root" # We'll assume user "root"
-mysql_version = "5.5" # Options: 5.5 | 5.6
-mysql_enable_remote = "false" # remote access enabled when true
-pgsql_root_password = "root" # We'll assume user "root"
-
-# Languages and Packages6
-ruby_version = "latest" # Choose what ruby version should be installed (will also be the default version)
-ruby_gems = [ # List any Ruby Gems that you want to install
- #"jekyll",
- #"sass",
- #"compass",
-]
-
-# To install HHVM instead of PHP, set this to "true"
-hhvm = "false"
-
-# PHP Options
-composer_packages = [ # List any global Composer packages that you want to install
- #"phpunit/phpunit:4.0.*",
- #"codeception/codeception=*",
- #"phpspec/phpspec:2.0.*@dev",
- #"squizlabs/php_codesniffer:1.5.*",
-]
-
-# Default web server document root
-# Symfony's public directory is assumed "web"
-# Laravel's public directory is assumed "public"
-public_folder = "/vagrant"
-
-laravel_root_folder = "/vagrant/laravel" # Where to install Laravel. Will `composer install` if a composer.json file exists
-laravel_version = "latest-stable" # If you need a specific version of Laravel, set it here
-symfony_root_folder = "/vagrant/symfony" # Where to install Symfony.
-
-nodejs_version = "latest" # By default "latest" will equal the latest stable version
-nodejs_packages = [ # List any global NodeJS packages that you want to install
- #"grunt-cli",
- #"gulp",
- #"bower",
- #"yo",
-]
+public_folder = "/vagrant"
Vagrant.configure("2") do |config|
- # Set server to Ubuntu 14.04
- config.vm.box = "ubuntu/trusty64"
+ # Set server to Ubuntu 12.04
+ config.vm.box = "precise64"
+
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
# Create a hostname, don't forget to put it to the `hosts` file
# This will point to the server's default virtual host
# TO DO: Make this work with virtualhost along-side xip.io URL
- config.vm.hostname = hostname
+ config.vm.hostname = "friendica.dev"
# Create a static IP
config.vm.network :private_network, ip: server_ip
@@ -89,175 +32,28 @@ Vagrant.configure("2") do |config|
vb.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 10000]
# Prevent VMs running on Ubuntu to lose internet connection
- # vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
- # vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
+ vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
+ vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end
# If using VMWare Fusion
config.vm.provider "vmware_fusion" do |vb, override|
override.vm.box_url = "http://files.vagrantup.com/precise64_vmware.box"
-
+
# Set server memory
vb.vmx["memsize"] = server_memory
end
- # If using Vagrant-Cachier
- # http://fgrehm.viewdocs.io/vagrant-cachier
- if Vagrant.has_plugin?("vagrant-cachier")
- # Configure cached packages to be shared between instances of the same base box.
- # Usage docs: http://fgrehm.viewdocs.io/vagrant-cachier/usage
- config.cache.scope = :box
-
- config.cache.synced_folder_opts = {
- type: :nfs,
- mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
- }
- end
-
- ####
- # Base Items
- ##########
-
- # Provision Base Packages
- config.vm.provision "shell", path: "#{github_url}/scripts/base.sh", args: [github_url, server_swap]
-
- # Provision PHP
- config.vm.provision "shell", path: "#{github_url}/scripts/php.sh", args: [server_timezone, hhvm]
-
- # Enable MSSQL for PHP
- # config.vm.provision "shell", path: "#{github_url}/scripts/mssql.sh"
-
- # Provision Vim
- # config.vm.provision "shell", path: "#{github_url}/scripts/vim.sh", args: github_url
-
-
- ####
- # Web Servers
- ##########
-
- # Provision Apache Base
- config.vm.provision "shell", path: "#{github_url}/scripts/apache.sh", args: [server_ip, public_folder, hostname, github_url]
-
- # Provision Nginx Base
- # config.vm.provision "shell", path: "#{github_url}/scripts/nginx.sh", args: [server_ip, public_folder, hostname, github_url]
-
-
- ####
- # Databases
- ##########
-
- # Provision MySQL
- config.vm.provision "shell", path: "#{github_url}/scripts/mysql.sh", args: [mysql_root_password, mysql_version, mysql_enable_remote]
-
- # Provision PostgreSQL
- # config.vm.provision "shell", path: "#{github_url}/scripts/pgsql.sh", args: pgsql_root_password
-
- # Provision SQLite
- # config.vm.provision "shell", path: "#{github_url}/scripts/sqlite.sh"
-
- # Provision RethinkDB
- # config.vm.provision "shell", path: "#{github_url}/scripts/rethinkdb.sh", args: pgsql_root_password
-
- # Provision Couchbase
- # config.vm.provision "shell", path: "#{github_url}/scripts/couchbase.sh"
-
- # Provision CouchDB
- # config.vm.provision "shell", path: "#{github_url}/scripts/couchdb.sh"
-
- # Provision MongoDB
- # config.vm.provision "shell", path: "#{github_url}/scripts/mongodb.sh"
-
- # Provision MariaDB
- # config.vm.provision "shell", path: "#{github_url}/scripts/mariadb.sh", args: [mysql_root_password, mysql_enable_remote]
-
- ####
- # Search Servers
- ##########
-
- # Install Elasticsearch
- # config.vm.provision "shell", path: "#{github_url}/scripts/elasticsearch.sh"
-
- # Install SphinxSearch
- # config.vm.provision "shell", path: "#{github_url}/scripts/sphinxsearch.sh"
-
- ####
- # Search Server Administration (web-based)
- ##########
-
- # Install ElasticHQ
- # Admin for: Elasticsearch
- # Works on: Apache2, Nginx
- # config.vm.provision "shell", path: "#{github_url}/scripts/elastichq.sh"
-
-
- ####
- # In-Memory Stores
- ##########
-
- # Install Memcached
- # config.vm.provision "shell", path: "#{github_url}/scripts/memcached.sh"
-
- # Provision Redis (without journaling and persistence)
- # config.vm.provision "shell", path: "#{github_url}/scripts/redis.sh"
-
- # Provision Redis (with journaling and persistence)
- # config.vm.provision "shell", path: "#{github_url}/scripts/redis.sh", args: "persistent"
- # NOTE: It is safe to run this to add persistence even if originally provisioned without persistence
-
-
- ####
- # Utility (queue)
- ##########
-
- # Install Beanstalkd
- # config.vm.provision "shell", path: "#{github_url}/scripts/beanstalkd.sh"
-
- # Install Heroku Toolbelt
- # config.vm.provision "shell", path: "https://toolbelt.heroku.com/install-ubuntu.sh"
-
- # Install Supervisord
- # config.vm.provision "shell", path: "#{github_url}/scripts/supervisord.sh"
-
- ####
- # Additional Languages
- ##########
-
- # Install Nodejs
- # config.vm.provision "shell", path: "#{github_url}/scripts/nodejs.sh", privileged: false, args: nodejs_packages.unshift(nodejs_version, github_url)
-
- # Install Ruby Version Manager (RVM)
- # config.vm.provision "shell", path: "#{github_url}/scripts/rvm.sh", privileged: false, args: ruby_gems.unshift(ruby_version)
-
- ####
- # Frameworks and Tooling
- ##########
-
- # Provision Composer
- # config.vm.provision "shell", path: "#{github_url}/scripts/composer.sh", privileged: false, args: composer_packages.join(" ")
-
- # Provision Laravel
- # config.vm.provision "shell", path: "#{github_url}/scripts/laravel.sh", privileged: false, args: [server_ip, laravel_root_folder, public_folder, laravel_version]
-
- # Provision Symfony
- # config.vm.provision "shell", path: "#{github_url}/scripts/symfony.sh", privileged: false, args: [server_ip, symfony_root_folder, public_folder]
-
- # Install Screen
- # config.vm.provision "shell", path: "#{github_url}/scripts/screen.sh"
-
- # Install config Mailcatcher
- # config.vm.provision "shell", path: "#{github_url}/scripts/mailcatcher.sh"
-
- # Install git-ftp
- # config.vm.provision "shell", path: "#{github_url}/scripts/git-ftp.sh", privileged: false
-
+
####
# Local Scripts
# Any local scripts you may want to run post-provisioning.
# Add these to the same directory as the Vagrantfile.
##########
- config.vm.provision "shell", path: "./util/vagrant_provision.sh"
+
config.vm.synced_folder "./", "/vagrant/", :owner=> 'www-data', :group=>'vagrant', :mount_options => ['dmode=775', 'fmode=775']
+ config.vm.provision "shell", path: "./util/vagrant_provision.sh"
end
diff --git a/boot.php b/boot.php
index 5ef24f494..44d72bb3c 100644
--- a/boot.php
+++ b/boot.php
@@ -11,10 +11,14 @@ require_once('include/cache.php');
require_once('library/Mobile_Detect/Mobile_Detect.php');
require_once('include/features.php');
+require_once('update.php');
+require_once('include/dbstructure.php');
+
define ( 'FRIENDICA_PLATFORM', 'Friendica');
-define ( 'FRIENDICA_VERSION', '3.2.1753' );
+define ( 'FRIENDICA_CODENAME', 'Ginger');
+define ( 'FRIENDICA_VERSION', '3.3.1' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
-define ( 'DB_UPDATE_VERSION', 1173 );
+define ( 'DB_UPDATE_VERSION', 1175 );
define ( 'EOL', " \r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
@@ -505,27 +509,41 @@ if(! class_exists('App')) {
$argc --;
}
- set_include_path("include/$this->hostname" . PATH_SEPARATOR . get_include_path());
+ #set_include_path("include/$this->hostname" . PATH_SEPARATOR . get_include_path());
- if((x($_SERVER,'QUERY_STRING')) && substr($_SERVER['QUERY_STRING'],0,2) === "q=") {
+ if((x($_SERVER,'QUERY_STRING')) && substr($_SERVER['QUERY_STRING'],0,9) === "pagename=") {
+ $this->query_string = substr($_SERVER['QUERY_STRING'],9);
+ // removing trailing / - maybe a nginx problem
+ if (substr($this->query_string, 0, 1) == "/")
+ $this->query_string = substr($this->query_string, 1);
+ } elseif((x($_SERVER,'QUERY_STRING')) && substr($_SERVER['QUERY_STRING'],0,2) === "q=") {
$this->query_string = substr($_SERVER['QUERY_STRING'],2);
// removing trailing / - maybe a nginx problem
if (substr($this->query_string, 0, 1) == "/")
$this->query_string = substr($this->query_string, 1);
}
- if(x($_GET,'q'))
+
+ if (x($_GET,'pagename'))
+ $this->cmd = trim($_GET['pagename'],'/\\');
+ elseif (x($_GET,'q'))
$this->cmd = trim($_GET['q'],'/\\');
+
+ // fix query_string
+ $this->query_string = str_replace($this->cmd."&",$this->cmd."?", $this->query_string);
+
+
// unix style "homedir"
if(substr($this->cmd,0,1) === '~')
- $this->cmd = 'profile/' . substr($this->cmd,1);
+ $this->cmd = 'profile/' . substr($this->cmd,1);
// Diaspora style profile url
if(substr($this->cmd,0,2) === 'u/')
$this->cmd = 'profile/' . substr($this->cmd,2);
+
/**
*
* Break the URL path into C style argc/argv style arguments for our
@@ -598,6 +616,10 @@ if(! class_exists('App')) {
return($basepath);
}
+ function get_scheme() {
+ return($this->scheme);
+ }
+
function get_baseurl($ssl = false) {
$scheme = $this->scheme;
@@ -617,6 +639,9 @@ if(! class_exists('App')) {
}
}
+ if (get_config('config','hostname') != "")
+ $this->hostname = get_config('config','hostname');
+
$this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
return $this->baseurl;
}
@@ -638,12 +663,19 @@ if(! class_exists('App')) {
if (file_exists(".htpreconfig.php"))
@include(".htpreconfig.php");
- $this->hostname = $hostname;
+ if (get_config('config','hostname') != "")
+ $this->hostname = get_config('config','hostname');
+
+ if (!isset($this->hostname) OR ($this->hostname == ""))
+ $this->hostname = $hostname;
}
}
function get_hostname() {
+ if (get_config('config','hostname') != "")
+ $this->hostname = get_config('config','hostname');
+
return $this->hostname;
}
@@ -789,7 +821,7 @@ if(! class_exists('App')) {
}
if ($name===""){
echo "template engine $class cannot be registered without a name.\n";
- killme();
+ killme();
}
$this->template_engines[$name] = $class;
}
@@ -797,7 +829,7 @@ if(! class_exists('App')) {
/**
* return template engine instance. If $name is not defined,
* return engine defined by theme, or default
- *
+ *
* @param strin $name Template engine name
* @return object Template Engine instance
*/
@@ -865,6 +897,10 @@ if(! class_exists('App')) {
$this->performance["markstart"] = microtime(true) - $this->performance["markstart"] - $this->performance["marktime"];
}
+ function get_useragent() {
+ return(FRIENDICA_PLATFORM." '".FRIENDICA_CODENAME."' ".FRIENDICA_VERSION."-".DB_UPDATE_VERSION."; ".$this->get_baseurl());
+ }
+
}
}
@@ -992,7 +1028,6 @@ if(! function_exists('check_url')) {
if(! function_exists('update_db')) {
function update_db(&$a) {
-
$build = get_config('system','build');
if(! x($build))
$build = set_config('system','build',DB_UPDATE_VERSION);
@@ -1000,99 +1035,51 @@ if(! function_exists('update_db')) {
if($build != DB_UPDATE_VERSION) {
$stored = intval($build);
$current = intval(DB_UPDATE_VERSION);
- if(($stored < $current) && file_exists('update.php')) {
-
+ if($stored < $current) {
load_config('database');
// We're reporting a different version than what is currently installed.
// Run any existing update scripts to bring the database up to current.
- require_once('update.php');
-
// make sure that boot.php and update.php are the same release, we might be
// updating right this very second and the correct version of the update.php
// file may not be here yet. This can happen on a very busy site.
if(DB_UPDATE_VERSION == UPDATE_VERSION) {
-
// Compare the current structure with the defined structure
$t = get_config('database','dbupdate_'.DB_UPDATE_VERSION);
if($t !== false)
- break;
+ return;
+
set_config('database','dbupdate_'.DB_UPDATE_VERSION, time());
- require_once("include/dbstructure.php");
+ // run old update routine (wich could modify the schema and
+ // conflits with new routine)
+ for ($x = $stored; $x < NEW_UPDATE_ROUTINE_VERSION; $x++) {
+ $r = run_update_function($x);
+ if (!$r) break;
+ }
+ if ($stored < NEW_UPDATE_ROUTINE_VERSION) $stored = NEW_UPDATE_ROUTINE_VERSION;
+
+
+ // run new update routine
+ // it update the structure in one call
$retval = update_structure(false, true);
if($retval) {
- //send the administrator an e-mail
- $email_tpl = get_intltext_template("update_fail_eml.tpl");
- $email_msg = replace_macros($email_tpl, array(
- '$sitename' => $a->config['sitename'],
- '$siteurl' => $a->get_baseurl(),
- '$update' => DB_UPDATE_VERSION,
- '$error' => sprintf(t('Update %s failed. See error logs.'), DB_UPDATE_VERSION)
- ));
- $subject=sprintf(t('Update Error at %s'), $a->get_baseurl());
- require_once('include/email.php');
- $subject = email_header_encode($subject,'UTF-8');
- mail($a->config['admin_email'], $subject, $email_msg,
- 'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME']."\n"
- .'Content-type: text/plain; charset=UTF-8'."\n"
- .'Content-transfer-encoding: 8bit');
- //try the logger
- logger("CRITICAL: Database structure update failed: ".$retval);
- break;
- } else
+ update_fail(
+ DB_UPDATE_VERSION,
+ $retval
+ );
+ return;
+ } else {
set_config('database','dbupdate_'.DB_UPDATE_VERSION, 'success');
+ }
+ // run any left update_nnnn functions in update.php
for($x = $stored; $x < $current; $x ++) {
- if(function_exists('update_' . $x)) {
-
- // There could be a lot of processes running or about to run.
- // We want exactly one process to run the update command.
- // So store the fact that we're taking responsibility
- // after first checking to see if somebody else already has.
-
- // If the update fails or times-out completely you may need to
- // delete the config entry to try again.
-
- $t = get_config('database','update_' . $x);
- if($t !== false)
- break;
- set_config('database','update_' . $x, time());
-
- // call the specific update
-
- $func = 'update_' . $x;
- $retval = $func();
- if($retval) {
- //send the administrator an e-mail
- $email_tpl = get_intltext_template("update_fail_eml.tpl");
- $email_msg = replace_macros($email_tpl, array(
- '$sitename' => $a->config['sitename'],
- '$siteurl' => $a->get_baseurl(),
- '$update' => $x,
- '$error' => sprintf( t('Update %s failed. See error logs.'), $x)
- ));
- $subject=sprintf(t('Update Error at %s'), $a->get_baseurl());
- require_once('include/email.php');
- $subject = email_header_encode($subject,'UTF-8');
- mail($a->config['admin_email'], $subject, $email_msg,
- 'From: ' . 'Administrator' . '@' . $_SERVER['SERVER_NAME'] . "\n"
- . 'Content-type: text/plain; charset=UTF-8' . "\n"
- . 'Content-transfer-encoding: 8bit' );
- //try the logger
- logger('CRITICAL: Update Failed: '. $x);
- break;
- } else {
- set_config('database','update_' . $x, 'success');
- set_config('system','build', $x + 1);
- }
- } else {
- set_config('database','update_' . $x, 'success');
- set_config('system','build', $x + 1);
- }
+ $r = run_update_function($x);
+ if (!$r) break;
}
}
}
@@ -1101,6 +1088,48 @@ if(! function_exists('update_db')) {
return;
}
}
+if(!function_exists('run_update_function')){
+ function run_update_function($x) {
+ if(function_exists('update_' . $x)) {
+
+ // There could be a lot of processes running or about to run.
+ // We want exactly one process to run the update command.
+ // So store the fact that we're taking responsibility
+ // after first checking to see if somebody else already has.
+
+ // If the update fails or times-out completely you may need to
+ // delete the config entry to try again.
+
+ $t = get_config('database','update_' . $x);
+ if($t !== false)
+ return false;
+ set_config('database','update_' . $x, time());
+
+ // call the specific update
+
+ $func = 'update_' . $x;
+ $retval = $func();
+
+ if($retval) {
+ //send the administrator an e-mail
+ update_fail(
+ $x,
+ sprintf(t('Update %s failed. See error logs.'), $x)
+ );
+ return false;
+ } else {
+ set_config('database','update_' . $x, 'success');
+ set_config('system','build', $x + 1);
+ return true;
+ }
+ } else {
+ set_config('database','update_' . $x, 'success');
+ set_config('system','build', $x + 1);
+ return true;
+ }
+ return true;
+ }
+}
if(! function_exists('check_plugins')) {
@@ -1209,7 +1238,7 @@ if(! function_exists('login')) {
}
$noid = get_config('system','no_openid');
-
+
$dest_url = $a->get_baseurl(true) . '/' . $a->query_string;
if(local_user()) {
@@ -1230,18 +1259,18 @@ if(! function_exists('login')) {
'$dest_url' => $dest_url,
'$logout' => t('Logout'),
'$login' => t('Login'),
-
+
'$lname' => array('username', t('Nickname or Email address: ') , '', ''),
'$lpassword' => array('password', t('Password: '), '', ''),
'$lremember' => array('remember', t('Remember me'), 0, ''),
-
+
'$openid' => !$noid,
'$lopenid' => array('openid_url', t('Or login using OpenID: '),'',''),
-
+
'$hiddens' => $hiddens,
-
+
'$register' => $reg,
-
+
'$lostpass' => t('Forgot your password?'),
'$lostlink' => t('Password Reset'),
@@ -1304,9 +1333,9 @@ if(! function_exists('remote_user')) {
if(! function_exists('notice')) {
/**
* Show an error message to user.
- *
+ *
* This function save text in session, to be shown to the user at next page load
- *
+ *
* @param string $s - Text of notice
*/
function notice($s) {
@@ -1319,9 +1348,9 @@ if(! function_exists('notice')) {
if(! function_exists('info')) {
/**
* Show an info message to user.
- *
+ *
* This function save text in session, to be shown to the user at next page load
- *
+ *
* @param string $s - Text of notice
*/
function info($s) {
@@ -1745,7 +1774,7 @@ if(! function_exists('get_birthdays')) {
$rr['date'] = day_translate(datetime_convert('UTC', $a->timezone, $rr['start'], $rr['adjust'] ? $bd_format : $bd_short)) . (($today) ? ' ' . t('[today]') : '');
$rr['startime'] = Null;
$rr['today'] = $today;
-
+
}
}
}
@@ -1820,7 +1849,7 @@ if(! function_exists('get_events')) {
$strt = datetime_convert('UTC',$rr['convert'] ? $a->timezone : 'UTC',$rr['start']);
$today = ((substr($strt,0,10) === datetime_convert('UTC',$a->timezone,'now','Y-m-d')) ? true : false);
-
+
$rr['link'] = $md;
$rr['title'] = $title;
$rr['date'] = day_translate(datetime_convert('UTC', $rr['adjust'] ? $a->timezone : 'UTC', $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
@@ -1880,7 +1909,7 @@ if(! function_exists('proc_run')) {
}
$args = $newargs;
-
+
$arr = array('args' => $args, 'run_cmd' => true);
call_hooks("proc_run", $arr);
@@ -1889,14 +1918,14 @@ if(! function_exists('proc_run')) {
if(count($args) && $args[0] === 'php')
$args[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
-
+
// add baseurl to args. cli scripts can't construct it
$args[] = $a->get_baseurl();
-
+
for($x = 0; $x < count($args); $x ++)
$args[$x] = escapeshellarg($args[$x]);
-
+
$cmdline = implode($args," ");
if(get_config('system','proc_windows'))
@@ -1909,9 +1938,9 @@ if(! function_exists('proc_run')) {
if(! function_exists('current_theme')) {
function current_theme(){
$app_base_themes = array('duepuntozero', 'dispy', 'quattro');
-
+
$a = get_app();
-
+
// $mobile_detect = new Mobile_Detect();
// $is_mobile = $mobile_detect->isMobile() || $mobile_detect->isTablet();
$is_mobile = $a->is_mobile || $a->is_tablet;
@@ -1941,17 +1970,17 @@ if(! function_exists('current_theme')) {
(file_exists('view/theme/' . $theme_name . '/style.css') ||
file_exists('view/theme/' . $theme_name . '/style.php')))
return($theme_name);
-
+
foreach($app_base_themes as $t) {
if(file_exists('view/theme/' . $t . '/style.css')||
file_exists('view/theme/' . $t . '/style.php'))
return($t);
}
-
+
$fallback = array_merge(glob('view/theme/*/style.css'),glob('view/theme/*/style.php'));
if(count($fallback))
return (str_replace('view/theme/','', substr($fallback[0],0,-10)));
-
+
}
}
@@ -1991,7 +2020,7 @@ if(! function_exists('feed_birthday')) {
*
*/
-
+
$birthday = '';
if(! strlen($tz))
@@ -2061,13 +2090,13 @@ if(! function_exists('load_contact_links')) {
if(! function_exists('profile_tabs')){
function profile_tabs($a, $is_owner=False, $nickname=Null){
//echo "
"; var_dump($a->user); killme();
-
+
if (is_null($nickname))
$nickname = $a->user['nickname'];
-
+
if(x($_GET,'tab'))
$tab = notags(trim($_GET['tab']));
-
+
$url = $a->get_baseurl() . '/profile/' . $nickname;
$tabs = array(
@@ -2100,7 +2129,7 @@ if(! function_exists('profile_tabs')){
'id' => 'video-tab',
),
);
-
+
if ($is_owner){
$tabs[] = array(
'label' => t('Events'),
@@ -2121,7 +2150,7 @@ if(! function_exists('profile_tabs')){
$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
call_hooks('profile_tabs', $arr);
-
+
$tpl = get_markup_template('common_tabs.tpl');
return replace_macros($tpl,array('$tabs' => $arr['tabs']));
@@ -2160,28 +2189,28 @@ function zrl($s,$force = false) {
/**
* returns querystring as string from a mapped array
*
-* @param params Array
+* @param params Array
* @return string
*/
-function build_querystring($params, $name=null) {
- $ret = "";
+function build_querystring($params, $name=null) {
+ $ret = "";
foreach($params as $key=>$val) {
- if(is_array($val)) {
+ if(is_array($val)) {
if($name==null) {
- $ret .= build_querystring($val, $key);
+ $ret .= build_querystring($val, $key);
} else {
- $ret .= build_querystring($val, $name."[$key]");
+ $ret .= build_querystring($val, $name."[$key]");
}
} else {
$val = urlencode($val);
if($name!=null) {
- $ret.=$name."[$key]"."=$val&";
+ $ret.=$name."[$key]"."=$val&";
} else {
- $ret.= "$key=$val&";
+ $ret.= "$key=$val&";
}
- }
- }
- return $ret;
+ }
+ }
+ return $ret;
}
function explode_querystring($query) {
diff --git a/doc/FAQ.md b/doc/FAQ.md
index c3c3e8bc2..6fa852e0b 100644
--- a/doc/FAQ.md
+++ b/doc/FAQ.md
@@ -12,6 +12,7 @@ User
* **[What happens when an account is removed? Is it truly deleted?](help/FAQ#removed)**
* **[Can I subscribe to a hashtag?](help/FAQ#hashtag)**
* **[How to create a RSS feed of the stream?](help/FAQ#rss)**
+* **[Are there any clients for friendica I can use?](help/FAQ#clients)**
* **[Where I can find help?](help/FAQ#help)**
Admins
@@ -39,7 +40,6 @@ Sometimes you get a browser warning about a missing certificate. These warnings
If you dont have a SSL cert yet, there are three ways to get one: buy one, get a free one (eg. via StartSSL) or create your own (not recommended). [You can find more information about setting up SSL and why it's a bad idea to use self-signed SSL here.](help/SSL)
Be aware that a browser warning about security issues is something that can make new users feel insecure about the whole friendica project.
-Because of this, Friendica Red will only accept SSL certs signed by a recognized CA and doesn't connect to servers without these kind of SSL. Despite of the negative aspects of SSL, this is a necessary solution until there is an established alternative for this technique.
Also you can have problems with the connection to diaspora because some pods require a SSL-certificated connection.
@@ -130,14 +130,33 @@ RSS feed of the conversations at your site
https://helpers.pyxis.uberspace.de/dfrn_poll/helpers/converse
+
+
+**Are there any clients for friendica I can use?**
+
+Friendica is using a [Twitter/StatusNet compatible API](help/api), which means you can use any Twitter/StatusNet/GNU Social client for your plattform as long as you can change the API path in its settings. Here is a list of known working clients
+
+* Android
+ * Friendica Client for Android
+ * AndStatus
+ * Twidere
+ * Mustard and Mustard-Mod
+* Linux
+ * Hotot
+ * Choqok
+* MacOS X
+ * Hotot
+* Windows
+ * Hotot
+
+Depending on the features of the client you might encounter some glitches in usability, like being limited in the length of your postings to 140 characters and having no access to the [permission settings](help/Groups-and-Privacy).
+
**Where I can find help?**
If you have problems with your Friendica page, you can ask the community at the [Friendica Support Group](https://helpers.pyxis.uberspace.de/profile/helpers). If you can't use your default profile you can either use a test account [test server](http://friendica.com/node/31) respectively an account at a public site [list](http://dir.friendica.com/siteinfo) or you can use the Librelist mailing list. If you want to use the mailing list, please just send a mail to friendica AT librelist DOT com.
-If you are using Friendica Red, you will also find help at this forum: [Friendica Red Development](https://myfriendica.net/profile/friendicared).
-
If you are a theme developer, you will find help at this forum: [Friendica Theme Developers](https://friendica.eu/profile/ftdevs).
Admin
@@ -147,14 +166,14 @@ Admin
**Can I configure multiple domains with the same code instance?**
-You can do that. What you can't do is point two different domains at the same database. As long as .htconfig.php exists to keep it from trying to do an install, you can keep the real config in include/$hostname/.htconfig.php All of the cache and lock stuff can be configured per instance.
+This function is not supported anymore starting from Friendica 3.3
**Where can I find the source code of friendica, addons and themes?**
-You can find the main respository [here](https://github.com/friendica/friendica). There you will always find the current stable version of friendica. The source files of Friendica Red are [here](https://github.com/friendica/red).
+You can find the main respository [here](https://github.com/friendica/friendica). There you will always find the current stable version of friendica.
Addons are listed at [this page](https://github.com/friendica/friendica-addons).
-If you are searching for new themes, you can find them at [Friendica-Themes.com](http://friendica-themes.com/)
\ No newline at end of file
+If you are searching for new themes, you can find them at [Friendica-Themes.com](http://friendica-themes.com/)
diff --git a/doc/Home.md b/doc/Home.md
index 86a4eb647..6020f2c01 100644
--- a/doc/Home.md
+++ b/doc/Home.md
@@ -33,6 +33,8 @@ Friendica Documentation and Resources
* [Message Flow](help/Message-Flow)
* [Using SSL with Friendica](help/SSL)
* [Developers](help/Developers)
+* [Twitter/StatusNet API Functions](help/api)
+* [Translation of Friendica](help/translations)
**External Resources**
diff --git a/doc/Improve-Performance.md b/doc/Improve-Performance.md
index ceed6fcab..d4c94d2d1 100644
--- a/doc/Improve-Performance.md
+++ b/doc/Improve-Performance.md
@@ -70,19 +70,6 @@ This plugin reduces the database load massively. Downside: You can't see the tot
Go to the admin settings of "altpager" and set it to "global".
-###Privacy Image Cache
-
-**Description**
-
-This plugin pre-fetches external content and stores it in the cache. Besides speeding up the page rendering it is also good for the privacy of your users, since embedded pictures are loaded from your site and not from a foreign site (that could spy on the IP addresses).
-
-Additionally it helps with content from external sites that have slow performance or aren not online all the time.
-
-**Administration**
-
-Please create a folder named "privacy_image_cache" and "photo" in your web root. If these folders exists then the cached files will be stored there. This has the great advantage that your web server will fetch the files directly from there.
-
-
###rendertime
This plugin doesn't speed up your system. It helps analyzing your bottlenecks.
diff --git a/doc/Making-Friends.md b/doc/Making-Friends.md
index 70b87abbc..e0b1a254e 100644
--- a/doc/Making-Friends.md
+++ b/doc/Making-Friends.md
@@ -5,9 +5,7 @@ Making Friends
Friendship in Friendica can take on a great many different meanings. But let's keep it simple, you want to be friends with somebody. How do you do it?
-The easiest thing to do is to join the New Here group. This group is especially for people new to the Friendica network. Simply connect to the group, post to the wall, and make new friends. You don't even have to like us - comment on a few of our posts, and other people will start to add you too.
-
-The next thing you can do is look at the Directory. The directory is split up into two parts. If you click the directory button, you will be presented with a list of all members (who chose to be listed) on your server. You'll also see a link to the Global Directory. If you click through to the global directory, you will be presented with a list of everybody who chose to be listed across all instances of Friendica. You will also see a "Show Community Forums" link, which will direct you to Groups, Forums and Fanpages. You connect to people, groups and forums in the same way, except groups and forums will automatically accept your introduction request, whereas a human will approve you manually.
+The first thing you can do is look at the Directory. The directory is split up into two parts. If you click the directory button, you will be presented with a list of all members (who chose to be listed) on your server. You'll also see a link to the Global Directory. If you click through to the global directory, you will be presented with a list of everybody who chose to be listed across all instances of Friendica. You will also see a "Show Community Forums" link, which will direct you to Groups, Forums and Fanpages. You connect to people, groups and forums in the same way, except groups and forums will automatically accept your introduction request, whereas a human will approve you manually.
To connect with other Friendica users:
diff --git a/doc/andfinally.md b/doc/andfinally.md
index c4e8cb948..f7aeb1bd4 100644
--- a/doc/andfinally.md
+++ b/doc/andfinally.md
@@ -7,12 +7,8 @@ Here are some more things to help get you started:
**Groups**
-- New Here - a group for people new to Friendica
-
- Friendica Support - problems? This is the place to ask.
-- Public Stream - a place to talk about anything to anyone.
-
- Let's Talk a group for finding people and groups who share similar interests.
- Local Friendica a page for local Friendica groups
diff --git a/doc/api.md b/doc/api.md
new file mode 100644
index 000000000..f36a79a5e
--- /dev/null
+++ b/doc/api.md
@@ -0,0 +1,362 @@
+The friendica API aims to be compatible to the [StatusNet API](http://status.net/wiki/Twitter-compatible_API) which aims to be compatible to the [Twitter API 1.0](https://dev.twitter.com/docs/api/1).
+
+Please refer to the linked documentation for further information.
+
+## Implemented API calls
+
+### General
+#### Unsupported parameters
+* cursor: Not implemented in StatusNet
+* trim_user: Not implemented in StatusNet
+* contributor_details: Not implemented in StatusNet
+* place_id: Not implemented in StatusNet
+* display_coordinates: Not implemented in StatusNet
+* include_rts: To-Do
+* include_my_retweet: Retweets in friendica are implemented in a different way
+
+#### Different behaviour
+* screen_name: The nick name in friendica is only unique in each network but not for all networks. The users are searched in the following priority: Friendica, StatusNet/GNU Social, Diaspora, pump.io, Twitter. If no contact was found by this way, then the first contact is taken.
+* include_entities: Default is "false". If set to "true" then the plain text is formatted so that links are having descriptions.
+
+#### Return values
+* cid: Contact id of the user (important for "contact_allow" and "contact_deny")
+* network: network of the user
+
+### account/verify_credentials
+#### Parameters
+* skip_status: Don't show the "status" field. (Default: false)
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+### statuses/update, statuses/update_with_media
+#### Parameters
+* title: Title of the status
+* status: Status in text format
+* htmlstatus: Status in HTML format
+* in_reply_to_status_id
+* lat: latitude
+* long: longitude
+* media: image data
+* source: Application name
+* group_allow
+* contact_allow
+* group_deny
+* contact_deny
+* network
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* trim_user
+* place_id
+* display_coordinates
+
+### users/search
+#### Parameters
+* q: name of the user
+
+#### Unsupported parameters
+* page
+* count
+* include_entities
+
+### users/show
+#### Parameters
+* user_id: id of the user
+* screen_name: screen name (for technical reasons, this value is not unique!)
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+### statuses/home_timeline
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* exclude_replies: don't show replies (default: false)
+* conversation_id: Shows all statuses of a given conversation.
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* include_rts
+* trim_user
+* contributor_details
+
+### statuses/friends_timeline
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* exclude_replies: don't show replies (default: false)
+* conversation_id: Shows all statuses of a given conversation.
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* include_rts
+* trim_user
+* contributor_details
+
+### statuses/public_timeline
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* exclude_replies: don't show replies (default: false)
+* conversation_id: Shows all statuses of a given conversation.
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* trim_user
+
+### statuses/show
+#### Parameters
+* id: message number
+* conversation: if set to "1" show all messages of the conversation with the given id
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* include_my_retweet
+* trim_user
+
+### statuses/retweet
+#### Parameters
+* id: message number
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* trim_user
+
+### statuses/destroy
+#### Parameters
+* id: message number
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* trim_user
+
+### statuses/mentions
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* include_rts
+* trim_user
+* contributor_details
+
+### statuses/replies
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* include_rts
+* trim_user
+* contributor_details
+
+### statuses/user_timeline
+#### Parameters
+* user_id: id of the user
+* screen_name: screen name (for technical reasons, this value is not unique!)
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* exclude_replies: don't show replies (default: false)
+* conversation_id: Shows all statuses of a given conversation.
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* include_rts
+* trim_user
+* contributor_details
+
+### conversation/show
+Unofficial Twitter command. It shows all direct answers (excluding the original post) to a given id.
+
+#### Parameters
+* id: id of the post
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* include_rts
+* trim_user
+* contributor_details
+
+### favorites
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* user_id
+* screen_name
+
+Favorites aren't displayed to other users, so "user_id" and "screen_name". So setting this value will result in an empty array.
+
+### account/rate_limit_status
+
+### help/test
+
+### statuses/friends
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* user_id
+* screen_name
+* cursor
+
+Friendica doesn't allow showing friends of other users.
+
+### statuses/followers
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* user_id
+* screen_name
+* cursor
+
+Friendica doesn't allow showing followers of other users.
+
+### statusnet/config
+
+### statusnet/version
+
+### friends/ids
+#### Parameters
+* stringify_ids: Should the id numbers be sent as text (true) or number (false)? (default: false)
+
+#### Unsupported parameters
+* user_id
+* screen_name
+* cursor
+
+Friendica doesn't allow showing friends of other users.
+
+### followers/ids
+#### Parameters
+* stringify_ids: Should the id numbers be sent as text (true) or number (false)? (default: false)
+
+#### Unsupported parameters
+* user_id
+* screen_name
+* cursor
+
+Friendica doesn't allow showing followers of other users.
+
+### direct_messages/new
+#### Parameters
+* user_id: id of the user
+* screen_name: screen name (for technical reasons, this value is not unique!)
+* text: The message
+* replyto: ID of the replied direct message
+* title: Title of the direct message
+
+### direct_messages/conversation
+Shows all direct messages of a conversation
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* getText: Defines the format of the status field. Can be "html" or "plain"
+* uri: URI of the conversation
+
+### direct_messages/all
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* getText: Defines the format of the status field. Can be "html" or "plain"
+
+### direct_messages/sent
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* getText: Defines the format of the status field. Can be "html" or "plain"
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+### direct_messages
+#### Parameters
+* count: Items per page (default: 20)
+* page: page number
+* since_id: minimal id
+* max_id: maximum id
+* getText: Defines the format of the status field. Can be "html" or "plain"
+* include_entities: "true" shows entities for pictures and links (Default: false)
+
+#### Unsupported parameters
+* skip_status
+
+### oauth/request_token
+#### Parameters
+* oauth_callback
+
+#### Unsupported parameters
+* x_auth_access_type
+
+### oauth/access_token
+#### Parameters
+* oauth_verifier
+
+#### Unsupported parameters
+* x_auth_password
+* x_auth_username
+* x_auth_mode
+
+## Not Implemented API calls
+The following list is extracted from the [API source file](https://github.com/friendica/friendica/blob/master/include/api.php) (at the very bottom):
+* favorites/create
+* favorites/destroy
+* statuses/retweets_of_me
+* friendships/create
+* friendships/destroy
+* friendships/exists
+* friendships/show
+* account/update_location
+* account/update_profile_background_image
+* account/update_profile_image
+* blocks/create
+* blocks/destroy
+
+The following are things from the Twitter API also not implemented in StatusNet:
+* statuses/retweeted_to_me
+* statuses/retweeted_by_me
+* direct_messages/destroy
+* account/end_session
+* account/update_delivery_device
+* notifications/follow
+* notifications/leave
+* blocks/exists
+* blocks/blocking
+* lists
+
+## Usage Examples
+### BASH / cURL
+Betamax has documentated some example API usage from a [bash script](https://en.wikipedia.org/wiki/Bash_(Unix_shell) employing [curl](https://en.wikipedia.org/wiki/CURL) (see [his posting](https://betamax65.de/display/betamax65/43539)).
+
+ /usr/bin/curl -u USER:PASS https://YOUR.FRIENDICA.TLD/api/statuses/update.xml -d source="some source id" -d status="the status you want to post"
+
+### Python
+The [RSStoFriedika](https://github.com/pafcu/RSStoFriendika) code can be used as an example of how to use the API with python. The lines for posting are located at [line 21](https://github.com/pafcu/RSStoFriendika/blob/master/RSStoFriendika.py#L21) and following.
+
+ def tweet(server, message, group_allow=None):
+ url = server + '/api/statuses/update'
+ urllib2.urlopen(url, urllib.urlencode({'status': message,'group_allow[]':group_allow}, doseq=True))
+
+There is also a [module for python 3](https://bitbucket.org/tobiasd/python-friendica) for using the API.
\ No newline at end of file
diff --git a/doc/de/Home.md b/doc/de/Home.md
index fee7b6a58..0fd5634cc 100644
--- a/doc/de/Home.md
+++ b/doc/de/Home.md
@@ -33,6 +33,8 @@ Friendica - Dokumentation und Ressourcen
* [Nachrichtenfluss](help/Message-Flow)
* [Betreibe deine Seite mit einem SSL-Zertifikat](help/SSL)
* [Entwickler](help/Developers)
+* [Twitter/StatusNet API Functions](help/api) (EN)
+* [Translation of Friendica](help/translations) (EN)
**Externe Ressourcen**
diff --git a/doc/de/Improve-Performance.md b/doc/de/Improve-Performance.md
index fe9912334..346c76fc3 100644
--- a/doc/de/Improve-Performance.md
+++ b/doc/de/Improve-Performance.md
@@ -12,7 +12,7 @@ Wenn du Fragen zu den folgenden Anweisungen oder zu anderen Themen hast, dann ka
Systemeinstellungen
---------------
-Geh auf /admin/site in deinem System und ändere die folgenden Werte:
+Geh auf /admin/site in deinem System und ändere die folgenden Werte:
setze "Qualität des JPEG Bildes" auf 50.
@@ -36,20 +36,20 @@ Wenn du MyISAM (Standardeinstellung) nutzt, dann beschleunigt dies die Suche.
setze "Pfad zum Eintrag Cache" auf einen leeren Ordner außerhalb deines Stammverzeichnisses.
-Verarbeiteter BBCode und einige externe Bilder werden hier gespeichert. BBCode verarbeiten ist ein zeitintensiver Prozess, der zudem eine hohe CPU-Leistung erfordert.
+Verarbeiteter BBCode und einige externe Bilder werden hier gespeichert. BBCode verarbeiten ist ein zeitintensiver Prozess, der zudem eine hohe CPU-Leistung erfordert.
-Du kannst den gleichen Ordner nutzen, den du für die Sperrdatei genutzt hast.
+Du kannst den gleichen Ordner nutzen, den du für die Sperrdatei genutzt hast.
**Warnung!**
-Der Ordner für den Eintrag-Cache wird regelmäßig geleert. Jede Datei, die die Cache-Dauer überschreitet, wird gelöscht. **Wenn du versehentlich den Cache-Pfad auf dein Stammverzeichnis legst, dann würde dir dies das gesamte Stammverzeichnis löschen.**
+Der Ordner für den Eintrag-Cache wird regelmäßig geleert. Jede Datei, die die Cache-Dauer überschreitet, wird gelöscht. **Wenn du versehentlich den Cache-Pfad auf dein Stammverzeichnis legst, dann würde dir dies das gesamte Stammverzeichnis löschen.**
-Prüfe also doppelt, dass der gewählte Ordner nur temporäre Dateien enthält, die jederzeit gelöscht werden können.
+Prüfe also doppelt, dass der gewählte Ordner nur temporäre Dateien enthält, die jederzeit gelöscht werden können.
Plugins
--------
-Aktiviere die folgenden Plugins:
+Aktiviere die folgenden Plugins:
Alternate Pagination
Privacy Image Cache
@@ -59,29 +59,17 @@ Aktiviere die folgenden Plugins:
**Beschreibung**
-Dieses Plugin reduziert die Ladezeit der Datenbank massiv. Nachteil: Du kannst nicht mehr die Anzahl aller Seiten sehen.
+Dieses Plugin reduziert die Ladezeit der Datenbank massiv. Nachteil: Du kannst nicht mehr die Anzahl aller Seiten sehen.
**Einrichtung**
Gehe auf admin/plugins/altpager und wähle "global".
-###Privacy Image Cache
-
-**Beschreibung**
-
-Dieses Plugin lädt externe Inhalte vor und speichert sie im Cache. Neben der Beschleunigung der Seite dient es so außerdem dazu, die Privatssphäre der Nutzer zu schützen, da eingebettete Inhalte so von deiner Seite aus geladen werden und nicht von externen Quellen (die deine IP-Adresse ermitteln könnten).
-
-Ebenso hilft es bei Inhalten, die nur langsam laden oder nicht immer online sind.
-
-**Einrichtung**
-
-Bitte erstelle einen Ordner namens "privacy_image_cache" und "photo" in deinem Stammverzeichnis. Wenn diese Ordner existieren, dann werden die zwischengespeicherten Inhalte dort abgelegt. Dies hat den großen Vorteil, dass der Server die Dateien direkt von dort bezieht.
-
###rendertime
**Beschreibung**
-Dieses Plugin beschleunigt dein System nicht, aber es hilft dabei, die Flaschenhälse zu ermitteln.
+Dieses Plugin beschleunigt dein System nicht, aber es hilft dabei, die Flaschenhälse zu ermitteln.
Wenn es aktiviert ist, dann siehst du Werte wie die folgenden auf jeder deiner Seiten:
@@ -100,17 +88,17 @@ Diese Werte zeigen deine Performance-Probleme.
Webserver
----------
-Wenn du einen Apache-Webserver nutzt, aktiviere bitte die folgenden Module:
+Wenn du einen Apache-Webserver nutzt, aktiviere bitte die folgenden Module:
###Cache-Control
**Beschreibung**
-Dieses Modul weist den Client an, den Inhalt statischer Dateien zu speichern, um diese nicht immer wieder neu laden zu müssen.
+Dieses Modul weist den Client an, den Inhalt statischer Dateien zu speichern, um diese nicht immer wieder neu laden zu müssen.
Aktiviere das Modul "mod_expires", indem du "a2enmod expires" als root eingibst.
-Füge die folgenden Zeilen in die Apache-Konfiguration deiner Seite im "directory"-Bereich ein.
+Füge die folgenden Zeilen in die Apache-Konfiguration deiner Seite im "directory"-Bereich ein.
ExpiresActive on ExpiresDefault "access plus 1 week"
@@ -120,7 +108,7 @@ Weitere Informationen findest du hier: http://httpd.apache.org/docs/2.2/mod/mod_
**Beschreibung**
-Dieses Modul komprimiert den Datenverkehr (Traffic) zwischen dem Webserver und dem Client.
+Dieses Modul komprimiert den Datenverkehr (Traffic) zwischen dem Webserver und dem Client.
Aktiviere das Modul "mod_deflate" durch die Eingabe "a2enmod deflate" als root.
@@ -131,7 +119,7 @@ Weitere Informationen findest du hier: http://httpd.apache.org/docs/2.2/mod/mod_
**FCGI**
-Wenn du Apache nutzt, dann denk darüber nach, FCGI zu nutzen. Wenn du eine Debian-basierte Distribution nutzt, dann wirst du die Pakete "php5-cgi" und "libapache2-mod-fcgid" benötigen.
+Wenn du Apache nutzt, dann denk darüber nach, FCGI zu nutzen. Wenn du eine Debian-basierte Distribution nutzt, dann wirst du die Pakete "php5-cgi" und "libapache2-mod-fcgid" benötigen.
Nutze externe Dokumente, um eine detailiertere Erklärung für die Einrichtung eines Systems auf FCGI-Basis zu erhalten.
**APC**
@@ -142,6 +130,6 @@ Wenn APC aktiviert ist, dann nutzt Friendica dies, um Konfigurationseinstellunge
###Database
-Es gibt Skripte wie [tuning-primer.sh](http://www.day32.com/MySQL/) und [mysqltuner.pl](http://mysqltuner.pl), die den Datenbankserver analysieren und Hinweise darauf geben, welche Werte verändert werden könnten.
-
-Aktivere hierfür die "Slow query" Log-Datei, um Performanceprobleme zu erkennen.
+Es gibt Skripte wie [tuning-primer.sh](http://www.day32.com/MySQL/) und [mysqltuner.pl](http://mysqltuner.pl), die den Datenbankserver analysieren und Hinweise darauf geben, welche Werte verändert werden könnten.
+
+Aktivere hierfür die "Slow query" Log-Datei, um Performanceprobleme zu erkennen.
diff --git a/doc/de/Quick-Start-andfinally.md b/doc/de/Quick-Start-andfinally.md
index 06a1878ba..b6e492ae6 100644
--- a/doc/de/Quick-Start-andfinally.md
+++ b/doc/de/Quick-Start-andfinally.md
@@ -8,12 +8,8 @@ Hier sind noch einige weitere Dinge, die dir den Start vereinfachen können.
**Gruppen**
-- Neu hier? - eine Gruppe für Leute, die neu bei Friendica sind
-
- Friendica Support - Probleme? Dann ist das der Platz, um zu fragen!
-- Öffentlicher Stream - ein Platz, um über alles mit jedem zu reden.
-
- Let's Talk eine Gruppe, um Leute und Gruppen mit gleichen Interessen zu finden
- Local Friendica eine Seite für lokale Friendica-Gruppen
diff --git a/doc/readme.md b/doc/readme.md
new file mode 100644
index 000000000..6020f2c01
--- /dev/null
+++ b/doc/readme.md
@@ -0,0 +1,48 @@
+Friendica Documentation and Resources
+=====================================
+
+**Contents**
+
+* General functions - first steps
+ * [Account Basics](help/Account-Basics)
+ * [New User Quick Start](help/Quick-Start-guide)
+ * [Creating posts](help/Text_editor)
+ * [BBCode tag reference](help/BBCode)
+ * [Comment, sort and delete posts](help/Text_comment)
+ * [Profiles](help/Profiles)
+* You and other user
+ * [Connectors](help/Connectors)
+ * [Making Friends](help/Making-Friends)
+ * [Groups and Privacy](help/Groups-and-Privacy)
+ * [Tags and Mentions](help/Tags-and-Mentions)
+ * [Community Forums](help/Forums)
+ * [Chats](help/Chats)
+* Further information
+ * [Improve Performance](help/Improve-Performance)
+ * [Move Account](help/Move-Account)
+ * [Remove Account](help/Remove-Account)
+ * [Bugs and Issues](help/Bugs-and-Issues)
+ * [Frequently asked questions (FAQ)](help/FAQ)
+
+**Technical Documentation**
+
+* [Install](help/Install)
+* [Settings](help/Settings)
+* [Plugins](help/Plugins)
+* [Installing Connectors (Facebook/Twitter/StatusNet)](help/Installing-Connectors)
+* [Message Flow](help/Message-Flow)
+* [Using SSL with Friendica](help/SSL)
+* [Developers](help/Developers)
+* [Twitter/StatusNet API Functions](help/api)
+* [Translation of Friendica](help/translations)
+
+
+**External Resources**
+
+* [Main Website](http://friendica.com)
+* [Mailing List Archive](http://librelist.com/browser/friendica/)
+
+**About**
+
+* [Site/Version Info](friendica)
+
diff --git a/doc/translations.md b/doc/translations.md
new file mode 100644
index 000000000..b874e9ea2
--- /dev/null
+++ b/doc/translations.md
@@ -0,0 +1,95 @@
+Friendica translations
+======================
+
+Translation Process
+-------------------
+
+The strings used in the UI of Friendica is translated at [Transifex] [1] and then
+included in the git repository at github. If you want to help with translation
+for any language, be it correcting terms or translating friendica to a
+currently not supported language, please register an account at transifex.com
+and contact the friendica translation team there.
+
+Translating friendica is simple. Just use the online tool at transifex. If you
+don't want to deal with git & co. that is fine, we check the status of the
+translations regularly and import them into the source tree at github so that
+others can use them.
+
+We do not include every translation from transifex in the source tree to avoid
+a scattered and disturbed overall experience. As an uneducated guess we have a
+lower limit of 50% translated strings before we include the language (for the
+core message.po file, addont translation will be included once all strings of
+an addon are translated. This limit is judging only by the amount of translated
+strings under the assumption that the most prominent strings for the UI will be
+translated first by a translation team. If you feel your translation useable
+before this limit, please contact us and we will probably include your teams
+work in the source tree.
+
+If you want to get your work into the source tree yourself, feel free to do so
+and contact us with and question that arises. The process is simple and
+friendica ships with all the tools necessary.
+
+The location of the translated files in the source tree is
+ /view/LNG-CODE/
+where LNG-CODE is the language code used, e.g. de for German or fr for French.
+For the email templates (the *.tpl files) just place them into the directory
+and you are done. The translated strings come as a "message.po" file from
+transifex which needs to be translated into the PHP file friendica uses. To do
+so, place the file in the directory mentioned above and use the "po2php"
+utility from the util directory of your friendica installation.
+
+Assuming you want to convert the German localization which is placed in
+view/de/message.po you would do the following.
+
+ 1. Navigate at the command prompt to the base directory of your
+ friendica installation
+
+ 2. Execute the po2php script, which will place the translation
+ in the strings.php file that is used by friendica.
+
+ $> php util/po2php.php view/de/message.po
+
+ The output of the script will be placed at view/de/strings.php where
+ froemdoca os expecting it, so you can test your translation mmediately.
+
+ 3. Visit your friendica page to check if it still works in the language you
+ just translated. If not try to find the error, most likely PHP will give
+ you a hint in the log/warnings.about the error.
+
+ For debugging you can also try to "run" the file with PHP. This should
+ not give any output if the file is ok but might give a hint for
+ searching the bug in the file.
+
+ $> php view/de/strings.php
+
+ 4. commit the two files with a meaningful commit message to your git
+ repository, push it to your fork of the friendica repository at github and
+ issue a pull request for that commit.
+
+Utilities
+---------
+
+Additional to the po2php script there are some more utilities for translation
+in the "util" directory of the friendica source tree. If you only want to
+translate friendica into another language you wont need any of these tools most
+likely but it gives you an idea how the translation process of friendica
+works.
+
+For further information see the utils/README file.
+
+Known Problems
+--------------
+
+Friendica uses the language setting of the visitors browser to determain the
+language for the UI. Most of the time this works, but there are some known
+quirks.
+
+One is that some browsers, like Safari, do the setting to "de-de" but friendica
+only has a "de" localisation. A workaround would be to add a symbolic link
+from
+ $friendica/view/de-de
+pointing to
+ $friendica/view/de
+
+[1]: https://www.transifex.com/projects/p/friendica/
+
diff --git a/htconfig.php b/htconfig.php
index a5f5574ee..4208924cf 100644
--- a/htconfig.php
+++ b/htconfig.php
@@ -59,7 +59,7 @@ $a->config['system']['directory_search_url'] = 'http://dir.friendica.com/directo
// PuSH - aka pubsubhubbub URL. This makes delivery of public posts as fast as private posts
-$a->config['system']['huburl'] = 'http://pubsubhubbub.appspot.com';
+$a->config['system']['huburl'] = '[internal]';
// Server-to-server private message encryption (RINO) is allowed by default.
// Encryption will only be provided if this setting is true and the
diff --git a/images/person-175.jpg b/images/person-175.jpg
index fc0ec3d77..527a9d78b 100644
Binary files a/images/person-175.jpg and b/images/person-175.jpg differ
diff --git a/images/person-48.jpg b/images/person-48.jpg
index dc5eb6e69..8984bb295 100644
Binary files a/images/person-48.jpg and b/images/person-48.jpg differ
diff --git a/images/person-80.jpg b/images/person-80.jpg
index 75b8faf92..4e70a4dde 100644
Binary files a/images/person-80.jpg and b/images/person-80.jpg differ
diff --git a/include/EmailNotification.php b/include/Emailer.php
similarity index 64%
rename from include/EmailNotification.php
rename to include/Emailer.php
index 8861e8f5d..535a05428 100644
--- a/include/EmailNotification.php
+++ b/include/Emailer.php
@@ -2,7 +2,7 @@
require_once('include/email.php');
-class EmailNotification {
+class Emailer {
/**
* Send a multipart/alternative message with Text and HTML versions
*
@@ -13,13 +13,13 @@ class EmailNotification {
* @param messageSubject subject of the message
* @param htmlVersion html version of the message
* @param textVersion text only version of the message
+ * @param additionalMailHeader additions to the smtp mail header
*/
- static public function sendTextHtmlEmail($fromName,$fromEmail,$replyTo,$toEmail,$messageSubject,$htmlVersion,$textVersion) {
+ static public function send($params) {
+
+ $fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
+ $messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
- $fromName = email_header_encode($fromName,'UTF-8');
- $messageSubject = email_header_encode($messageSubject,'UTF-8');
-
-
// generate a mime boundary
$mimeBoundary =rand(0,9)."-"
.rand(10000000000,9999999999)."-"
@@ -28,14 +28,15 @@ class EmailNotification {
// generate a multipart/alternative message header
$messageHeader =
- "From: {$fromName} <{$fromEmail}>\n" .
- "Reply-To: {$replyTo}\n" .
+ $params['additionalMailHeader'] .
+ "From: $fromName <{$params['fromEmail']}>\n" .
+ "Reply-To: $fromName <{$params['replyTo']}>\n" .
"MIME-Version: 1.0\n" .
"Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
// assemble the final multipart message body with the text and html types included
- $textBody = chunk_split(base64_encode($textVersion));
- $htmlBody = chunk_split(base64_encode($htmlVersion));
+ $textBody = chunk_split(base64_encode($params['textVersion']));
+ $htmlBody = chunk_split(base64_encode($params['htmlVersion']));
$multipartMessageBody =
"--" . $mimeBoundary . "\n" . // plain text section
"Content-Type: text/plain; charset=UTF-8\n" .
@@ -49,12 +50,14 @@ class EmailNotification {
// send the message
$res = mail(
- $toEmail, // send to address
+ $params['toEmail'], // send to address
$messageSubject, // subject
$multipartMessageBody, // message body
$messageHeader // message headers
);
- logger("sendTextHtmlEmail: END");
+ logger("header " . 'To: ' . $params['toEmail'] . "\n" . $messageHeader, LOGGER_DEBUG);
+ logger("return value " . (($res)?"true":"false"), LOGGER_DEBUG);
+ return $res;
}
}
-?>
\ No newline at end of file
+?>
diff --git a/include/api.php b/include/api.php
index ade783662..374a71847 100644
--- a/include/api.php
+++ b/include/api.php
@@ -26,6 +26,19 @@
return false;
}
+ function api_source() {
+ if (requestdata('source'))
+ return (requestdata('source'));
+
+ // Support for known clients that doesn't send a source name
+ if (strstr($_SERVER['HTTP_USER_AGENT'], "Twidere"))
+ return ("Twidere");
+
+ logger("Unrecognized user-agent ".$_SERVER['HTTP_USER_AGENT'], LOGGER_DEBUG);
+
+ return ("api");
+ }
+
function api_date($str){
//Wed May 23 06:01:13 +0000 2007
return datetime_convert('UTC', 'UTC', $str, "D M d H:i:s +0000 Y" );
@@ -122,7 +135,6 @@
// preset
$type="json";
-
foreach ($API as $p=>$info){
if (strpos($a->query_string, $p)===0){
$called_api= explode("/",$p);
@@ -154,7 +166,10 @@
case "json":
header ("Content-Type: application/json");
foreach($r as $rr)
- return json_encode($rr);
+ $json = json_encode($rr);
+ if ($_GET['callback'])
+ $json = $_GET['callback']."(".$json.")";
+ return $json;
break;
case "rss":
header ("Content-Type: application/rss+xml");
@@ -710,8 +725,6 @@
if($parent)
$_REQUEST['type'] = 'net-comment';
else {
-// logger("api_statuses_update: upload ".print_r($_FILES, true)." ".print_r($_POST, true)." ".print_r($_GET, true), LOGGER_DEBUG);
-//die("blubb");
$_REQUEST['type'] = 'wall';
if(x($_FILES,'media')) {
// upload the image if we have one
@@ -727,6 +740,9 @@
$_REQUEST['api_source'] = true;
+ if (!x($_REQUEST, "source"))
+ $_REQUEST["source"] = api_source();
+
// call out normal post function
require_once('mod/item.php');
@@ -936,6 +952,35 @@
}
api_register_func('api/users/show','api_users_show');
+
+ function api_users_search(&$a, $type) {
+ $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
+
+ $userlist = array();
+
+ if (isset($_GET["q"])) {
+ $r = q("SELECT id FROM unique_contacts WHERE name='%s'", dbesc($_GET["q"]));
+ if (!count($r))
+ $r = q("SELECT id FROM unique_contacts WHERE nick='%s'", dbesc($_GET["q"]));
+
+ if (count($r)) {
+ foreach ($r AS $user) {
+ $user_info = api_get_user($a, $user["id"]);
+ //echo print_r($user_info, true)."\n";
+ $userdata = api_apply_template("user", $type, array('user' => $user_info));
+ $userlist[] = $userdata["user"];
+ }
+ $userlist = array("users" => $userlist);
+ } else
+ die(api_error($a, $type, t("User not found.")));
+ } else
+ die(api_error($a, $type, t("User not found.")));
+
+ return ($userlist);
+ }
+
+ api_register_func('api/users/search','api_users_search');
+
/**
*
* http://developer.twitter.com/doc/get/statuses/home_timeline
@@ -1272,6 +1317,9 @@
$_REQUEST['type'] = 'wall';
$_REQUEST['api_source'] = true;
+ if (!x($_REQUEST, "source"))
+ $_REQUEST["source"] = api_source();
+
require_once('mod/item.php');
item_post($a);
}
@@ -1359,7 +1407,7 @@
AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
- AND `item`.`parent` IN (SELECT `iid` from thread where uid = %d AND `mention`)
+ AND `item`.`parent` IN (SELECT `iid` from thread where uid = %d AND `mention` AND !`ignored`)
$sql_extra
AND `item`.`id`>%d
ORDER BY `item`.`id` DESC LIMIT %d ,%d ",
@@ -1790,7 +1838,17 @@
return($entities);
}
-
+ function api_format_items_embeded_images($item, $text){
+ $a = get_app();
+ $text = preg_replace_callback(
+ "|data:image/([^;]+)[^=]+=*|m",
+ function($match) use ($a, $item) {
+ return $a->get_baseurl()."/display/".$item['guid'];
+ },
+ $text);
+ return $text;
+ }
+
function api_format_items($r,$user_info, $filter_user = false) {
$a = get_app();
@@ -1848,17 +1906,23 @@
//$statusbody = trim(html2plain(bbcode(api_clean_plain_items($item['body']), false, false, 5, true), 0));
$html = bbcode(api_clean_plain_items($item['body']), false, false, 2, true);
$statusbody = trim(html2plain($html, 0));
-
+
+ // handle data: images
+ $statusbody = api_format_items_embeded_images($item,$statusbody);
+
$statustitle = trim($item['title']);
if (($statustitle != '') and (strpos($statusbody, $statustitle) !== false))
$statustext = trim($statusbody);
else
$statustext = trim($statustitle."\n\n".$statusbody);
-
+
if (($item["network"] == NETWORK_FEED) and (strlen($statustext)> 1000))
$statustext = substr($statustext, 0, 1000)."... \n".$item["plink"];
+ $statushtml = trim(bbcode($item['body'], false, false));
+
+
$status = array(
'text' => $statustext,
'truncated' => False,
@@ -1876,7 +1940,7 @@
//'attachments' => array(),
'user' => $status_user ,
//'entities' => NULL,
- 'statusnet_html' => trim(bbcode($item['body'], false, false)),
+ 'statusnet_html' => $statushtml,
'statusnet_conversation_id' => $item['parent'],
);
@@ -2198,13 +2262,6 @@
function api_direct_messages_box(&$a, $type, $box) {
if (api_user()===false) return false;
- unset($_REQUEST["user_id"]);
- unset($_GET["user_id"]);
-
- unset($_REQUEST["screen_name"]);
- unset($_GET["screen_name"]);
-
- $user_info = api_get_user($a);
// params
$count = (x($_GET,'count')?$_GET['count']:20);
@@ -2214,11 +2271,25 @@
$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
- $start = $page*$count;
+ $user_id = (x($_REQUEST,'user_id')?$_REQUEST['user_id']:"");
+ $screen_name = (x($_REQUEST,'screen_name')?$_REQUEST['screen_name']:"");
+ // caller user info
+ unset($_REQUEST["user_id"]);
+ unset($_GET["user_id"]);
+
+ unset($_REQUEST["screen_name"]);
+ unset($_GET["screen_name"]);
+
+ $user_info = api_get_user($a);
//$profile_url = $a->get_baseurl() . '/profile/' . $a->user['nickname'];
$profile_url = $user_info["url"];
+
+ // pagination
+ $start = $page*$count;
+
+ // filters
if ($box=="sentbox") {
$sql_extra = "`mail`.`from-url`='".dbesc( $profile_url )."'";
}
@@ -2235,11 +2306,19 @@
if ($max_id > 0)
$sql_extra .= ' AND `mail`.`id` <= '.intval($max_id);
+ if ($user_id !="") {
+ $sql_extra .= ' AND `mail`.`contact-id` = ' . intval($user_id);
+ }
+ elseif($screen_name !=""){
+ $sql_extra .= " AND `contact`.`nick` = '" . dbesc($screen_name). "'";
+ }
+
$r = q("SELECT `mail`.*, `contact`.`nurl` AS `contact-url` FROM `mail`,`contact` WHERE `mail`.`contact-id` = `contact`.`id` AND `mail`.`uid`=%d AND $sql_extra AND `mail`.`id` > %d ORDER BY `mail`.`id` DESC LIMIT %d,%d",
intval(api_user()),
intval($since_id),
intval($start), intval($count)
);
+
$ret = Array();
foreach($r as $item) {
@@ -2247,12 +2326,11 @@
$recipient = $user_info;
$sender = api_get_user($a,normalise_link($item['contact-url']));
}
- elseif ($box == "sentbox" || $item['from-url'] != $profile_url){
+ elseif ($box == "sentbox" || $item['from-url'] == $profile_url){
$recipient = api_get_user($a,normalise_link($item['contact-url']));
$sender = $user_info;
}
-
$ret[]=api_format_messages($item, $recipient, $sender);
}
@@ -2350,9 +2428,6 @@
-
-
-
function api_share_as_retweet($a, $uid, &$item) {
$body = trim($item["body"]);
diff --git a/include/bbcode.php b/include/bbcode.php
index 017673423..5395548f5 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -66,7 +66,7 @@ function bb_attachment($Text, $plaintext = false, $tryoembed = true) {
}
if ($plaintext)
- $text = sprintf('%s', $url, $title);
+ $text = sprintf('%s ', $url, $title);
else {
$text = sprintf('', $type);
@@ -92,35 +92,6 @@ function bb_attachment($Text, $plaintext = false, $tryoembed = true) {
return($Text);
}
-/* function bb_rearrange_link($shared) {
- if ($shared[1] != "type-link")
- return($shared[0]);
-
- $newshare = trim($shared[2]);
- $newshare = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $newshare);
-
- if (!strpos($shared[0], "[bookmark"))
- $newshare = preg_replace("/\[url\=(.*?)\](.*?)\[\/url\]/ism", '[bookmark=$1]$2[/bookmark]', $newshare, 1);
-
- preg_match("/\[img\](.*?)\[\/img\]/ism", $newshare, $matches);
-
- if ($matches) {
- $newshare = str_replace($matches[0], '', $newshare);
- $newshare = "[img]".$matches[1]."[/img]\n".$newshare;
- }
-
- $search = array("\n\n", "\n ", " \n");
- $replace = array("\n", "\n", "\n");
- do {
- $oldtext = $newshare;
- $newshare = str_replace($search, $replace, $newshare);
- } while ($oldtext != $newshare);
-
- $newshare = "[class=type-link]".$newshare."[/class]";
-
- return($newshare);
-} */
-
function bb_rearrange_share($shared) {
if (!in_array(strtolower($shared[2]), array("type-link", "type-audio", "type-video")))
return($shared[0]);
@@ -211,7 +182,8 @@ function bb_cleanup_share($shared, $plaintext, $nolink) {
if (isset($bookmark[1][0]))
$link = $bookmark[1][0];
- if (($title != "") AND (strpos($shared[1],$title) !== false))
+ if (($title != "") AND ((strpos($shared[1],$title) !== false) OR
+ (similar_text($shared[1],$title) / strlen($title)) > 0.9))
$title = "";
// if (strpos($shared[1],$link) !== false)
@@ -534,10 +506,14 @@ function bb_ShareAttributes($share, $simplehtml) {
if ($text != "")
$text .= "";
- $text .= $headline.'