diff --git a/.htaccess b/.htaccess
index 83d67e8f89..1b63f9ad6f 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 0000000000..33a1c58bb8
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,126 @@
+Version 3.3.2
+
+ Set default value for all not-null fields (fixes SQL warinigs) (annando)
+ Fix item filters in network page (issue #1222) (fabrixxm)
+ Remove reference to an ex Friendica hub from documentation (beardyunixer, tobiasd)
+ API throttling (annando)
+ Use a san-serif font in breathe style of vier theme (silke)
+ Prevent BBCode parsing problems with URLs (annando)
+ Add back tags to posts to Diaspora (annando)
+ Better display of pictures in posts (annando)
+ Fix out of control gprobe process (annando)
+
+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
+
+ API
+ added support in the API to allow image uploads from Twidere
+ support for the diaspora app in Firefox
+
+ Themes
+ Stopped support of unmaintained themes. They will continue to work if enabled but are no longer displayed in the list of themes.
+ Merged all "zero" themes into a theme with variations.
+ new default avatar by Andi Stadler
+
+ Usability
+ network page as default page after login
+ sections on users' settings page are now collapsable
+ automatic updating the network stream was improved
+
+ Interaction
+ ignoring of threads
+ for selected contects one can now get notifications when they post something, useful e.g. for forums
+ After a new friendica contact is added, the user is directed to the contact page of the new contact. (Instead of the remote profile)
+ many improvement on all connectors, new app.net connector
+ the algorithm for shortening postings when posting to limited platforms was improved
+ improvements for the remote_self functionality for RSS/Atom feeds were done
+
+ System stuff
+ no more apc support due problems with PHP 5.5
+ privacy image cache moved from an addon into the core
+ updated the following libraries: smarty 3.1.19, fullcalendar 1.6.4, jquery 1.11, jgrowl 1.3.0
+ added modernizer 2.8.3, better browser support
+ updates to the DB structure for better performance
+ preperations to use PDO in a later release
+ new notification system
+ web interface translations updated, addon translations now also possible separately from the main UI and done for CS, IT, RO, DE
+ vagrant support added for developers
+ some bugs were fixed for the profile import function
+ BBCode handling and reformatting to e.g. markdown was improved
+ Internal PusH server for communication with OStatus contacts
+
+ Addons
+ translation now done at transifex as well
+ "newmemberwidget" adds widget with help links + welcome message to sidebar of network tab for new members
+ new statistics addon to take part in the Diaspora* survey
+ new bidirectional connector for app.net
+ new relay connector for Diaspora*
+ new connector for the buffer service
+ improvements for the connectors with Twitter, StatusNet/GNU Social, pump.io, google+ and facebook
+ improvements to the cal and jappix-mini addons
+
+ Change in the structure of the git repo
+ The "master" branch will now contain stable stuff and hotfixes.
+ The new "develop" branch will contain the latest changes.
+
+Version 3.2
+
+ LICENSE change from Friendica uses now the AGPL
+ Language updates: PT_BR, RU, NB_NO, DE, PL, CS, ZH-CN, IT, CA, FR, NL
+ new languages: BG
+ added a README.translate and updates to the translation utils
+ addons are now translated separately
+ Theme updates: vier, smoothly, diabook, decaf-mobile, dispy, frost, frost-mobile, quattro
+ Bug fixes: #516, #517, #525, #476, #540, #546, #712, #728
+ sample nginx and lighttpd config
+ new default templating engine: smarty3
+ new share element
+ maintenance mode for longer running upgrade tasks
+ small fixed
+ edit profile photo link
+ better caching of pictures
+ threadening for outgoing emails
+ mail import
+ oembed thumbnails
+ SN subscriptions & more SN like behaviour if snautofollow addon is used
+ collect content of SN discussion threads
+ communication with Diaspora*
+ usage of the API
+ search improvements
+ MIME types for attachments
+ support Open Graph and Dublin Core when showing single items
+ better use of APC if present
+ use https versions of videos from youtube and vimeo to make firefox happy
+ fixes to the documentation
+ if a home.html is there, home.css is used as well
+ update included TinyMCE to version 3.5.8, fancybox
+ made more options available in the admin panel that were hidden before
+ show the admin information about when accounts expire in the admin panel
+ improving the install.php script
+ addons now can be members only
+ item object now contains the "edited" information left for the theme designers to show this info in a pretty way
+ improvments to the user-import from exported account files
+ It's now possible to authenticate an ejabberd server against friendica.
+ bugtracker moved to github
+ improvements to MySQL queries
+
+Version 3.1
+
+ See http://friendica.com/node/58
diff --git a/Vagrantfile b/Vagrantfile
index 755cf202b4..48af4ae518 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
@@ -97,167 +40,20 @@ Vagrant.configure("2") do |config|
# 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 5ef24f4944..34836a97aa 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.2' );
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/changelist.txt b/changelist.txt
deleted file mode 100644
index 95c5abd270..0000000000
--- a/changelist.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-Friendica 3.2
-------------
-
-* LICENSE change from Friendica uses now the AGPL
-* Language updates: PT_BR, RU, NB_NO, DE, PL, CS, ZH-CN, IT, CA, FR, NL
-* new languages: BG
-* added a README.translate and updates to the translation utils
-* addons are now translated separately
-* Theme updates: vier, smoothly, diabook, decaf-mobile, dispy, frost, frost-mobile, quattro
-* Bug fixes: #516, #517, #525, #476, #540, #546, #712, #728
-* sample nginx and lighttpd config
-* new default templating engine: smarty3
-* new share element
-* maintenance mode for longer running upgrade tasks
-* small fixed
- * edit profile photo link
- * better caching of pictures
- * threadening for outgoing emails
- * mail import
- * oembed thumbnails
- * SN subscriptions & more SN like behaviour if snautofollow addon is used
- * collect content of SN discussion threads
- * communication with Diaspora*
- * usage of the API
- * search improvements
- * MIME types for attachments
- * support Open Graph and Dublin Core when showing single items
- * better use of APC if present
- * use https versions of videos from youtube and vimeo to make firefox happy
-* fixes to the documentation
-* if a home.html is there, home.css is used as well
-* update included TinyMCE to version 3.5.8, fancybox
-* made more options available in the admin panel that were hidden before
-* show the admin information about when accounts expire in the admin panel
-* improving the install.php script
-* addons now can be members only
-* item object now contains the "edited" information left for the theme designers to show this info in a pretty way
-* improvments to the user-import from exported account files
-* It's now possible to authenticate an ejabberd server against friendica.
-* bugtracker moved to github
-* improvements to MySQL queries
-
diff --git a/doc/FAQ.md b/doc/FAQ.md
index c3c3e8bc24..6fa852e0b0 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 86a4eb6473..6020f2c01c 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 ceed6fcabc..d4c94d2d11 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/Install.md b/doc/Install.md
index 4ef1e40e53..28b8ba9f7e 100644
--- a/doc/Install.md
+++ b/doc/Install.md
@@ -47,7 +47,7 @@ you might have trouble getting everything to work.]
`mkdir view/smarty3`
- `chown 777 view/smarty3`
+ `chmod 777 view/smarty3`
- For installing addons
diff --git a/doc/Making-Friends.md b/doc/Making-Friends.md
index 70b87abbc0..e0b1a254e0 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 c4e8cb9480..f7aeb1bd45 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 0000000000..f36a79a5eb
--- /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 fee7b6a58b..0fd5634cc3 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 fe99123342..346c76fc3e 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/Making-Friends.md b/doc/de/Making-Friends.md
index e6725228ff..74f1f62b37 100644
--- a/doc/de/Making-Friends.md
+++ b/doc/de/Making-Friends.md
@@ -5,9 +5,7 @@ Freunde finden
Freundschaft kann in Friendica viele verschiedene Bedeutungen annehmen. Aber lasst es uns einfach halten, du willst einfach mit jemandem befreundet sein. Wie machst du das?
-Der einfachste Weg, um das zu machen, ist es, der Gruppe Neu hier beizutreten. Diese Gruppe ist speziell für Leute, die neu im Friendica-Netzwerk sind. Verbinde dich einfach mit der Gruppe, schreibe auf die "Wall" und lerne neue Leute kennen. Du musst uns nicht einmal direkt "liken" - kommentiere einige Beiträge und andere Leute werden anfangen, dich hinzuzufügen.
-
-Als Nächstes kannst du dir das Verzeichnis anschauen. Das Verzeichnis ist in zwei Teile aufgeteilt. Wenn du auf den "Verzeichnis"-Button klickst, wirst du zunächst alle Mitglieder deines Servers sehen, die sich dazu entschlossen haben, angezeigt zu werden. Außerdem siehst du dort einen Link zum globalen Verzeichnis. Wenn du dich durch das globale Verzeichnis klickst, siehst du alle Nutzer weltweit auf allen Servern, die sich entschlossen haben, im Verzeichnis zu erscheinen. Du wirst außerdem den Link "Show Community Forums" sehen, welcher dich zu Gruppen, Foren und Fan-Seiten führt. Du verbindest dich mit Personen, Gruppen und Foren auf die gleiche Art, wobei Gruppen und Foren deine Anfrage automatisch annehmen, wohingegen ein Mensch dich erst manuell bestätigen muss.
+Schau dir das Verzeichnis an. Das Verzeichnis ist in zwei Teile aufgeteilt. Wenn du auf den "Verzeichnis"-Button klickst, wirst du zunächst alle Mitglieder deines Servers sehen, die sich dazu entschlossen haben, angezeigt zu werden. Außerdem siehst du dort einen Link zum globalen Verzeichnis. Wenn du dich durch das globale Verzeichnis klickst, siehst du alle Nutzer weltweit auf allen Servern, die sich entschlossen haben, im Verzeichnis zu erscheinen. Du wirst außerdem den Link "Show Community Forums" sehen, welcher dich zu Gruppen, Foren und Fan-Seiten führt. Du verbindest dich mit Personen, Gruppen und Foren auf die gleiche Art, wobei Gruppen und Foren deine Anfrage automatisch annehmen, wohingegen ein Mensch dich erst manuell bestätigen muss.
*Mit anderen Friendica-Nutzern verbinden*
diff --git a/doc/de/Quick-Start-andfinally.md b/doc/de/Quick-Start-andfinally.md
index 06a1878ba9..b6e492ae69 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/de/andfinally.md b/doc/de/andfinally.md
index 06a1878ba9..b6e492ae69 100644
--- a/doc/de/andfinally.md
+++ b/doc/de/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 0000000000..6020f2c01c
--- /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 0000000000..b874e9ea2e
--- /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 a5f5574eea..4208924cfd 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 fc0ec3d771..527a9d78b6 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 dc5eb6e692..8984bb2955 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 75b8faf922..4e70a4dde1 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 8861e8f5d8..535a054289 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 ade783662b..ffa5d0e9df 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");
@@ -666,6 +681,7 @@
logger('api_statuses_update: no user');
return false;
}
+
$user_info = api_get_user($a);
// convert $_POST array items to the form we use for web posts.
@@ -710,8 +726,64 @@
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");
+ // Check for throttling (maximum posts per day, week and month)
+ $throttle_day = get_config('system','throttle_limit_day');
+ if ($throttle_day > 0) {
+ $datefrom = date("Y-m-d H:i:s", time() - 24*60*60);
+
+ $r = q("SELECT COUNT(*) AS `posts_day` FROM `item` WHERE `uid`=%d AND `wall`
+ AND `created` > '%s' AND `id` = `parent`",
+ intval(api_user()), dbesc($datefrom));
+
+ if ($r)
+ $posts_day = $r[0]["posts_day"];
+ else
+ $posts_day = 0;
+
+ if ($posts_day > $throttle_day) {
+ logger('Daily posting limit reached for user '.api_user(), LOGGER_DEBUG);
+ die(api_error($a, $type, sprintf(t("Daily posting limit of %d posts reached. The post was rejected."), $throttle_day)));
+ }
+ }
+
+ $throttle_week = get_config('system','throttle_limit_week');
+ if ($throttle_week > 0) {
+ $datefrom = date("Y-m-d H:i:s", time() - 24*60*60*7);
+
+ $r = q("SELECT COUNT(*) AS `posts_week` FROM `item` WHERE `uid`=%d AND `wall`
+ AND `created` > '%s' AND `id` = `parent`",
+ intval(api_user()), dbesc($datefrom));
+
+ if ($r)
+ $posts_week = $r[0]["posts_week"];
+ else
+ $posts_week = 0;
+
+ if ($posts_week > $throttle_week) {
+ logger('Weekly posting limit reached for user '.api_user(), LOGGER_DEBUG);
+ die(api_error($a, $type, sprintf(t("Weekly posting limit of %d posts reached. The post was rejected."), $throttle_week)));
+ }
+ }
+
+ $throttle_month = get_config('system','throttle_limit_month');
+ if ($throttle_month > 0) {
+ $datefrom = date("Y-m-d H:i:s", time() - 24*60*60*30);
+
+ $r = q("SELECT COUNT(*) AS `posts_month` FROM `item` WHERE `uid`=%d AND `wall`
+ AND `created` > '%s' AND `id` = `parent`",
+ intval(api_user()), dbesc($datefrom));
+
+ if ($r)
+ $posts_month = $r[0]["posts_month"];
+ else
+ $posts_month = 0;
+
+ if ($posts_month > $throttle_month) {
+ logger('Monthly posting limit reached for user '.api_user(), LOGGER_DEBUG);
+ die(api_error($a, $type, sprintf(t("Monthly posting limit of %d posts reached. The post was rejected."), $throttle_month)));
+ }
+ }
+
$_REQUEST['type'] = 'wall';
if(x($_FILES,'media')) {
// upload the image if we have one
@@ -727,6 +799,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 +1011,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 +1376,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 +1466,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 +1897,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 +1965,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 +1999,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 +2321,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 +2330,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 +2365,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 +2385,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 +2487,6 @@
-
-
-
function api_share_as_retweet($a, $uid, &$item) {
$body = trim($item["body"]);
diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php
index 39742291fd..7107c49139 100644
--- a/include/bb2diaspora.php
+++ b/include/bb2diaspora.php
@@ -56,6 +56,8 @@ function diaspora2bb($s) {
function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
+ $OriginalText = $Text;
+
// Since Diaspora is creating a summary for links, this function removes them before posting
if ($fordiaspora)
$Text = bb_remove_share_information($Text);
@@ -73,12 +75,24 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
// Convert it to HTML - don't try oembed
- if ($fordiaspora)
+ if ($fordiaspora) {
$Text = bbcode($Text, $preserve_nl, false, 3);
- else {
+
+ // Add all tags that maybe were removed
+ if (preg_match_all("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",$OriginalText, $tags)) {
+ $tagline = "";
+ foreach($tags[2] as $tag)
+ if (!strpos($Text, "#".$tag))
+ $tagline .= "#".$tag." ";
+
+ $Text = $Text." ".$tagline;
+ }
+
+ } else {
$Text = bbcode($Text, $preserve_nl, false, 4);
+
// Libertree doesn't convert a harizontal rule if there isn't a linefeed
- $Text = str_replace("", " ", $Text);
+ $Text = str_replace(array("", ""), array(" ", " "), $Text);
}
// Now convert HTML to Markdown
diff --git a/include/bbcode.php b/include/bbcode.php
index 017673423b..724b8e2fdd 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -3,10 +3,10 @@ require_once("include/oembed.php");
require_once('include/event.php');
function bb_attachment($Text, $plaintext = false, $tryoembed = true) {
- $Text = preg_replace_callback("/\[attachment(.*?)\](.*?)\[\/attachment\]/ism",
+ $Text = preg_replace_callback("/(.*?)\[attachment(.*?)\](.*?)\[\/attachment\]/ism",
function ($match) use ($plaintext){
- $attributes = $match[1];
+ $attributes = $match[2];
$type = "";
preg_match("/type='(.*?)'/ism", $attributes, $matches);
@@ -65,8 +65,13 @@ function bb_attachment($Text, $plaintext = false, $tryoembed = true) {
$preview = $matches[1];
}
+ if (((strpos($match[1], "[img=") !== false) OR (strpos($match[1], "[img]") !== false)) AND ($image != "")) {
+ $preview = $image;
+ $image = "";
+ }
+
if ($plaintext)
- $text = sprintf('%s', $url, $title);
+ $text = sprintf('%s ', $url, $title);
else {
$text = sprintf('', $type);
@@ -83,44 +88,15 @@ function bb_attachment($Text, $plaintext = false, $tryoembed = true) {
$text .= $oembed;
- $text .= sprintf('
')})}
\ No newline at end of file
diff --git a/js/webtoolkit.base64.min.js b/js/webtoolkit.base64.min.js
deleted file mode 100644
index 62c22eec4d..0000000000
--- a/js/webtoolkit.base64.min.js
+++ /dev/null
@@ -1 +0,0 @@
-var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(input){var output="";var chr1,chr2,chr3,enc1,enc2,enc3,enc4;var i=0;input=Base64._utf8_encode(input);while(i>2;enc2=(chr1&3)<<4|chr2>>4;enc3=(chr2&15)<<2|chr3>>6;enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64}else if(isNaN(chr3)){enc4=64}output=output+this._keyStr.charAt(enc1)+this._keyStr.charAt(enc2)+this._keyStr.charAt(enc3)+this._keyStr.charAt(enc4)}return output},decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64){output=output+String.fromCharCode(chr2)}if(enc4!=64){output=output+String.fromCharCode(chr3)}}output=Base64._utf8_decode(output);return output},_utf8_encode:function(string){string=string.replace(/\r\n/g,"\n");var utftext="";for(var n=0;n127&&c<2048){utftext+=String.fromCharCode(c>>6|192);utftext+=String.fromCharCode(c&63|128)}else{utftext+=String.fromCharCode(c>>12|224);utftext+=String.fromCharCode(c>>6&63|128);utftext+=String.fromCharCode(c&63|128)}}return utftext},_utf8_decode:function(utftext){var string="";var i=0;var c=c1=c2=0;while(i191&&c<224){c2=utftext.charCodeAt(i+1);string+=String.fromCharCode((c&31)<<6|c2&63);i+=2}else{c2=utftext.charCodeAt(i+1);c3=utftext.charCodeAt(i+2);string+=String.fromCharCode((c&15)<<12|(c2&63)<<6|c3&63);i+=3}}return string}};
\ No newline at end of file
diff --git a/library/HTML5/Parser.php b/library/HTML5/Parser.php
index 5f9ca560e5..c7faf875ad 100644
--- a/library/HTML5/Parser.php
+++ b/library/HTML5/Parser.php
@@ -17,6 +17,12 @@ class HTML5_Parser
* @return Parsed HTML as DOMDocument
*/
static public function parse($text, $builder = null) {
+
+ // Cleanup invalid HTML
+ $doc = new DOMDocument();
+ @$doc->loadHTML($text);
+ $text = $doc->saveHTML();
+
$tokenizer = new HTML5_Tokenizer($text, $builder);
$tokenizer->parse();
return $tokenizer->save();
diff --git a/library/Smarty/README b/library/Smarty/README
index 167462823f..50e0d60e59 100644
--- a/library/Smarty/README
+++ b/library/Smarty/README
@@ -1,4 +1,4 @@
-Smarty 3.1.11
+Smarty 3.1.19
Author: Monte Ohrt
Author: Uwe Tews
@@ -120,7 +120,7 @@ $smarty->unregisterObject($object_name)
$smarty->unregisterFilter($type, $function_name)
$smarty->unregisterResource($resource_type)
-$smarty->compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
+$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
$smarty->testInstall()
diff --git a/library/Smarty/SMARTY_3.1_NOTES.txt b/library/Smarty/SMARTY_3.1_NOTES.txt
index e56e56f67f..57709f0d72 100644
--- a/library/Smarty/SMARTY_3.1_NOTES.txt
+++ b/library/Smarty/SMARTY_3.1_NOTES.txt
@@ -199,7 +199,7 @@ Relative paths are available with {include file="..."} and
$smarty->fetch('./foo.tpl') cannot be relative to a template, an
exception is thrown.
- Adressing a specific $template_dir
+ Addressing a specific $template_dir
Smarty 3.1 introduces the $template_dir index notation.
$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"}
diff --git a/library/Smarty/change_log.txt b/library/Smarty/change_log.txt
index 27c506db69..7eb58320d0 100644
--- a/library/Smarty/change_log.txt
+++ b/library/Smarty/change_log.txt
@@ -1,5 +1,298 @@
-===== trunk =====
-===== Smarty-3.1.11 =====
+ ===== 3.1.20-dev ===== (xx.xx.2014)
+ ===== 3.1.19 ===== (06.30.2014)
+ 20.06.2014
+ - bugfix template variables could not be passed as paramter in {include} when the include was in a {nocache} section (topic 25131)
+
+ 17.06.2014
+ - bugfix large template text of some charsets could cause parsing errors (topic 24630)
+
+ 08.06.2014
+ - bugfix registered objects did not work after spelling fixes of 06.06.2014
+ - bugfix {block} tags within {literal} .. {/literal} got not displayed correctly (topic 25024)
+ - bugfix UNC WINDOWS PATH like "\\psf\path\to\dir" did not work as template directory (Issue 192)
+ - bugfix {html_image} security check did fail on files relative to basedir (Issue 191)
+
+ 06.06.2014
+ - fixed PHPUnit outputFilterTrimWhitespaceTests.php assertion of test result
+ - fixed spelling, PHPDoc , minor errors, code cleanup
+
+ 02.06.2014
+ - using multiple cwd with relative template dirs could result in identical compiled file names. (issue 194 and topic 25099)
+
+ 19.04.2014
+ - bugfix calling createTemplate(template, data) with empty data array caused notice of array to string conversion (Issue 189)
+ - bugfix clearCompiledTemplate() did not delete files on WINDOWS when a compile_id was specified
+
+ 18.04.2014
+ - revert bugfix of 5.4.2014 because %-e date format is not supported on all operating systems
+
+ ===== 3.1.18 ===== (07.04.2014)
+ 06.04.2014
+ - bugfix template inheritance fail when using custom resource after patch of 8.3.2014 (Issue 187)
+ - bugfix update of composer file (Issue 168 and 184)
+
+ 05.04.2014
+ - bugfix default date format leads to extra spaces when displaying dates with single digit days (Issue 165)
+
+ 26.03.2014
+ - bugfix Smart_Resource_Custom should not lowercase the resource name (Issue 183)
+
+ 24.03.2014
+ - bugfix using a {foreach} property like @iteration could fail when used in inheritance parent templates (Issue 182)
+
+ 20.03.2014
+ - bugfix $smarty->auto_literal and mbsting.func_overload 2, 6 or 7 did fail (forum topic 24899)
+
+ 18.03.2014
+ - revert change of 17.03.2014
+
+17.03.2014
+ - bugfix $smarty->auto_literal and mbsting.func_overload 2, 6 or 7 did fail (forum topic 24899)
+
+ 15.03.2014
+ - bugfix Smarty_CacheResource_Keyvaluestore did use different keys on read/writes and clearCache() calls (Issue 169)
+
+ 13.03.2014
+ - bugfix clearXxx() change of 27.1.2014 did not work when specifing cache_id or compile_id (forum topic 24868 and 24867)
+
+ ===== 3.1.17 =====
+ 08.03.2014
+ - bugfix relative file path {include} within {block} of child templates did throw exception on first call (Issue 177)
+
+ 17.02.2014
+ - bugfix Smarty failed when executing PHP on HHVM (Hip Hop 2.4) because uniqid('',true) does return string with ',' (forum topic 20343)
+
+ 16.02.2014
+ - bugfix a '//' or '\\' in template_dir path could produce wrong path on relative filepath in {include} (Issue 175)
+
+ 05.02.2014
+ - bugfix shared.literal_compiler_param.php did throw an exception when literal did contain a '-' (smarty-developers group)
+
+ 27.01.2014
+ - bugfix $smarty->debugging = true; did show the variable of the $smarty object not the variables used in display() call (forum topic 24764)
+ - bugfix clearCompiledTemplate(), clearAll() and clear() should use realpath to avoid possible exception from RecursiveDirectoryIterator (Issue 171)
+
+ 26.01.2014
+ - bugfix undo block nesting checks for {nocache} for reasons like forum topic 23280 (forum topic 24762)
+
+ 18.01.2014
+ - bugfix the compiler did fail when using template inheritance and recursive {include} (smarty-developers group)
+
+ 11.01.2014
+ - bugfix "* }" (spaces before right delimiter) was interpreted by mistake as comment end tag (Issue 170)
+ - internals content cache should be clear when updating cache file
+
+ 08.01.2014
+ - bugfix Smarty_CacheResource_Custom did not handle template resource type specifications on clearCache() calls (Issue 169)
+ - bugfix SmartyBC.class.php should use require_once to load Smarty.class.php (forum topic 24683)
+
+ ===== 3.1.16 =====
+ 15.12.2013
+ - bugfix {include} with {block} tag handling (forum topic 24599, 24594, 24682) (Issue 161)
+ Read 3.1.16_RELEASE_NOTES for more details
+ - enhancement additional debug output at $smarty->_parserdebug = true;
+
+ 07.11.2013
+ - bugfix too restrictive handling of {include} within {block} tags. 3.1.15 did throw errors where 3.1.14 did not (forum topic 24599)
+ - bugfix compiler could fail if PHP mbstring.func_overload is enabled (Issue 164)
+
+ 28.10.2013
+ - bugfix variable resource name at custom resource plugin did not work within {block} tags (Issue 163)
+ - bugfix notice "Trying to get property of non-object" removed (Issue 163)
+ - bugfix correction of modifier capitalize fix from 3.10.2013 (issue 159)
+ - bugfix multiple {block}s with same name in parent did not work (forum topic 24631)
+
+ 20.10.2013
+ - bugfix a variable file name at {extends} tag did fail (forum topic 24618)
+
+ 14.10.2013
+ - bugfix yesterdays fix could result in an undefined variable
+
+ 13.10.2013
+ - bugfix variable names on {include} in template inheritance did unextepted error message (forum topic 24594) (Issue 161)
+.- bugfix relative includes with same name like {include './foo.tpl'} from different folder failed (forum topic 24590)(Issue 161)
+
+ 04.10.2013
+ - bugfix variable file names at {extends} had been disbabled by mistake with the rewrite of
+ template inheritance of 24.08.2013 (forum topic 24585)
+
+03.10.2013
+ - bugfix loops using modifier capitalize did eat up memory (issue 159)
+
+ ===== Smarty 3.1.15 =====
+01.10.2013
+ - use current delimiters in compiler error messages (issue 157)
+ - improvement on performance when using error handler and multiple template folders (issue 152)
+
+17.09.2013
+ - improvement added patch for additional SmartyCompilerException properties for better access to scource information (forum topic 24559)
+
+16.09.2013
+ - bugfix recompiled templates did not show on first request with zend opcache cache (forum topic 24320)
+
+13.09.2013
+ - bugfix html_select_time defaulting error for the Meridian dropdown (forum topic 24549)
+
+09.09.2012
+- bugfix incorrect compiled code with array(object,method) callback at registered Variable Filter (forum topic 24542)
+
+27.08.2013
+- bugfix delimiter followed by linebreak did not work as auto literal after update from 24.08.2013 (forum topic 24518)
+
+24.08.2013
+- bugfix and enhancement
+ Because several recent problems with template inheritance the {block} tag compiler has been rewriten
+ - Error messages shown now the correct child template file and line number
+ - The compiler could fail on some larger UTF-8 text block (forum topic 24455)
+ - The {strip} tag can now be placed outside {block} tags in child templates (forum topic 24289)
+- change SmartyException::$escape is now false by default
+- change PHP traceback has been remove for SmartyException and SmartyCompilerException
+
+14.08.2013
+- bugfix compiled filepath of config file did not observe different config_dir (forum topic 24493)
+
+13.08.2013
+- bugfix the internal resource cache did not observe config_dir changes (forum topic 24493)
+
+12.08.2013
+- bugfix internal $tmpx variables must be unique over all inheritance templates (Issue 149)
+
+10.08.2013
+- bugfix a newline was eaten when a was passed by a Smarty variable and caching was enabled (forum topic 24482)
+
+29.07.2013
+- bugfix headers already send warning thrown when using 'SMARTY_DEBUG=on' from URL (Issue 148)
+
+27.07.2013
+- enhancement allow access to properties of registered opjects for Smarty2 BC (forum topic 24344)
+
+26.07.2013
+- bugfix template inheritance nesting problem (forum topic 24387)
+
+15.7.2013
+- update code generated by PSR-2 standards fixer which introduced PHP 5.4 incompatibilities of 14.7.2013
+
+14.7.2013
+- bugfix increase of internal maximum parser stacksize to allow more complex tag code {forum topic 24426}
+- update for PHP 5.4 compatibility
+- reformat source to PSR-2 standard
+
+12.7.2013
+- bugfix Do not remove '//' from file path at normalization (Issue 142)
+
+2.7.2013
+- bugfix trimwhitespace would replace captured items in wrong order (forum topic 24387)
+
+===== Smarty-3.1.14 =====
+27.06.2013
+- bugfix removed PHP 5.5 deprecated preg_replace /e option in modifier capitalize (forum topic 24389)
+
+17.06.2013
+- fixed spelling in sources and documentation (from smarty-developers forum Veres Lajos)
+- enhancement added constant SMARTY::CLEAR_EXPIRED for the change of 26.05.2013 (forum topic 24310)
+- bugfix added smarty_security.php to composer.json (Issue 135)
+
+26.05.2013
+- enhancement an expire_time of -1 in clearCache() and clearAllCache() will delete outdated cache files
+ by their individual cache_lifetime used at creation (forum topic 24310)
+
+21.05.2013
+- bugfix modifier strip_tags:true was compiled into wrong code (Forum Topic 24287)
+- bugfix /n after ?> in Smarty.class.php did start output buffering (Issue 138)
+
+25.04.2013
+- bugfix escape and wordrap modifier could be compiled into wrong code when used in {nocache}{/nocache}
+ section but caching is disabled (Forum Topic 24260)
+
+05.04.2013
+- bugfix post filter must not run when compiling inheritance child blocks (Forum Topic 24094)
+- bugfix after the fix for Issue #130 compiler exceptions got double escaped (Forum Topic 24199)
+
+28.02.2013
+- bugfix nocache blocks could be lost when using CACHING_LIFETIME_SAVED (Issue #133)
+- bugfix Compile ID gets nulled when compiling child blocks (Issue #134)
+
+
+24.01.2013
+- bugfix wrong tag type in smarty_internal_templatecompilerbase.php could cause wrong plugin search order (Forum Topic 24028)
+
+===== Smarty-3.1.13 =====
+13.01.2013
+- enhancement allow to disable exception message escaping by SmartyException::$escape = false; (Issue #130)
+
+09.01.2013
+- bugfix compilation did fail when a prefilter did modify an {extends} tag c
+- bugfix template inheritance could fail if nested {block} tags in childs did contain {$smarty.block.child} (Issue #127)
+- bugfix template inheritance could fail if {block} tags in childs did have similar name as used plugins (Issue #128)
+- added abstract method declaration doCompile() in Smarty_Internal_TemplateCompilerBase (Forum Topic 23969)
+
+06.01.2013
+- Allow '://' URL syntax in template names of stream resources (Issue #129)
+
+27.11.2012
+- bugfix wrong variable usage in smarty_internal_utility.php (Issue #125)
+
+26.11.2012
+- bugfix global variable assigned within template function are not seen after template function exit (Forum Topic 23800)
+
+24.11.2012
+- made SmartyBC loadable via composer (Issue #124)
+
+20.11.2012
+- bugfix assignGlobal() called from plugins did not work (Forum Topic 23771)
+
+13.11.2012
+- adding attribute "strict" to html_options, html_checkboxes, html_radios to only print disabled/readonly attributes if their values are true or "disabled"/"readonly" (Issue #120)
+
+01.11.2012
+- bugfix muteExcpetedErrors() would screw up for non-readable paths (Issue #118)
+
+===== Smarty-3.1.12 =====
+14.09.2012
+- bugfix template inheritance failed to compile with delimiters {/ and /} (Forum Topic 23008)
+
+11.09.2012
+- bugfix escape Smarty exception messages to avoid possible script execution
+
+10.09.2012
+- bugfix tag option flags and shorttag attributes did not work when rdel started with '=' (Forum Topic 22979)
+
+31.08.2012
+- bugfix resolving relative paths broke in some circumstances (Issue #114)
+
+22.08.2012
+- bugfix test MBString availability through mb_split, as it could've been compiled without regex support (--enable-mbregex).
+ Either we get MBstring's full package, or we pretend it's not there at all.
+
+21.08.2012
+- bugfix $auto_literal = false did not work with { block} tags in child templates
+ (problem was reintroduced after fix in 3.1.7)(Forum Topic 20581)
+
+17.08.2012
+- bugfix compiled code of nocache sections could contain wrong escaping (Forum Topic 22810)
+
+15.08.2012
+- bugfix template inheritance did produce wrong code if subtemplates with {block} was
+ included several times (from smarty-developers forum)
+
+14.08.2012
+- bugfix PHP5.2 compatibility compromised by SplFileInfo::getBasename() (Issue 110)
+
+01.08.2012
+- bugfix avoid PHP error on $smarty->configLoad(...) with invalid section specification (Forum Topic 22608)
+
+30.07.2012
+-bugfix {assign} in a nocache section should not overwrite existing variable values
+ during compilation (issue 109)
+
+28.07.2012
+- bugfix array access of config variables did not work (Forum Topic 22527)
+
+19.07.2012
+- bugfix the default plugin handler did create wrong compiled code for static class methods
+ from external script files (issue 108)
+
+===== Smarty-3.1.11 =====
30.06.2012
- bugfix {block.. hide} did not work as nested child (Forum Topic 22216)
@@ -342,7 +635,7 @@
03/09/2011
- bugfix createTemplate() must default to cache_id and compile_id of Smarty object
- bugfix Smarty_CacheResource_KeyValueStore must include $source->uid in cache filepath to keep templates with same
- name but different folders seperated
+ name but different folders separated
- added cacheresource.apc.php example in demo folder
02/09/2011
@@ -533,7 +826,7 @@
- changed ./ and ../ behaviour
14/02/2011
-- added {block ... hide} option to supress block if no child is defined
+- added {block ... hide} option to suppress block if no child is defined
13/02/2011
- update handling of recursive subtemplate calls
@@ -647,7 +940,7 @@
- bugfix on compiler object destruction. compiler_object property was by mistake unset.
09/03/2011
--bugfix a variable filter should run before modifers on an output tag (see change of 23/07/2010)
+-bugfix a variable filter should run before modifiers on an output tag (see change of 23/07/2010)
08/03/2011
- bugfix loading config file without section should load only defaults
@@ -951,10 +1244,10 @@ request_use_auto_globals
- bugfix passing scope attributes in doublequoted strings did not work at {include} {assign} and {append}
25/07/2010
-- another bugfix of change from 23/07/2010 when compiling modifer
+- another bugfix of change from 23/07/2010 when compiling modifier
24/07/2010
-- bugfix of change from 23/07/2010 when compiling modifer
+- bugfix of change from 23/07/2010 when compiling modifier
23/07/2010
- changed execution order. A variable filter does now run before modifiers on output of variables
@@ -1261,7 +1554,7 @@ request_use_auto_globals
- bugfix on {if} tags
01/12/2010
-- changed back modifer handling in parser. Some restrictions still apply:
+- changed back modifier handling in parser. Some restrictions still apply:
if modifiers are used in side {if...} expression or in mathematical expressions
parentheses must be used.
- bugfix the {function..} tag did not accept the name attribute in double quotes
@@ -1873,7 +2166,7 @@ NOTICE: existing compiled template and cache files must be deleted
- fixed exceptions in function plugins
- fixed notice error in Smarty.class.php
- allow chained objects to span multiple lines
-- fixed error in modifers
+- fixed error in modifiers
03/20/2009
- moved /plugins folder into /libs folder
@@ -1881,7 +2174,7 @@ NOTICE: existing compiled template and cache files must be deleted
- autoappend a directory separator if the xxxxx_dir definition have no trailing one
03/19/2009
-- allow array definition as modifer parameter
+- allow array definition as modifier parameter
- changed modifier to use multi byte string funktions.
03/17/2009
diff --git a/library/Smarty/demo/index.php b/library/Smarty/demo/index.php
index 74c8e89712..33f3035c5b 100644
--- a/library/Smarty/demo/index.php
+++ b/library/Smarty/demo/index.php
@@ -1,33 +1,30 @@
force_compile = true;
$smarty->debugging = true;
$smarty->caching = true;
$smarty->cache_lifetime = 120;
-$smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill",true);
-$smarty->assign("FirstName",array("John","Mary","James","Henry"));
-$smarty->assign("LastName",array("Doe","Smith","Johnson","Case"));
-$smarty->assign("Class",array(array("A","B","C","D"), array("E", "F", "G", "H"),
- array("I", "J", "K", "L"), array("M", "N", "O", "P")));
+$smarty->assign("Name", "Fred Irving Johnathan Bradley Peppergill", true);
+$smarty->assign("FirstName", array("John", "Mary", "James", "Henry"));
+$smarty->assign("LastName", array("Doe", "Smith", "Johnson", "Case"));
+$smarty->assign("Class", array(array("A", "B", "C", "D"), array("E", "F", "G", "H"),
+ array("I", "J", "K", "L"), array("M", "N", "O", "P")));
$smarty->assign("contacts", array(array("phone" => "1", "fax" => "2", "cell" => "3"),
- array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234")));
+ array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234")));
-$smarty->assign("option_values", array("NY","NE","KS","IA","OK","TX"));
-$smarty->assign("option_output", array("New York","Nebraska","Kansas","Iowa","Oklahoma","Texas"));
+$smarty->assign("option_values", array("NY", "NE", "KS", "IA", "OK", "TX"));
+$smarty->assign("option_output", array("New York", "Nebraska", "Kansas", "Iowa", "Oklahoma", "Texas"));
$smarty->assign("option_selected", "NE");
$smarty->display('index.tpl');
-?>
diff --git a/library/Smarty/demo/plugins/cacheresource.apc.php b/library/Smarty/demo/plugins/cacheresource.apc.php
index 00ba598178..d7336f2bf7 100644
--- a/library/Smarty/demo/plugins/cacheresource.apc.php
+++ b/library/Smarty/demo/plugins/cacheresource.apc.php
@@ -2,19 +2,19 @@
/**
* APC CacheResource
- *
* CacheResource Implementation based on the KeyValueStore API to use
* memcache as the storage resource for Smarty's output caching.
* *
+ *
* @package CacheResource-examples
- * @author Uwe Tews
+ * @author Uwe Tews
*/
-class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore {
-
+class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore
+{
public function __construct()
{
// test if APC is present
- if(!function_exists('apc_cache_info')) {
+ if (!function_exists('apc_cache_info')) {
throw new Exception('APC Template Caching Error: APC is not installed');
}
}
@@ -22,8 +22,9 @@ class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore {
/**
* Read values for a set of keys from cache
*
- * @param array $keys list of keys to fetch
- * @return array list of values with the given keys used as indexes
+ * @param array $keys list of keys to fetch
+ *
+ * @return array list of values with the given keys used as indexes
* @return boolean true on success, false on failure
*/
protected function read(array $keys)
@@ -33,28 +34,32 @@ class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore {
foreach ($res as $k => $v) {
$_res[$k] = $v;
}
+
return $_res;
}
/**
* Save values for a set of keys to cache
*
- * @param array $keys list of values to save
- * @param int $expire expiration time
+ * @param array $keys list of values to save
+ * @param int $expire expiration time
+ *
* @return boolean true on success, false on failure
*/
- protected function write(array $keys, $expire=null)
+ protected function write(array $keys, $expire = null)
{
foreach ($keys as $k => $v) {
apc_store($k, $v, $expire);
}
+
return true;
}
/**
* Remove values from cache
*
- * @param array $keys list of keys to delete
+ * @param array $keys list of keys to delete
+ *
* @return boolean true on success, false on failure
*/
protected function delete(array $keys)
@@ -62,6 +67,7 @@ class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore {
foreach ($keys as $k) {
apc_delete($k);
}
+
return true;
}
diff --git a/library/Smarty/demo/plugins/cacheresource.memcache.php b/library/Smarty/demo/plugins/cacheresource.memcache.php
index 230607d696..e265365fbb 100644
--- a/library/Smarty/demo/plugins/cacheresource.memcache.php
+++ b/library/Smarty/demo/plugins/cacheresource.memcache.php
@@ -2,34 +2,35 @@
/**
* Memcache CacheResource
- *
* CacheResource Implementation based on the KeyValueStore API to use
* memcache as the storage resource for Smarty's output caching.
- *
* Note that memcache has a limitation of 256 characters per cache-key.
* To avoid complications all cache-keys are translated to a sha1 hash.
*
* @package CacheResource-examples
- * @author Rodney Rehm
+ * @author Rodney Rehm
*/
-class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore {
+class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore
+{
/**
* memcache instance
+ *
* @var Memcache
*/
protected $memcache = null;
-
+
public function __construct()
{
$this->memcache = new Memcache();
- $this->memcache->addServer( '127.0.0.1', 11211 );
+ $this->memcache->addServer('127.0.0.1', 11211);
}
-
+
/**
* Read values for a set of keys from cache
*
- * @param array $keys list of keys to fetch
- * @return array list of values with the given keys used as indexes
+ * @param array $keys list of keys to fetch
+ *
+ * @return array list of values with the given keys used as indexes
* @return boolean true on success, false on failure
*/
protected function read(array $keys)
@@ -45,29 +46,33 @@ class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore {
foreach ($res as $k => $v) {
$_res[$lookup[$k]] = $v;
}
+
return $_res;
}
-
+
/**
* Save values for a set of keys to cache
*
- * @param array $keys list of values to save
- * @param int $expire expiration time
+ * @param array $keys list of values to save
+ * @param int $expire expiration time
+ *
* @return boolean true on success, false on failure
*/
- protected function write(array $keys, $expire=null)
+ protected function write(array $keys, $expire = null)
{
foreach ($keys as $k => $v) {
$k = sha1($k);
$this->memcache->set($k, $v, 0, $expire);
}
+
return true;
}
/**
* Remove values from cache
*
- * @param array $keys list of keys to delete
+ * @param array $keys list of keys to delete
+ *
* @return boolean true on success, false on failure
*/
protected function delete(array $keys)
@@ -76,6 +81,7 @@ class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore {
$k = sha1($k);
$this->memcache->delete($k);
}
+
return true;
}
@@ -86,6 +92,6 @@ class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore {
*/
protected function purge()
{
- return $this->memcache->flush();
+ $this->memcache->flush();
}
}
diff --git a/library/Smarty/demo/plugins/cacheresource.mysql.php b/library/Smarty/demo/plugins/cacheresource.mysql.php
index ab8c475164..d8d00ab261 100644
--- a/library/Smarty/demo/plugins/cacheresource.mysql.php
+++ b/library/Smarty/demo/plugins/cacheresource.mysql.php
@@ -2,10 +2,8 @@
/**
* MySQL CacheResource
- *
* CacheResource Implementation based on the Custom API to use
* MySQL as the storage resource for Smarty's output caching.
- *
* Table definition:
*
CREATE TABLE IF NOT EXISTS `output_cache` (
* `id` CHAR(40) NOT NULL COMMENT 'sha1 hash',
@@ -22,19 +20,22 @@
* ) ENGINE = InnoDB;
*
* @package CacheResource-examples
- * @author Rodney Rehm
+ * @author Rodney Rehm
*/
-class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
+class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom
+{
// PDO instance
protected $db;
protected $fetch;
protected $fetchTimestamp;
protected $save;
-
- public function __construct() {
+
+ public function __construct()
+ {
try {
- $this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty", "smarty");
- } catch (PDOException $e) {
+ $this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
+ }
+ catch (PDOException $e) {
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
}
$this->fetch = $this->db->prepare('SELECT modified, content FROM output_cache WHERE id = :id');
@@ -46,19 +47,20 @@ class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
/**
* fetch cached content and its modification time from data source
*
- * @param string $id unique cache content identifier
- * @param string $name template name
- * @param string $cache_id cache id
- * @param string $compile_id compile id
- * @param string $content cached content
- * @param integer $mtime cache modification timestamp (epoch)
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param string $content cached content
+ * @param integer $mtime cache modification timestamp (epoch)
+ *
* @return void
*/
protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime)
{
$this->fetch->execute(array('id' => $id));
$row = $this->fetch->fetch();
- $this->fetch->closeCursor();
+ $this->fetch->closeCursor();
if ($row) {
$content = $row['content'];
$mtime = strtotime($row['modified']);
@@ -67,15 +69,17 @@ class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
$mtime = null;
}
}
-
+
/**
* Fetch cached content's modification timestamp from data source
*
* @note implementing this method is optional. Only implement it if modification times can be accessed faster than loading the complete cached content.
- * @param string $id unique cache content identifier
- * @param string $name template name
- * @param string $cache_id cache id
- * @param string $compile_id compile id
+ *
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ *
* @return integer|boolean timestamp (epoch) the template was modified, or false if not found
*/
protected function fetchTimestamp($id, $name, $cache_id, $compile_id)
@@ -83,40 +87,44 @@ class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
$this->fetchTimestamp->execute(array('id' => $id));
$mtime = strtotime($this->fetchTimestamp->fetchColumn());
$this->fetchTimestamp->closeCursor();
+
return $mtime;
}
-
+
/**
* Save content to cache
*
- * @param string $id unique cache content identifier
- * @param string $name template name
- * @param string $cache_id cache id
- * @param string $compile_id compile id
- * @param integer|null $exp_time seconds till expiration time in seconds or null
- * @param string $content content to cache
- * @return boolean success
+ * @param string $id unique cache content identifier
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer|null $exp_time seconds till expiration time in seconds or null
+ * @param string $content content to cache
+ *
+ * @return boolean success
*/
protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content)
{
$this->save->execute(array(
- 'id' => $id,
- 'name' => $name,
- 'cache_id' => $cache_id,
- 'compile_id' => $compile_id,
- 'content' => $content,
- ));
+ 'id' => $id,
+ 'name' => $name,
+ 'cache_id' => $cache_id,
+ 'compile_id' => $compile_id,
+ 'content' => $content,
+ ));
+
return !!$this->save->rowCount();
}
-
+
/**
* Delete content from cache
*
- * @param string $name template name
- * @param string $cache_id cache id
- * @param string $compile_id compile id
- * @param integer|null $exp_time seconds till expiration or null
- * @return integer number of deleted caches
+ * @param string $name template name
+ * @param string $cache_id cache id
+ * @param string $compile_id compile id
+ * @param integer|null $exp_time seconds till expiration or null
+ *
+ * @return integer number of deleted caches
*/
protected function delete($name, $cache_id, $compile_id, $exp_time)
{
@@ -124,7 +132,8 @@ class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
// returning the number of deleted caches would require a second query to count them
$query = $this->db->query('TRUNCATE TABLE output_cache');
- return -1;
+
+ return - 1;
}
// build the filter
$where = array();
@@ -142,11 +151,12 @@ class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
}
// equal test cache_id and match sub-groups
if ($cache_id !== null) {
- $where[] = '(cache_id = '. $this->db->quote($cache_id)
- . ' OR cache_id LIKE '. $this->db->quote($cache_id .'|%') .')';
+ $where[] = '(cache_id = ' . $this->db->quote($cache_id)
+ . ' OR cache_id LIKE ' . $this->db->quote($cache_id . '|%') . ')';
}
// run delete query
$query = $this->db->query('DELETE FROM output_cache WHERE ' . join(' AND ', $where));
+
return $query->rowCount();
}
}
diff --git a/library/Smarty/demo/plugins/resource.extendsall.php b/library/Smarty/demo/plugins/resource.extendsall.php
index d8c40b5bae..500b3c8623 100644
--- a/library/Smarty/demo/plugins/resource.extendsall.php
+++ b/library/Smarty/demo/plugins/resource.extendsall.php
@@ -2,49 +2,51 @@
/**
* Extends All Resource
- *
* Resource Implementation modifying the extends-Resource to walk
* through the template_dirs and inherit all templates of the same name
- *
+ *
* @package Resource-examples
- * @author Rodney Rehm
+ * @author Rodney Rehm
*/
-class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends {
-
+class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends
+{
/**
* populate Source Object with meta data from Resource
*
- * @param Smarty_Template_Source $source source object
- * @param Smarty_Internal_Template $_template template object
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ *
* @return void
*/
- public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
{
$uid = '';
$sources = array();
$exists = true;
foreach ($_template->smarty->getTemplateDir() as $key => $directory) {
try {
- $s = Smarty_Resource::source(null, $source->smarty, '[' . $key . ']' . $source->name );
+ $s = Smarty_Resource::source(null, $source->smarty, '[' . $key . ']' . $source->name);
if (!$s->exists) {
continue;
}
$sources[$s->uid] = $s;
$uid .= $s->filepath;
}
- catch (SmartyException $e) {}
+ catch (SmartyException $e) {
+ }
}
-
+
if (!$sources) {
$source->exists = false;
$source->template = $_template;
+
return;
}
-
+
$sources = array_reverse($sources, true);
reset($sources);
$s = current($sources);
-
+
$source->components = $sources;
$source->filepath = $s->filepath;
$source->uid = sha1($uid);
@@ -55,6 +57,4 @@ class Smarty_Resource_Extendsall extends Smarty_Internal_Resource_Extends {
// need the template at getContent()
$source->template = $_template;
}
-}
-
-?>
\ No newline at end of file
+}
diff --git a/library/Smarty/demo/plugins/resource.mysql.php b/library/Smarty/demo/plugins/resource.mysql.php
index 312f3fc73c..dfc9606b4e 100644
--- a/library/Smarty/demo/plugins/resource.mysql.php
+++ b/library/Smarty/demo/plugins/resource.mysql.php
@@ -2,10 +2,8 @@
/**
* MySQL Resource
- *
* Resource Implementation based on the Custom API to use
* MySQL as the storage resource for Smarty's templates and configs.
- *
* Table definition:
*
CREATE TABLE IF NOT EXISTS `templates` (
* `name` varchar(100) NOT NULL,
@@ -13,14 +11,14 @@
* `source` text,
* PRIMARY KEY (`name`)
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
{* bold and title are read from the config file *}
-{if #bold#}{/if}
-{* capitalize the first letters of each word of the title *}
-Title: {#title#|capitalize}
-{if #bold#}{/if}
+ {if #bold#}{/if}
+ {* capitalize the first letters of each word of the title *}
+ Title: {#title#|capitalize}
+ {if #bold#}{/if}
-The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
+ The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
-The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
+ The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
-Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
+ Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
-The value of {ldelim}$Name{rdelim} is {$Name}
+ The value of {ldelim}$Name{rdelim} is {$Name}
variable modifier example of {ldelim}$Name|upper{rdelim}
@@ -24,59 +24,64 @@ variable modifier example of {ldelim}$Name|upper{rdelim}
An example of a section loop:
-{section name=outer
-loop=$FirstName}
-{if $smarty.section.outer.index is odd by 2}
- {$smarty.section.outer.rownum} . {$FirstName[outer]} {$LastName[outer]}
-{else}
- {$smarty.section.outer.rownum} * {$FirstName[outer]} {$LastName[outer]}
-{/if}
-{sectionelse}
- none
-{/section}
+ {section name=outer
+ loop=$FirstName}
+ {if $smarty.section.outer.index is odd by 2}
+ {$smarty.section.outer.rownum} . {$FirstName[outer]} {$LastName[outer]}
+ {else}
+ {$smarty.section.outer.rownum} * {$FirstName[outer]} {$LastName[outer]}
+ {/if}
+ {sectionelse}
+ none
+ {/section}
-An example of section looped key values:
+ An example of section looped key values:
-{section name=sec1 loop=$contacts}
- phone: {$contacts[sec1].phone}
- fax: {$contacts[sec1].fax}
- cell: {$contacts[sec1].cell}
-{/section}
-