Merge branch 'release-3.4.3-rc'

This commit is contained in:
Fabrixxm 2015-12-22 10:43:57 +01:00
commit c007722041
295 changed files with 39666 additions and 25659 deletions

View file

@ -1,6 +1,85 @@
Version 3.4.3
What's new for the users:
Updates to the documentation (silke, tobiasd, annando, rebeka-catalina)
Updated translations (tobiasd & translation teams)
New "Credits" page (tobiasd)
New custom font icon set (tobiasd, Andi Stadler)
Support to events attendance. Users can mark their participation to an event (rabuzarus, tobiasd, fabrixxm, annando)
Revised templates and used interaction in contacts lists (rabuzarus)
Mobile support for Vier theme (annando, fabrixxm)
Events editing and deletion from stream (annando)
Private forums are mentioned automatically like community forums (rabuzarus)
Show profile pictures and pending notifications on manage page (rabuzarus, annando)
Show Profile photo album only to owner and authenticated contacts (rabuzarus)
User language setting is now between settings in user settings page (fabrixxm)
Search for remote users in form of "@user@domain.tld" is supported (issue #1595) (annando)
Optionally show geo informations of uploaded photos, backport from Red (rabuzarus)
Setting for the first day of the week for events calendar (annando)
Reduced profile view with "show more" link (annando)
Show more informations to users when following a new contact (annando)
Renamed "Statusnet" to "GNU Social" (annando)
Image dialog insert link to image page instead of direct image (fabrixxm)
In registration page make clear that we only need a 'real-looking' name (issue #1898) (tobiasd, n4rky)
Unseen items per groups are shown (issue #1718) (strk, rabuzarus, fabrixxm)
Unseen items in forumlist widget (rabuzarus)
Preview the last five conversations in private message's sidebar (FlxAlbroscheit, fabrixxm)
Don't get notifications about own posts (strk)
Profile page shows a "Subscribe to atom feed" link (annando)
Contact list shows only contacts from supported networks (ananndo)
username@hostname is used instead of full urls (issue #1925) (annando)
Various small OStatus improvements (annando)
Contact's posts are shown in a dedicated page (annando)
Module name is shown in page title to ease browser history navigation (issue #2079) (tobiasd)
What's new for admins:
Forumlist functionality moved from plugin to core (rabuzarus, annando)
Changes on poller/workers limits management (annando)
Diaspora and OStatus can be enabled only if requirements are satisfied (annando)
Support for additional passwords for ejabberd (annando)
Use proxy for profile photos (annando)
'Reload active themes' in theme admin page (fabrixxm)
Install routine checks for ImageMagick and GIF support (fabrixxm)
Install routine checks for availability of "mcrypt_create_iv()" function, needed for RINO2 (fabrixxm)
Only suported themes are shown in admin page (annando)
Optimized SQL queries (annando)
System perform an optimize pass on tables in cron, with maximum table size and minimum fragmentation level settings (annando)
New access keys in profile and contact pages (rabuzarus, annando)
Support for a new Diaspora command for post retraction (annando)
Show an info message if an empty contact group is shown (issue #1871) (annando)
User setting to disable network page autoupdate (issue #1921) (annando)
Settings to limit or permit access to crawler to search page (annando)
What's new for developers:
Themes can show Events entry in navbar (annando)
Themes can now override colorbox (fabrixxm)
Updated Vagrant development VM (silke, hauke)
New hook 'template_vars' (fabrixxm)
$baseurl variable is passed to all templates by default (fabrixxm)
OStatus delivery code is moved in new function (annando)
Doxygen config file and initial documetation of code (rabuzarus)
Full rewrite of util/php2po.php (fabrixxm)
Bugfixs:
Remote self works again (annando)
Fix feeds mistakenly recognized as OStatus (issue #1914) (annando)
Report invalid feeds to user (issue #1913) (annando)
Fix Update contact data functionality (annando)
Fix proxy function with embedded images (annando)
Fix Diaspora unidirectional connect request (annando)
Fix empty poco response (annando)
Fix API for andStatus (issue#1427, AndStatus issue #241) (annando)
Fix expiration of items (fabrixxm)
Fix javascript contact deletion confirmation dialog (issue #1986) (fabrixxm)
Admin wasn't able to change settings of not currently in use themes. Fixed (issue #2022) (fabrixxm)
Fix rapid repeated requests to GNUSocial instance (issue #2038) (annando)
Fix install routine css when mod_rewrite doesn't works (issue #2071) (fabrixxm)
Fix code to be compliant with minimum required PHP version (issue #2066) (fabrixxm, rabuzarus)
Fix feedback after succesfull registration (issue #2060) (annando)
Fix mention completition popup with TinyMCE (issue #1920) (fabrixxm)
Fix photo cache and proxy when installed in subfolder (ddorian1)
Fix bbcode conversion of the about text for the profile (issue #1607) (annando)
Version 3.4.2 Version 3.4.2
Updates to the documentation (tobias, silke, annando) Updates to the documentation (tobiasd, silke, annando)
Updates to the translations (tobiasd & translation teams) Updates to the translations (tobiasd & translation teams)
Updates to themes frost-mobile, vier, duepuntozero, quattro (annando, tobiasd) Updates to themes frost-mobile, vier, duepuntozero, quattro (annando, tobiasd)
Enancements of the communications via OStatus and Diaspora protocols (annando) Enancements of the communications via OStatus and Diaspora protocols (annando)

56
Vagrantfile vendored
View file

@ -5,12 +5,15 @@ server_timezone = "UTC"
public_folder = "/vagrant" public_folder = "/vagrant"
Vagrant.configure("2") do |config| Vagrant.configure(2) do |config|
# Set server to Ubuntu 12.04 # Set server to Ubuntu 14.04
config.vm.box = "precise64" config.vm.box = "ubuntu/trusty64"
config.vm.box_url = "http://files.vagrantup.com/precise64.box" # Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a hostname, don't forget to put it to the `hosts` file # Create a hostname, don't forget to put it to the `hosts` file
# This will point to the server's default virtual host # This will point to the server's default virtual host
@ -20,40 +23,21 @@ Vagrant.configure("2") do |config|
# Create a static IP # Create a static IP
config.vm.network :private_network, ip: server_ip config.vm.network :private_network, ip: server_ip
# If using VirtualBox # Share a folder between host and guest
config.vm.provider :virtualbox do |vb| config.vm.synced_folder "./", "/vagrant/", owner: "www-data", group: "vagrant"
# Set server memory
vb.customize ["modifyvm", :id, "--memory", server_memory]
# Set the timesync threshold to 10 seconds, instead of the default 20 minutes.
# If the clock gets more than 15 minutes out of sync (due to your laptop going
# to sleep for instance, then some 3rd party services will reject requests.
vb.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 10000]
# Prevent VMs running on Ubuntu to lose internet connection
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
vb.memory = server_memory
end end
# If using VMWare Fusion # Enable provisioning with a shell script.
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
####
# Local Scripts
# Any local scripts you may want to run post-provisioning.
# Add these to the same directory as the Vagrantfile.
##########
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" config.vm.provision "shell", path: "./util/vagrant_provision.sh"
# run: "always"
# run: "once"
end end

114
boot.php
View file

@ -17,9 +17,9 @@ require_once('include/dbstructure.php');
define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_CODENAME', 'Lily of the valley'); define ( 'FRIENDICA_CODENAME', 'Lily of the valley');
define ( 'FRIENDICA_VERSION', '3.4.2' ); define ( 'FRIENDICA_VERSION', '3.4.3-rc' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1188 ); define ( 'DB_UPDATE_VERSION', 1191 );
define ( 'EOL', "<br />\r\n" ); define ( 'EOL', "<br />\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
@ -163,7 +163,8 @@ define ( 'NETWORK_TWITTER', 'twit'); // Twitter
define ( 'NETWORK_DIASPORA2', 'dspc'); // Diaspora connector define ( 'NETWORK_DIASPORA2', 'dspc'); // Diaspora connector
define ( 'NETWORK_STATUSNET', 'stac'); // Statusnet connector define ( 'NETWORK_STATUSNET', 'stac'); // Statusnet connector
define ( 'NETWORK_APPNET', 'apdn'); // app.net define ( 'NETWORK_APPNET', 'apdn'); // app.net
define ( 'NETWORK_NEWS', 'nntp'); // Network News Transfer Protocol
define ( 'NETWORK_ICALENDAR', 'ical'); // iCalendar
define ( 'NETWORK_PHANTOM', 'unkn'); // Place holder define ( 'NETWORK_PHANTOM', 'unkn'); // Place holder
/** /**
@ -190,6 +191,8 @@ $netgroup_ids = array(
NETWORK_DIASPORA2 => (-15), NETWORK_DIASPORA2 => (-15),
NETWORK_STATUSNET => (-16), NETWORK_STATUSNET => (-16),
NETWORK_APPNET => (-17), NETWORK_APPNET => (-17),
NETWORK_NEWS => (-18),
NETWORK_ICALENDAR => (-19),
NETWORK_PHANTOM => (-127), NETWORK_PHANTOM => (-127),
); );
@ -270,6 +273,10 @@ define ( 'NAMESPACE_ATOM1', 'http://www.w3.org/2005/Atom' );
define ( 'ACTIVITY_LIKE', NAMESPACE_ACTIVITY_SCHEMA . 'like' ); define ( 'ACTIVITY_LIKE', NAMESPACE_ACTIVITY_SCHEMA . 'like' );
define ( 'ACTIVITY_DISLIKE', NAMESPACE_DFRN . '/dislike' ); define ( 'ACTIVITY_DISLIKE', NAMESPACE_DFRN . '/dislike' );
define ( 'ACTIVITY_ATTEND', NAMESPACE_ZOT . '/activity/attendyes' );
define ( 'ACTIVITY_ATTENDNO', NAMESPACE_ZOT . '/activity/attendno' );
define ( 'ACTIVITY_ATTENDMAYBE', NAMESPACE_ZOT . '/activity/attendmaybe' );
define ( 'ACTIVITY_OBJ_HEART', NAMESPACE_DFRN . '/heart' ); define ( 'ACTIVITY_OBJ_HEART', NAMESPACE_DFRN . '/heart' );
define ( 'ACTIVITY_FRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'make-friend' ); define ( 'ACTIVITY_FRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'make-friend' );
@ -408,6 +415,7 @@ if(! class_exists('App')) {
public $videoheight = 350; public $videoheight = 350;
public $force_max_items = 0; public $force_max_items = 0;
public $theme_thread_allow = true; public $theme_thread_allow = true;
public $theme_events_in_profile = true;
// An array for all theme-controllable parameters // An array for all theme-controllable parameters
// Mostly unimplemented yet. Only options 'stylesheet' and // Mostly unimplemented yet. Only options 'stylesheet' and
@ -626,6 +634,9 @@ if(! class_exists('App')) {
$basepath = get_config("system", "basepath"); $basepath = get_config("system", "basepath");
if ($basepath == "")
$basepath = dirname(__FILE__);
if ($basepath == "") if ($basepath == "")
$basepath = $_SERVER["DOCUMENT_ROOT"]; $basepath = $_SERVER["DOCUMENT_ROOT"];
@ -726,10 +737,22 @@ if(! class_exists('App')) {
function init_pagehead() { function init_pagehead() {
$interval = ((local_user()) ? get_pconfig(local_user(),'system','update_interval') : 40000); $interval = ((local_user()) ? get_pconfig(local_user(),'system','update_interval') : 40000);
// If the update is "deactivated" set it to the highest integer number (~24 days)
if ($interval < 0)
$interval = 2147483647;
if($interval < 10000) if($interval < 10000)
$interval = 40000; $interval = 40000;
// compose the page title from the sitename and the
// current module called
if (!$this->module=='')
{
$this->page['title'] = $this->config['sitename'].' ('.$this->module.')';
} else {
$this->page['title'] = $this->config['sitename']; $this->page['title'] = $this->config['sitename'];
}
/* put the head template at the beginning of page['htmlhead'] /* put the head template at the beginning of page['htmlhead']
* since the code added by the modules frequently depends on it * since the code added by the modules frequently depends on it
@ -1432,8 +1455,46 @@ if(! function_exists('proc_run')) {
if(! $arr['run_cmd']) if(! $arr['run_cmd'])
return; return;
if(count($args) && $args[0] === 'php') if(count($args) && $args[0] === 'php') {
if (get_config("system", "worker")) {
$argv = $args;
array_shift($argv);
$parameters = json_encode($argv);
$found = q("SELECT `id` FROM `workerqueue` WHERE `parameter` = '%s'",
dbesc($parameters));
if (!$found)
q("INSERT INTO `workerqueue` (`parameter`, `created`, `priority`)
VALUES ('%s', '%s', %d)",
dbesc($parameters),
dbesc(datetime_convert()),
intval(0));
// Should we quit and wait for the poller to be called as a cronjob?
if (get_config("system", "worker_dont_fork"))
return;
// Checking number of workers
$workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
// Get number of allowed number of worker threads
$queues = intval(get_config("system", "worker_queues"));
if ($queues == 0)
$queues = 4;
// If there are already enough workers running, don't fork another one
if ($workers[0]["workers"] >= $queues)
return;
// Now call the poller to execute the jobs that we just added to the queue
$args = array("php", "include/poller.php", "no_cron");
}
$args[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : '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 // add baseurl to args. cli scripts can't construct it
$args[] = $a->get_baseurl(); $args[] = $a->get_baseurl();
@ -1441,9 +1502,8 @@ if(! function_exists('proc_run')) {
for($x = 0; $x < count($args); $x ++) for($x = 0; $x < count($args); $x ++)
$args[$x] = escapeshellarg($args[$x]); $args[$x] = escapeshellarg($args[$x]);
$cmdline = implode($args," "); $cmdline = implode($args," ");
if(get_config('system','proc_windows')) if(get_config('system','proc_windows'))
proc_close(proc_open('cmd /c start /b ' . $cmdline,array(),$foo,dirname(__FILE__))); proc_close(proc_open('cmd /c start /b ' . $cmdline,array(),$foo,dirname(__FILE__)));
else else
@ -1620,7 +1680,7 @@ if(! function_exists('load_contact_links')) {
if(! $uid || x($a->contacts,'empty')) if(! $uid || x($a->contacts,'empty'))
return; return;
$r = q("SELECT `id`,`network`,`url`,`thumb` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `thumb` != ''", $r = q("SELECT `id`,`network`,`url`,`thumb`, `rel` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `thumb` != ''",
intval($uid) intval($uid)
); );
if(count($r)) { if(count($r)) {
@ -1860,3 +1920,43 @@ if(!function_exists('exif_imagetype')) {
return($size[2]); return($size[2]);
} }
} }
function validate_include(&$file) {
$orig_file = $file;
$file = realpath($file);
if (strpos($file, getcwd()) !== 0)
return false;
$file = str_replace(getcwd()."/", "", $file, $count);
if ($count != 1)
return false;
if ($orig_file !== $file)
return false;
$valid = false;
if (strpos($file, "include/") === 0)
$valid = true;
if (strpos($file, "addon/") === 0)
$valid = true;
if (!$valid)
return false;
return true;
}
function current_load() {
if (!function_exists('sys_getloadavg'))
return false;
$load_arr = sys_getloadavg();
if (!is_array($load_arr))
return false;
return max($load_arr);
}

View file

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 3.4.1 (Lily of the valley) -- Friendica 3.4.2 (Lily of the valley)
-- DB_UPDATE_VERSION 1188 -- DB_UPDATE_VERSION 1190
-- ------------------------------------------ -- ------------------------------------------
@ -317,6 +317,7 @@ CREATE TABLE IF NOT EXISTS `gcontact` (
`gender` varchar(32) NOT NULL DEFAULT '', `gender` varchar(32) NOT NULL DEFAULT '',
`community` tinyint(1) NOT NULL DEFAULT 0, `community` tinyint(1) NOT NULL DEFAULT 0,
`network` varchar(255) NOT NULL DEFAULT '', `network` varchar(255) NOT NULL DEFAULT '',
`addr` varchar(255) NOT NULL DEFAULT '',
`generation` tinyint(3) NOT NULL DEFAULT 0, `generation` tinyint(3) NOT NULL DEFAULT 0,
`server_url` varchar(255) NOT NULL DEFAULT '', `server_url` varchar(255) NOT NULL DEFAULT '',
INDEX `nurl` (`nurl`), INDEX `nurl` (`nurl`),
@ -1020,3 +1021,16 @@ CREATE TABLE IF NOT EXISTS `userd` (
INDEX `username` (`username`) INDEX `username` (`username`)
) DEFAULT CHARSET=utf8; ) DEFAULT CHARSET=utf8;
--
-- TABLE workerqueue
--
CREATE TABLE IF NOT EXISTS `workerqueue` (
`id` int(11) NOT NULL auto_increment PRIMARY KEY,
`parameter` text NOT NULL,
`priority` tinyint(3) unsigned NOT NULL DEFAULT 0,
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`pid` int(11) NOT NULL DEFAULT 0,
`executed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
INDEX `created` (`created`)
) DEFAULT CHARSET=utf8;

View file

@ -19,6 +19,7 @@ General
* v: Videos * v: Videos
* e: Events and Calendar * e: Events and Calendar
* t: Personal Notes * t: Personal Notes
* k: View Contacts
/contacts (contact list) /contacts (contact list)
--------- ---------
@ -32,6 +33,10 @@ General
/contacts (single contact view) /contacts (single contact view)
------------------------------- -------------------------------
* m: Status messages
* o: Profile
* t: Contacts
* d: Common friends
* b: Toggle Blocked status * b: Toggle Blocked status
* i: Toggle Ignored status * i: Toggle Ignored status
* v: Toggle Archive status * v: Toggle Archive status

View file

@ -63,6 +63,7 @@ At first you have to activate the addon.
Now add your Jabber/XMPP name, the domain/server (without "http"; just "jappix.com"). Now add your Jabber/XMPP name, the domain/server (without "http"; just "jappix.com").
For „Jabber BOSH Host“ you could use "https://bind.jappix.com/". For „Jabber BOSH Host“ you could use "https://bind.jappix.com/".
Note that you need another BOSH server if you do not use jappix.com for your XMPP account.
You can find further information in the „Configuration Help“-section below this fields. You can find further information in the „Configuration Help“-section below this fields.
At last you have enter your password (there are some more optional options, you can choose). At last you have enter your password (there are some more optional options, you can choose).
Finish these steps with "send" to save the entries. Finish these steps with "send" to save the entries.

View file

@ -54,6 +54,8 @@ Have a look at our [issue tracker](https://github.com/friendica/friendica) on gi
* Try to reproduce a bug that needs more inquries and write down what you find out. * Try to reproduce a bug that needs more inquries and write down what you find out.
* If a bug looks fixed, ask the bug reporters for feedback to find out if the bug can be closed. * If a bug looks fixed, ask the bug reporters for feedback to find out if the bug can be closed.
* Fix a bug if you can. Please make the pull request against the *develop* branch of the repository. * Fix a bug if you can. Please make the pull request against the *develop* branch of the repository.
* There is a *Junior Job* label for issues we think might be a good point to start with.
But you don't have to limit yourself to those issues.
###Web interface ###Web interface

View file

@ -87,8 +87,8 @@ However their conversations with your friends will still be visible in your stre
If you remove a contact completely, they can send you another friend request. If you remove a contact completely, they can send you another friend request.
Blocked contacts cannot do this. They cannot communicate with you directly, only through friends. Blocked contacts cannot do this. They cannot communicate with you directly, only through friends.
**Ignored contacts** are included in delivery - they will receive your posts. **Ignored contacts** are included in delivery - they will receive your posts and private messages.
However we do not import their posts to you. However we do not import their posts or private messages to you.
Like blocking, you will still see this person's comments to posts made by your friends. Like blocking, you will still see this person's comments to posts made by your friends.
A plugin called "blockem" can be installed to collapse/hide all posts from a particular person in your stream if you desire complete blocking of an individual, including his/her conversations with your other friends. A plugin called "blockem" can be installed to collapse/hide all posts from a particular person in your stream if you desire complete blocking of an individual, including his/her conversations with your other friends.

View file

@ -10,7 +10,7 @@ Friendica Documentation and Resources
* [BBCode tag reference](help/BBCode) * [BBCode tag reference](help/BBCode)
* [Comment, sort and delete posts](help/Text_comment) * [Comment, sort and delete posts](help/Text_comment)
* [Profiles](help/Profiles) * [Profiles](help/Profiles)
* [Accesskey reference](help/Accesskeys * [Accesskey reference](help/Accesskeys)
* [Events](help/events) * [Events](help/events)
* You and other users * You and other users
* [Connectors](help/Connectors) * [Connectors](help/Connectors)
@ -30,9 +30,11 @@ Friendica Documentation and Resources
* [Install](help/Install) * [Install](help/Install)
* [Settings](help/Settings) * [Settings](help/Settings)
* [Installing Connectors (Twitter/GNU Social)](help/Installing-Connectors) * [Installing Connectors (Twitter/GNU Social)](help/Installing-Connectors)
* [Install an ejabberd server (XMPP chat) with synchronized credentials](help/install-ejabberd)
* [Message Flow](help/Message-Flow) * [Message Flow](help/Message-Flow)
* [Using SSL with Friendica](help/SSL) * [Using SSL with Friendica](help/SSL)
* [Twitter/GNU Social API Functions](help/api) * [Twitter/GNU Social API Functions](help/api)
* [Config values that can only be set in .htconfig.php](help/htconfig)
**Developer Manual** **Developer Manual**
@ -44,6 +46,7 @@ Friendica Documentation and Resources
* [Plugin Development](help/Plugins) * [Plugin Development](help/Plugins)
* [Theme Development](help/themes) * [Theme Development](help/themes)
* [Smarty 3 Templates](help/smarty3-templates) * [Smarty 3 Templates](help/smarty3-templates)
* [Code - Reference(Doxygen generated - sets cookies)](doc/html/)
**External Resources** **External Resources**
@ -53,4 +56,5 @@ Friendica Documentation and Resources
**About** **About**
* [Site/Version Info](friendica) * [Site/Version Info](friendica)
* [Friendica Credits](credits)

View file

@ -10,9 +10,11 @@ Not every PHP/MySQL hosting provider will be able to support Friendica.
Many will. Many will.
But **please** review the requirements and confirm these with your hosting provider prior to installation. But **please** review the requirements and confirm these with your hosting provider prior to installation.
Also if you encounter installation issues, please let us know via the [helper]() or the [developer]() forum or [file an issue](https://github.com/friendica/friendica/issues). Also if you encounter installation issues, please let us know via the [helper](http://helpers.pyxis.uberspace.de/profile/helpers) or the [developer](https://friendika.openmindspace.org/profile/friendicadevelopers) forum or [file an issue](https://github.com/friendica/friendica/issues).
Please be as clear as you can about your operating environment and provide as much detail as possible about any error messages you may see, so that we can prevent it from happening in the future. Please be as clear as you can about your operating environment and provide as much detail as possible about any error messages you may see, so that we can prevent it from happening in the future.
Due to the large variety of operating systems and PHP platforms in existence we may have only limited ability to debug your PHP installation or acquire any missing modules - but we will do our best to solve any general code issues. Due to the large variety of operating systems and PHP platforms in existence we may have only limited ability to debug your PHP installation or acquire any missing modules - but we will do our best to solve any general code issues.
If you do not have a Friendica account yet, you can register a temporary one at [tryfriendica.de](https://tryfriendica.de) and join the forums mentioned above from there.
The account will expire after 7 days, but you can ask the server admin to keep your account longer, should the problem not be resolved after that.
Before you begin: Choose a domain name or subdomain name for your server. Before you begin: Choose a domain name or subdomain name for your server.
Put some thought into this. Changing it after installation is currently not supported. Put some thought into this. Changing it after installation is currently not supported.
@ -29,7 +31,7 @@ Requirements
* curl, gd, mysql, hash and openssl extensions * curl, gd, mysql, hash and openssl extensions
* some form of email server or email gateway such that PHP mail() works * some form of email server or email gateway such that PHP mail() works
* mcrypt (optional; used for server-to-server message encryption) * mcrypt (optional; used for server-to-server message encryption)
* Mysql 5.x * Mysql 5.x or an equivalant alternative for MySQL (MariaDB etc.)
* the ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks (Windows) (Note: other options are presented in Section 7 of this document.) * the ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks (Windows) (Note: other options are presented in Section 7 of this document.)
* Installation into a top-level domain or sub-domain (without a directory/path component in the URL) is preferred. Directory paths will not be as convenient to use and have not been thoroughly tested. * Installation into a top-level domain or sub-domain (without a directory/path component in the URL) is preferred. Directory paths will not be as convenient to use and have not been thoroughly tested.
* If your hosting provider doesn't allow Unix shell access, you might have trouble getting everything to work. * If your hosting provider doesn't allow Unix shell access, you might have trouble getting everything to work.
@ -114,6 +116,8 @@ Change it to read
and save your changes. and save your changes.
Once you have installed Friendica and created an admin account as part of the process, you can access the admin panel of your installation and do most of the server wide configuration from there
Updating your installation with git Updating your installation with git
--- ---
@ -122,6 +126,10 @@ You can get the latest changes at any time with
cd mywebsite cd mywebsite
git pull git pull
The default branch to use it the ``master`` branch, which is the stable version of Friendica.
If you want to use and test bleeding edge code please checkout the ``develop`` branch.
The new features and fixes will be merged from ``develop`` into ``master`` when they are stable approx four times a year.
The addon tree has to be updated separately like so: The addon tree has to be updated separately like so:
cd mywebsite/addon cd mywebsite/addon

View file

@ -271,6 +271,16 @@ $b is an array, params to mail()
is called after the navigational menu is build in include/nav.php. is called after the navigational menu is build in include/nav.php.
$b is an array containing $nav from nav.php. $b is an array containing $nav from nav.php.
###'template_vars'
is called before vars are passed to the template engine to render the page.
The registered function can add,change or remove variables passed to template.
$b is an array with:
'template' => filename of template
'vars' => array of vars passed to template
Complete list of hook callbacks Complete list of hook callbacks
--- ---

View file

@ -3,166 +3,104 @@ Using SSL with Friendica
* [Home](help) * [Home](help)
If you are running your own Friendica site, you may want to use SSL (https) to encrypt communication between yourself and your server (communication between servers is encrypted anyway). Disclaimer
---
**This document has been updated in November 2015.
SSL encryption is relevant for security.
This means that recommended settings change fast.
Keep your setup up to date and do not rely on this document being updated as fast as technologies change!**
To do that on a domain of your own, you have to obtain a certificate from a trusted organization (so-called self-signed certificates that are popular among geeks dont work very well with Friendica, because they can cause disturbances in other people's browsers). Intro
---
If you are running your own Friendica site, you may want to use SSL (https) to encrypt communication between servers and between yourself and your server.
If you are reading this document before actually installing Friendica, you might want to consider a very simple option: Go for a shared hosting account without your own domain name. That way, your address will be something like yourname.yourprovidersname.com, which isn't very fancy compared to yourname.com. But it will still be your very own site, and you will usually be able to hitch a lift on your provider's SSL certificate. That means that you won't need to configure SSL at all - it will simply work out of the box when people type https instead of http. There are basically two sorts of SSL certificates: Self-signed certificates and certificates signed by a certificate authority (CA).
Technically, both provide the same valid encryption.
There is a problem with self-signed certificates though:
They are neither installed in browsers nor on other servers.
That is why they provoke warnings about "mistrusted certificates".
This is confusing and disturbing.
If that isn't your idea of doing things, read on... For this reason, we recommend to get a certificate signed by a CA.
Normally, you have to pay for them - and they are valid for a limited period of time (e.g. a year or two).
**Shared hosts** There are ways to get a trusted certificate for free.
If you are using a shared host on a domain of your own, your provider may well offer to obtain and install the certificate for you. You will then only need to apply and pay for it and everything will be set up. If that is the case for you, the rest of this document need not concern you at all. Just make sure the certificate is for the address that Friendica uses: e.g. myownfriendica.com or friendica.myserver.com. Chose your domain name
---
The above ought to be the most common scenario for Friendica sites, making the rest of this article superfluous for most people. Your SSL certificate will be valid for a domain or even only for a subdomain.
Make your final decision about your domain resp. subdomain *before* ordering the certificate.
Once you have it, changing the domain name means getting a new certificate.
**Obtaining a certificate yourself** Shared hosts
---
Alternatively, a few shared hosting providers may ask you to obtain and upload the certificate yourself. If your Friendica instance is running on a shared hosting platform, you should first check with your hosting provider.
They have instructions for you on how to do it there.
You can always order a paid certificate with your provider.
They will either install it for you or provide an easy way to upload the certificate and the key via a web interface.
The next section describes the process of acquiring a certificate from StartSSL. The good thing about StartSSL is that you can get an entry-level, but perfectly sufficient certificate for free. Thats not the case with most other certificate issuers - so we will be concentrating on StartSSL in this document If you want to use a certificate from a different source, you will have to follow the instructions given by that organization. We can't cover every possibility here.
Installing your certificate - once you have obtained it - depends on your providers way of doing things. But for shared hosts, there will usually be an easy web tool for this. It might be worth asking if your provider would install a certificate you provide yourself, to save money.
If so, read on.
Note: Your certificate is usually restricted to one subdomain. When you apply for the certificate, make sure its for the domain and subdomain Friendica uses: e.g. myownfriendica.com or friendica.myserver.com. Getting a free StartSSL certificate
---
StartSSL is a certificate authority that issues certificates for free.
They are valid for a year and are sufficient for our purposes.
**Getting a free StartSSL certificate** ### Step 1: Create a client certificate
StartSSLs website attempts to guide you through the process of obtaining a free certificate, but some people end up frustrated. We really recommend working your way through the steps on the site very slowly and carefully. Don't take things for granted - read every word before proceeding and don't close the browser window until everything is working. That said, there are three main stumbling blocks that can confuse users: When you initially sign up with StartSSL, you receive a certificate that is installed in your browser.
You need it for the login on startssl.com, also when coming back to the site later.
It has nothing to do with the SSL certificate for your server.
When you initially sign up with StartSSL, the first certificate you receive is simply installed in your browser (though you should also store it somewhere safe, so that you can reinstall it in any other browser at a later date, for instance when you need to renew something). This authentication certificate is only used for logging on to the StartSSL website it has nothing to do with the certificate you will need for your server. As a first-timer with StartSSL, start here: https://www.startssl.com/?app=12 and choose the Express Lane option to get that browser authentication certificate. Then seamlessly continue to the process of acquiring the desired certificate for your server (the one you actually came for). You can change the websites language if that makes things easier for you. ### Step 2: Validate your email address and your domain
When you are first prompted for a domain to certify, you need to enter your top-level domain not the subdomain Friendica uses. In the next step, you will be able to specify that subdomain. So if you have friendica.yourname.com on your server, you first enter yourname.com and specify the subdomain friendica later. To continue you have to prove that you own the email address you specified and the domain that you want a certificate for.
Specify your email address, request a validation link via email from the "validations wizard".
Same procedure for the domain validation.
Dont quit too fast when you have received your personal web server certificate at the end of the procedure. Depending on your server software, you will also require one or two generic files for use with this free StartSSL certificate. These are sub.class1.server.ca.pem and ca.pem. If you have already overlooked this step, you can download those files here: http://www.startssl.com/?app=21 But once again, the very best way of doing things is not to quit the StartSSL site until you are completely done and your https certificate is up and working. ### Step 3: Request the certificate
**Virtual private and dedicated servers (using StartSSL free)** Go to the "certificates wizard".
Choose the target web server.
When you are first prompted for a domain to certify, you need to enter your main domain, e.g. example.com.
In the next step, you will be able to specify a subdomain for Friendica, if needed.
Example: If you have friendica.example.com, you first enter example.com, then specify the subdomain friendica later.
The rest of this document is slightly more complicated, but its only for people running Friendica on a virtual private or dedicated server. Everyone else can stop reading at this point. If you know how to generate an openssl key and a certificate signing request (csr) yourself, do so.
Paste the csr into your browser to get it signed by StartSSL.
Follow the instructions here ( http://www.startssl.com/?app=20 ) to configure the web server you are using (e.g. Apache) for your certificate. If you do not know how to generate a key and a csr, accept StartSSL's offer to generate it for you.
This means: StartSSL has the key to your encryption but it is better than no certificate at all.
Download your certificate from the website.
(Or in the second case: Download your certificate and your key.)
To illustrate the necessary changes, we will now assume you are running Apache. In essence, you can simply create a second httpd.conf entry for Friendica. To install your certificate on a server, you need one or two extra files: sub.class1.server.ca.pem and ca.pem, delivered by startssl.com
Go to the "Tool box" section and download "Class 1 Intermediate Server CA" and "StartCom Root CA (PEM encoded)".
To do this, you copy the existing one and change the end of the first line to read :443> instead of :80>, then add the following lines to that entry, as also shown in StartSSLs instructions: If you want to send your certificate to your hosting provider, they need the certificate, the key and probably at least the intermediate server CA.
To be sure, send those three and the ca.pem file.
**You should send them to your provider via an encrypted channel!**
SSLEngine on If you run your own server, upload the files and check out the Mozilla wiki link below.
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM
SSLCertificateFile /usr/local/apache/conf/ssl.crt Let's encrypt
SSLCertificateKeyFile /usr/local/apache/conf/ssl.key ---
SSLCertificateChainFile /usr/local/apache/conf/sub.class1.server.ca.pem
SSLCACertificateFile /usr/local/apache/conf/ca.pem
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
CustomLog /usr/local/apache/logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
(Note that the directory /usr/local/apache/conf/ may not exist on your machine. For Debian, for instance, the directory might be /etc/apache2/ - in which you can create an ssl subdirectory if it doesnt already exist. Then you have /etc/apache2/ssl/… instead of /usr/local/apache/conf/…) If you run your own server and you control your name server, the "Let's encrypt" initiative might become an interesting alternative.
Their offer is not ready, yet.
Check out [their website](https://letsencrypt.org/) for status updates.
You thus end up with two entries for your Friendica site - one for simple http and one for https. Web server settings
---
Note to those who want to force SSL: Don't redirect to SSL in your Apache settings. Friendica's own admin panel has a special setting for SSL policy. Please use this facility instead. Visit the [Mozilla's wiki](https://wiki.mozilla.org/Security/Server_Side_TLS) for instructions on how to configure a secure webserver.
They provide recommendations for [different web servers](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations).
**Mixing certificates on Apache StartSSL and others (self-signed)** Test your SSL settings
---
Many people using a virtual private or dedicated server will be running more than Friendica on it. They will probably want to use SSL for other sites they run on the server, too. To achieve this, they may wish to employ more than one certificate with a single IP for instance, a trusted one for Friendica and a self-signed certificate for personal stuff (possibly a wildcard certificate covering arbitrary subdomains). When you are done, visit the test site [SSL Labs](https://www.ssllabs.com/ssltest/) to have them check if you succeeded.
For this to work, Apache offers a NameVirtualHost directive. You can see how to use it in httpd.conf in the following pattern. Note that wildcards (*) in httpd.conf break the NameVirtualHost method you cant use them in this new configuration. In other words, no more *80> or *443>. And you really must specify the IP, too, even if you only have one. Also note that you will soon be needing two additional NameVirtualHost lines at the top of the file to cater for IPv6.
NameVirtualHost 12.123.456.1:443
NameVirtualHost 12.123.456.1:80
<VirtualHost www.anywhere.net:80>
DocumentRoot /var/www/anywhere
Servername www.anywhere.net
</VirtualHost>
<VirtualHost www.anywhere.net:443>
DocumentRoot /var/www/anywhere
Servername www.anywhere.net
SSLEngine On
<pointers to a an eligible cert>
<more ssl stuff >
<other stuff>
</VirtualHost>
<VirtualHost www.somewhere-else.net:80>
DocumentRoot /var/www/somewhere-else
Servername www.somewhere-else.net
</VirtualHost>
<VirtualHost www.somewhere-else:443>
DocumentRoot /var/www/somewhere-else
Servername www.somewhere-else.net
SSLEngine On
<pointers to another eligible cert>
<more ssl stuff >
<other stuff>
</VirtualHost>
Of course, you may optionally be using other places like the sites-available directory to configure Apache, in which case only some of this information need be in httpd.conf or ports.conf - specifically, the NameVirtualHost lines must be there. But if you're savvy about alternatives like that, you will probably be able to figure out the details yourself.
Just restart Apache when you're done, whichever way you decide to do it.
**StartSSL on Nginx**
First, update to the latest Friendica code. Then follow the above instructions to get your free certificate. But instead of following the Apache installation instructions, do this:
Upload your certificate. It doesn't matter where to, as long as Nginx can find it. Some people use /home/randomlettersandnumbers to keep it in out of paranoia, but you can put it anywhere, so we'll call it /foo/bar.
You can remove the password if you like. This is probably bad practice, but if you don't, you'll have to enter the password every time you restart nginx. To remove it:
openssl rsa -in ssl.key-pass -out ssl.key
Now, grab the helper certificate:
wget http://www.startssl.com/certs/sub.class1.server.ca.pem
Now you need to merge the files:
cat ssl.crt sub.class1.server.ca.pem > ssl.crt
In some configurations there is a bug, and this doesn't quite work properly. You may now need to edit ssl.crt, so:
nano /foo/bar/ssl.crt
You'll see two certificates in the same file. Halfway down, you may see:
-----END CERTIFICATE----------BEGIN CERTIFICATE-----
This is bad. You need to see:
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
You can enter the carriage return manually if the bug is present on your system. Note there is a single carriage return for -----BEGIN CERTIFICATE----- to start on a new line. There is no empty line.
Now you need to tell Nginx about the certs.
In /etc/nginx/sites-available/foo.com.conf you need something like:
server {
listen 80;
listen 443 ssl;
listen [::]:80;
listen [::]:443 ipv6only=on ssl;
ssl_certificate /foo/bar/ssl.crt;
ssl_certificate_key /foo/bar/ssl.key;
...
Now, restart nginx:
/etc/init.d/nginx restart
And that's it.
For multiple domains, we have it easier than Apache users: Just repeat the above for each certificate, and keep it in it's own {server...} section.

View file

@ -198,7 +198,7 @@ Config:
This configures the URL to update the global directory, and is supplied in the default configuration. This configures the URL to update the global directory, and is supplied in the default configuration.
The undocumented part is that if this is not set, the global directory is completely unavailable to the application. The undocumented part is that if this is not set, the global directory is completely unavailable to the application.
This allows a private community to be completely isolated from the global mistpark network. This allows a private community to be completely isolated from the global network.
$a->config['system']['directory'] = 'http://dir.friendi.ca'; $a->config['system']['directory'] = 'http://dir.friendi.ca';

View file

@ -8,10 +8,12 @@ Getting started
[Vagrant](https://www.vagrantup.com/) is a virtualization solution for developers. [Vagrant](https://www.vagrantup.com/) is a virtualization solution for developers.
No need to setup up a webserver, database etc. before actually starting. No need to setup up a webserver, database etc. before actually starting.
Vagrant creates a virtual machine (an Ubuntu 12.04) for you that you can just run inside VirtualBox and start to work directly on Friendica. Vagrant creates a virtual machine (an Ubuntu 14.04) for you that you can just run inside VirtualBox and start to work directly on Friendica.
What you need to do: What you need to do:
1. Install VirtualBox and vagrant. 1. Install VirtualBox and vagrant.
Please use an up-to-date vagrant version from https://www.vagrantup.com/downloads.html.
2. Git clone your Friendica repository. 2. Git clone your Friendica repository.
Inside, you'll find a "Vagrantfile" and some scripts in the utils folder. Inside, you'll find a "Vagrantfile" and some scripts in the utils folder.
3. Run "vagrant up" from inside the friendica clone. 3. Run "vagrant up" from inside the friendica clone.
@ -20,8 +22,10 @@ Be patient: When it runs for the first time, it downloads an Ubuntu Server image
5. Open 192.168.22.10 in a browser. 5. Open 192.168.22.10 in a browser.
The mysql database is called "friendica", the mysql user and password both are "root". The mysql database is called "friendica", the mysql user and password both are "root".
6. Work on Friendica's code in your git clone on your machine (not in the VM). 6. Work on Friendica's code in your git clone on your machine (not in the VM).
Your local working directory is set up as a shared directory with the VM (/vagrant).
7. Check the changes in your browser in the VM. 7. Check the changes in your browser in the VM.
Debug via the "vagrant ssh" login. Debug via the "vagrant ssh" login.
Find the Friendica log file /vagrant/logfile.out.
8. Commit and push your changes directly back to Github. 8. Commit and push your changes directly back to Github.
If you want to stop vagrant after finishing your work, run the following command If you want to stop vagrant after finishing your work, run the following command
@ -40,3 +44,10 @@ You will then have the following accounts to login:
* friendica2 and friendica3 are conntected. friendica4 and friendica5 are connected. * friendica2 and friendica3 are conntected. friendica4 and friendica5 are connected.
For further documentation of vagrant, please see [the vagrant*docs*](https://docs.vagrantup.com/v2/). For further documentation of vagrant, please see [the vagrant*docs*](https://docs.vagrantup.com/v2/).
**Important notice:**
If you already had an Ubuntu 12.04 Vagrant VM, please run
$> vagrant destroy
before starting the new 14.04 machine.

View file

@ -70,7 +70,7 @@ Trage nun Deinen Jabber/XMPP Namen ein, ebenfalls die entsprechende Domain bzw.
Um das JavaScript Applet zum Chatten im Browser verwenden zu können, benötigst du einen BOSH Proxy. Um das JavaScript Applet zum Chatten im Browser verwenden zu können, benötigst du einen BOSH Proxy.
Entweder betreibst du deinen eigenen (s. Dokumentation deines XMPP Servers) oder du verwendest einen öffentlichen BOSH Proxy. Entweder betreibst du deinen eigenen (s. Dokumentation deines XMPP Servers) oder du verwendest einen öffentlichen BOSH Proxy.
Beachte aber, dass der Betreiber dieses Proxies den kompletten Datenverkehr über den Proxy mitlesen kann. Beachte aber, dass der Betreiber dieses Proxies den kompletten Datenverkehr über den Proxy mitlesen kann.
Siehe dazu auch die „Configuration Help“ weiter unten. Siehe dazu auch die „Configuration Help“ unter den Eingabefeldern.
Gebe danach noch Dein Passwort an, und damit ist eigentlich schon fast alles geschafft. Gebe danach noch Dein Passwort an, und damit ist eigentlich schon fast alles geschafft.
Die weiteren Einstellmöglichkeiten bleiben Dir überlassen, sind also optional. Die weiteren Einstellmöglichkeiten bleiben Dir überlassen, sind also optional.
Jetzt noch auf „senden“ klicken und fertig. Jetzt noch auf „senden“ klicken und fertig.

View file

@ -13,6 +13,11 @@ Die Anleitung unter [http://help.github.com/fork-a-repo/](http://help.github.com
Gehe dann nach getaner Arbeit zu Deiner Github-Seite und erstelle eine "Pull request", um Deine Änderungen in das Hauptprojekt einzugliedern (merge). Gehe dann nach getaner Arbeit zu Deiner Github-Seite und erstelle eine "Pull request", um Deine Änderungen in das Hauptprojekt einzugliedern (merge).
Solltest du keine Idee haben, an welcher Stelle du einsteigen könntest.
Wir haben einige Aufgaben auf github mit dem Schlagwort *Junior Job* versehen.
Bei diesen Aufgaben gehen wir davon aus, dass sie geeignete Einstiegsstellen sind.
Du musst dich aber natürlich nicht mit diesen Aufgaben beschäftigen um den Friendica Code zu verbeesern.
**Wichtig** **Wichtig**
Bitte hole Dir alle Änderungen aus dem Projektverzeichnis und führe sie mit Deiner Arbeit zusammen, **bevor** Du Deine "pull request" erstellst. Wir behalten es uns vor, Patches abzulehnen, die eine große Anzahl an Fehlern hervorrufen. Bitte hole Dir alle Änderungen aus dem Projektverzeichnis und führe sie mit Deiner Arbeit zusammen, **bevor** Du Deine "pull request" erstellst. Wir behalten es uns vor, Patches abzulehnen, die eine große Anzahl an Fehlern hervorrufen.

View file

@ -100,9 +100,9 @@ Wenn Du einen Kontakt komplett löschst, können sie Dir eine neue Freundschafts
Blockierte Kontakte können das nicht machen. Blockierte Kontakte können das nicht machen.
Sie können nicht mit Dir direkt kommunizieren, nur über Freunde. Sie können nicht mit Dir direkt kommunizieren, nur über Freunde.
Ignorierte Kontakte können weiterhin Beiträge von Dir erhalten. Ignorierte Kontakte können weiterhin Beiträge und private Nachrichten von Dir erhalten.
Deren Beiträge werden allerdings nicht importiert. W Deren Beiträge und private Nachrichten werden allerdings nicht importiert.
ie bei blockierten Beiträgen siehst Du auch hier weiterhin die Kommentare dieser Person zu anderen Beiträgen Deiner Freunde. Wie bei blockierten Beiträgen siehst Du auch hier weiterhin die Kommentare dieser Person zu anderen Beiträgen Deiner Freunde.
[Ein Plugin namens "blockem" kann installiert werden, um alle Beiträge einer bestimmten Person in Deinem Stream zu verstecken bzw. zu verkürzen. [Ein Plugin namens "blockem" kann installiert werden, um alle Beiträge einer bestimmten Person in Deinem Stream zu verstecken bzw. zu verkürzen.
Dabei werden auch Kommentare dieser Person in Beiträgen Deiner Freunde blockiert.] Dabei werden auch Kommentare dieser Person in Beiträgen Deiner Freunde blockiert.]

View file

@ -32,11 +32,13 @@ Friendica - Dokumentation und Ressourcen
* [Konfigurationen](help/Settings) * [Konfigurationen](help/Settings)
* [Plugins](help/Plugins) * [Plugins](help/Plugins)
* [Konnektoren (Connectors) installieren (Twitter/GNU Social)](help/Installing-Connectors) * [Konnektoren (Connectors) installieren (Twitter/GNU Social)](help/Installing-Connectors)
* [Installation eines ejabberd Servers (XMPP-Chat) mit synchronisierten Anmeldedaten](help/install-ejabberd) (EN)
* [Nachrichtenfluss](help/Message-Flow) * [Nachrichtenfluss](help/Message-Flow)
* [Betreibe deine Seite mit einem SSL-Zertifikat](help/SSL) * [Betreibe deine Seite mit einem SSL-Zertifikat](help/SSL)
* [Entwickler](help/Developers) * [Entwickler](help/Developers)
* [Twitter/GNU Social API Functions](help/api) (EN) * [Twitter/GNU Social API Functions](help/api) (EN)
* [Translation of Friendica](help/translations) (EN) * [Translation of Friendica](help/translations) (EN)
* [Konfigurationswerte, die nur in der .htconfig.php gesetzt werden können](help/htconfig) (EN)
**Entwickler Dokumentation** **Entwickler Dokumentation**
@ -48,6 +50,7 @@ Friendica - Dokumentation und Ressourcen
* [Plugin Development](help/Plugins) * [Plugin Development](help/Plugins)
* [Theme Development](help/themes) * [Theme Development](help/themes)
* [Smarty 3 Templates](help/smarty3-templates) * [Smarty 3 Templates](help/smarty3-templates)
* [Code-Referenz (mit doxygen generiert - setzt Cookies)](doc/html/)
**Externe Ressourcen** **Externe Ressourcen**
@ -58,4 +61,5 @@ Friendica - Dokumentation und Ressourcen
**Über diese Seite** **Über diese Seite**
* [Seite/Friendica-Version](friendica) * [Seite/Friendica-Version](friendica)
* [Mitwirkenden bei Friendica](credits)

View file

@ -3,216 +3,124 @@ Friendica mit SSL nutzen
* [Zur Startseite der Hilfe](help) * [Zur Startseite der Hilfe](help)
Wenn du deine eigene Friendica-Seite betreibst, willst du vielleicht SSL (https) nutzen, um die Kommunikation zwischen dir und deinem Server zu verschlüsseln (die Kommunikation zwischen den Servern ist bereits verschlüsselt). Disclaimer
---
**Dieses Dokument wurde im November 2015 aktualisiert.
SSL-Verschlüsselung ist sicherheitskritisch.
Das bedeutet, dass sich die empfohlenen Einstellungen schnell verändern.
Halte deine Installation auf dem aktuellen Stand und verlasse dich nicht darauf, dass dieses Dokument genau so schnell aktualisiert wird, wie sich Technologien verändern!**
Wenn du das auf deiner eigenen Domain machen willst, musst du ein Zertifikat von einer anerkannten Organisation beschaffen (sogenannte selbst-signierte Zertifikate, die unter Computerfreaks beliebt sind, arbeiten nicht sehr gut mit Friendica, weil sie Warnungen im Browser hervorrufen können). Einleitung
---
Wenn du dieses Dokument liest, bevor du Friendica installierst, kannst du eine sehr einfache Option in Betracht ziehen: suche dir ein geteiltes Hosting-Angebot (shared hosting) ohne eigene Domain. Wenn du deine eigene Friendica-Seite betreibst, willst du vielleicht SSL (https) nutzen, um die Kommunikation zwischen den Servern und zwischen dir und deinem Server zu verschlüsseln.
Dadurch wirst du eine Adresse in der Form deinName.deinAnbietername.de erhalten, was nicht so schön wie deinName.de ist.
Aber es wird trotzdem deine ganz persönliche Seite sein und du wirst unter Umständen die Möglichkeit haben, das SSL-Zertifikat deines Anbieters mitzubenutzen.
Das bedeutet, dass du SSL überhaupt nicht konfigurieren musst - es wird einfach sofort funktionieren, wenn die Besucher deiner Seite https statt http eingeben.
Wenn dir diese Lösung nicht gefällt, lies weiter... Dafür gibt es grundsätzlich zwei Arten von SSL-Zertifikaten: Selbst-signierte Zertifikate und Zertifikate, die von einer Zertifizierungsstelle (CA) unterschrieben sind.
Technisch gesehen sorgen beide für valide Verschlüsselung.
Mit selbst-signierten Zertifikaten gibt es jedoch ein Problem:
Sie sind weder in Browsern noch auf anderen Servern installiert.
Deshalb führen sie zu Warnungen über "nicht vertrauenswürdige Zertifikate".
Das ist verwirrend und stört sehr.
**Geteilte Hosting-Angebote/Shared hosts** Aus diesem Grund empfehlen wir, dass du dir ein von einer CA unterschriebenes Zertifikat besorgst.
Normalerweise kosten sie Geld - und sind nur für eine begrenzte Zeit gültig (z.B. ein Jahr oder zwei).
Wenn du ein geteiltes Hosting-Angebot mit einer eigenen Domain nutzt, dann wird dir dein Anbieter ggf. anbieten, dir das Zertifikat zu besorgen und zu installieren. Es gibt aber Möglichkeiten, ein vertrauenswürdiges Zertifikat umsonst zu bekommen.
Du musst es nur beantragen und bezahlen und alles wird eingerichtet.
Wenn das die Lösung für dich ist, musst du das weitere Dokument nicht lesen.
Gehe nur sicher, dass das Zertifikat auch für die Domain gilt, die du für Friendica nutzt: z.B. meinfriendica.de oder friendica.meinserver.de.
Das Vorangehende wird die häufigste Art sein, eine Friendica-Seite zu betreiben, so dass der Rest des Artikels für die meisten Leute nicht von Bedeutung ist. Wähle deinen Domainnamen
---
**Beschaffe dir das Zertifikat selbst** Dein SSL-Zertifikat wird für eine bestimmte Domain gültig sein oder sogar nur für eine Subdomain.
Entscheide dich endgültig für einen Domainnamen, *bevor* du ein Zertifikat bestellst.
Wenn du das Zertifikat hast, brauchst du ein neues, wenn du den Domainnamen ändern möchtest.
Alternativ kannst du dir auch selbst ein Zertifikat besorgen und hochladen, falls dein Anbieter das unterstützt. Gehosteter Webspace
---
Der nächste Abschnitt beschreibt den Ablauf, um ein Zertifikat von StartSSL zu erhalten. Wenn deine Friendica-Instanz auf einem gehosteten Webspace läuft, solltest du dich bei deinem Hosting-Provider informieren.
Das Gute an StartSSL ist, dass du kostenlos ein einfaches, aber perfekt ausreichendes Zertifikat erhältst. Dort bekommst du Instruktionen, wie es dort läuft.
Das ist bei vielen anderen Anbietern nicht so, weshalb wir uns in diesem Dokument auf StartSSL konzentrieren werden. Du kannst bei deinem Provider immer ein kostenpflichtiges Zertifikat bestellen.
Wenn du ein Zertifikat eines anderen Anbieters nutzen willst, musst du die Vorgaben dieser Organisation befolgen. Sie installieren es für dich oder haben in der Weboberfläche eine einfache Upload-Möglichkeit für Zertifikat und Schlüssel.
Wir können hier nicht jede Möglichkeit abdecken.
Die Installation deines erhaltenen Zertifikats hängt von den Vorgaben deines Anbieters ab. Um Geld zu sparen, kann es sich lohnen, dort auch nachzufragen, ob sie ein anderes Zertifikat, das du selbst beschaffst, für dich installieren würden.
Aber generell nutzen solche Anbieter ein einfaches Web-Tool, um die Einrichtung zu unterstützen. Wenn ja, dann lies weiter.
Beachte: dein Zertifikat gilt gewöhnlich nur für eine Subdomain. Ein kostenloses StartSSL-Zertifikat besorgen
Wenn du dein Zertifikat beantragst, sorge dafür, dass es für die Domain und die Subdomain gilt, die du für Friendica nutzt: z.B. meinfriendica.de oder friendica.meinserver.de. ---
**Erhalte ein kostenloses StartSSL-Zertifikat** StartSSL ist eine Zertifizierungsstelle, die kostenlose Zertifikate ausstellt.
Sie sind für ein Jahr gültig und genügen für unsere Zwecke.
Die Webseite von StartSSL führt dich durch den Erstellungsprozess, aber manche Leute haben hier trotzdem Probleme. ### Schritt 1: Client-Zertifikat erstellen
Wir empfehlen dir ausdrücklich, die Installationsanleitung Schritt für Schritt langsam und sorgfältig zu befolgen.
Lese dir jedes Wort durch und schließe deinen Browser erst, wenn alles läuft.
Es heißt, dass es drei Schritte gibt, die den Nutzer verwirren können:
Wenn du dich erstmals bei StartSSL anmeldest, erhältst du ein erstes Zertifikat, dass sich einfach in deinem Browser installiert. Wenn du dich erstmalig bei StartSSL anmeldest, erhältst du ein Zertifikat, das in deinem Browser installiert wird.
Dieses Zertifikat solltest du zur Sicherheit irgendwo speichern, so dass du es für einen neuen Browser neu installieren kannst, wenn du z.B. etwas erneuern musst. Du brauchst es, um dich bei StartSSL einzuloggen, auch wenn du später wiederkommst.
Dieses Authentifizierungszertifikat wird nur für das Login benötigt und hat nichts mit dem Zertifikat zu tun, dass du später für deinen Server benötigst. Dieses Client-Zertifikat hat nichts mit dem SSL-Zertifikat für deinen Server zu tun.
Als Anfänger mit StartSSL kannst du [hier starten](https://www.startssl.com/?lang=de) und die "Express Lane" nutzen, um dein Browser-Zertifikiat zu erhalten.
Im nächsten Schritt kannst du die Einrichtung deines Zertifikats fortsetzen.
Wenn du zuerst nach einer Domain für dein Zertifikat gefragt wirst, musst du die Top-Level-Domain angeben, nicht die Subdomain, die Friendica nutzt. ### Schritt 2: Email-Adresse und Domain validieren
Im nächsten Schritt kannst du dann die Subdomain spezifizieren.
Wenn du also friendica.deinName.de auf deinem Server hast, musst du zuerst deinName.de angeben.
Höre nicht zu früh auf, wenn du am Ende der Einrichtung dein persönliches Server-Zertifikat erhalten hast. Um fortzufahren musst du beweisen, dass du die Email-Adresse, die du angegeben hast, und die Domain, für die du das Zertifikat möchtest, besitzt.
Abhängig von deiner Server-Software benötigst du ein oder zwei generische Dateien, die du mit deinem kostenlosen StartSSL-Zertifikat nutzen musst. Gehe in den "Validation wizard" und fordere einen Bestätigungslink per Mail an.
Diese Dateien sind sub.class1.server.ca.pem und ca.pem. Dasselbe machst du auch für die Validierung der Domain.
Wenn du diesen Schritt bereits übersprungen hast, kannst du die Dateien hier finden: [http://www.startssl.com/?app=21](http://www.startssl.com/?app=21).
Aber am besten funktioniert es, wenn du StartSSL nicht beendest, bevor du den Vorgang komplett abgeschlossen hast und dein https-Zertifikat hochgeladen ist und funktioniert.
**Virtuelle private und dedizierte Server (mit StartSSL free)** ### Schritt 3: Das Zertifikat bestellen
Der Rest dieses Dokuments ist etwas komplizierter, aber es ist auch nur für Personen, die Friendica auf einem virtuellen oder dedizierten Server nutzen. Gehe in den "Certificate wizard".
Jeder andere kann an dieser Stelle mit dem Lesen aufhören. Wähle das Target Webserver.
Bei der ersten Abfrage der Domain gibst du deine Hauptdomain an.
Im nächsten Schritt kannst du eine Subdomain hinzufügen.
Ein Beispiel: Wenn die Adresse der Friendica-Instanz friendica.beispiel.net lautet, gibst du zuerst beispiel.net an und danach friendica.
Folge den weiteren Anleitungen [hier](http://www.startssl.com/?app=20), um den Webserver, den du benutzt (z.B. Apache), für dein Zertifikat einzurichten. Wenn du weißt, wie man einen openssl-Schlüssel und einen Certificate Signing Request (CSR) erstellt, tu das.
Kopiere den CSR in den Browser, um ihn von StartSSL signiert zu bekommen.
Um die nötigen Schritte zu verdeutlichen, setzen wir nun voraus, dass Apache aktiv ist. Wenn du nicht weißt, wie man Schlüssel und CSR erzeugt, nimm das Angebot von StartSSL an, beides für dich zu generieren.
Im Wesentlichen kannst du einfach einen zweiten httpd.conf-Eintrag für Friendica erstellen. Das bedeutet: StartSSL hat den Schlüssel zu deiner SSL-Verschlüsselung, aber das ist immer noch besser als gar kein Zertifikat.
Lade dein Zertifikat von der Website herunter.
(Oder im zweiten Fall: Lade Zertifikat und Schlüssel herunter.)
Um das zu machen, kopiere den existierenden Eintrag und ändere das Ende der ersten Zeile auf "lesen" :443> anstelle von :80> und trage dann die folgenden Zeilen ein, wie du es auch in der Anleitung von StartSSL finden kannst: Um dein Zertifikat auf einem Webserver zu installieren, brauchst du noch ein oder zwei andere Dateien: sub.class1.server.ca.pem und ca.pem, auch von StartSSL.
Gehe in die Rubrik "Tool box" und lade "Class 1 Intermediate Server CA" und "StartCom Root CA (PEM encoded)" herunter.
SSLEngine on Wenn du dein Zertifikat zu deinem Hosting-Provider schicken möchtest, brauchen Sie mindestens Zertifikat und Schlüssel.
SSLProtocol all -SSLv2 Schick zur Sicherheit alle vier Dateien hin.
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM **Du solltest sie auf einem verschlüsselten Weg hinschicken!**
SSLCertificateFile /usr/local/apache/conf/ssl.crt Wenn du deinen eigenen Server betreibst, lade die Dateien hoch und besuche das Mozilla-Wiki (Link unten).
SSLCertificateKeyFile /usr/local/apache/conf/ssl.key
SSLCertificateChainFile /usr/local/apache/conf/sub.class1.server.ca.pem
SSLCACertificateFile /usr/local/apache/conf/ca.pem
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
CustomLog /usr/local/apache/logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
(Beachte, dass das Verzeichnis /usr/local/apache/conf/ möglicherweise nicht in deinem System existiert. Let's encrypt
In Debian ist der Pfad bspw. /etc/apache2/, in dem du ein SSL-Unterverzeichnis erstellen kannst, wenn dieses noch nicht vorhanden ist. ---
Dann hast du /etc/apache2/ssl/… statt /usr/local/apache/conf/…)
Du solltest nun zwei Einträgen für deine Friendica-Seite haben - einen für einfaches http und eines für https. Wenn du einen eigenen Server betreibst und den Nameserver kontrollierst, könnte auch die Initiative "Let's encrypt" interessant für dich werden.
Momentan ist deren Angebot noch nicht fertig.
Auf der [Website](https://letsencrypt.org/) kannst du dich über den Stand informieren.
Ein Hinweis für diejenigen, die SSL steuern wollen: setze keine Weiterleitung deines SSL in deine Apache-Einstellung. Friendicas Admin-Panel hat eine spezielle Einstellung für die SSL-Methode. Webserver-Einstellungen
Bitte nutze diese Einstellungen. ---
**Vermische Zertifikate in Apache StartSSL und andere (selbst-signierte)** Im [Wiki von Mozilla](https://wiki.mozilla.org/Security/Server_Side_TLS) gibt es Anleitungen für die Konfiguration sicherer Webserver.
Dort findest du Empfehlungen, die auf [verschiedene Webserver](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations) zugeschnitten sind.
Viele Leute nutzen einen virtuellen privaten oder einen dedizierten Server, um mehr als Friendica darauf laufen zu lassen. Teste deine SSL-Einstellungen
Sie wollen möglicherweise SSL auch für andere Seiten nutzen, die auf dem Server liegen. ---
Um das zu erreichen, wollen sie mehrere Zertifikate für eine IP nutzen, z.B. ein Zertifikat eines anerkannten Anbieters für Friendica und ein selbst-signiertes für eine persönliche Inhalte (möglw. ein Wildcard-Zertifikat für mehrere Subdomains).
Um das zum Laufen zu bringen, bietet Apache eine NameVirtualHost-Direktive. Wenn du fertig bist, kannst du auf der Testseite [SSL-Labs](https://www.ssllabs.com/ssltest/) prüfen lassen, ob Du alles richtig gemacht hast.
Du findest Informationen zur Nutzung in httpd.conf in den folgenden Ausschnitten.
Beachte, dass Wildcards (*) in httpd.conf dazu führen, dass die NameVirtualHost-Methode nicht funktioniert; du kannst diese in dieser neuen Konfiguration nicht nutzen.
Das bedeutet, dass *80> oder *443> nicht funktionieren.
Und du musst unbedingt die IP definieren, selbst wenn du nur eine hast.
Beachte außerdem, dass du bald zwei Zeilen zu Beginn der Datei hinzufügen musst, um NameVirtualHost für IPv6 vorzubereiten.
NameVirtualHost 12.123.456.1:443
NameVirtualHost 12.123.456.1:80
<VirtualHost www.anywhere.net:80>
DocumentRoot /var/www/anywhere
Servername www.anywhere.net
</VirtualHost>
<VirtualHost www.anywhere.net:443>
DocumentRoot /var/www/anywhere
Servername www.anywhere.net
SSLEngine On
<pointers to a an eligible cert>
<more ssl stuff >
<other stuff>
</VirtualHost>
<VirtualHost www.somewhere-else.net:80>
DocumentRoot /var/www/somewhere-else
Servername www.somewhere-else.net
</VirtualHost>
<VirtualHost www.somewhere-else:443>
DocumentRoot /var/www/somewhere-else
Servername www.somewhere-else.net
SSLEngine On
<pointers to another eligible cert>
<more ssl stuff >
<other stuff>
</VirtualHost>
Natürlich kannst du auch andere Verzeichnisse auf deinem Server nutzen, um Apache zu konfigurieren.
In diesem Fall müssen nur einige Zeilen in httpd.conf oder ports.conf angepasst werden - vor allem die NameVirtualHost-Zeilen.
Aber wenn du sicher im Umgang mit solchen Alternativen bist, wirst du sicherlich die nötigen Anpassungen herausfinden.
Starte dein Apache abschließend neu.
**StartSSL auf Nginx**
Führe zunächst ein Update auf den neuesten Friendica-Code durch.
Folge dann der Anleitung oben, um dein kostenloses Zertifikat zu erhalten.
Aber statt der Apache-Installationsanleitung zu folgen, mache das Folgende:
Lade dein Zertifikat hoch.
Es ist nicht wichtig, wohin du es lädst, solange Nginx es finden kann.
Einige Leute nutzen /home/verschiedeneNummernundBuchstaben, du kannst aber auch z.B. etwas wie /foo/bar nutzen.
Du kannst das Passwort entfernen, wenn du willst.
Es ist zwar möglicherweise nicht die beste Wahl, aber wenn du es nicht machst, wirst du das Passwort immer wieder eingeben müssen, wenn du Ngingx neustartest.
Um es zu entfernen, gebe Folgendes ein:
openssl rsa -in ssl.key-pass -out ssl.key
Nun hole dir das Hifs-Zertifikat:
wget http://www.startssl.com/certs/sub.class1.server.ca.pem
Nun vereinige die Dateien:
cat ssl.crt sub.class1.server.ca.pem > ssl.crt
In manchen Konfigurationen ist ein Bug enthalten, weshalb diese Schritte nicht ordentlich arbeiten.
Du musst daher ggf. ssl.crt bearbeiten:
nano /foo/bar/ssl.crt
Du wirst zwei Zertifikate in der gleichen Date sehen. In der Mitte findest du:
-----END CERTIFICATE----------BEGIN CERTIFICATE-----
Das ist schlecht. Du brauchst die folgenden Einträge:
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
Du kannst den Zeilenumbruch manuell eingeben, falls dein System vom Bug betroffen ist.
Beachte, dass nach -----BEGIN CERTIFICATE----- nur ein Zeilenumbruch ist.
Es gibt keine leere Zeile zwischen beiden Einträgen.
Nun musst du Nginx über die Zertifikate informieren.
In /etc/nginx/sites-available/foo.com.conf benötigst du etwas wie:
server {
listen 80;
listen 443 ssl;
listen [::]:80;
listen [::]:443 ipv6only=on ssl;
ssl_certificate /foo/bar/ssl.crt;
ssl_certificate_key /foo/bar/ssl.key;
...
Nun starte Nginx neu:
/etc/init.d/nginx restart
Und das war es schon.
Für multiple Domains ist es mit Nginx einfacher als mit Apache.
Du musst du oben genannten Schritte nur für jedes Zertifikat wiederholen und die spezifischen Informationen im eigenen {server...}-Bereich spezifizieren.

View file

@ -53,9 +53,21 @@ In the descirption and location field you can use BBCode to format the text.
When you *Share* the event it will be posted to your wall with the access permissions you've selected. When you *Share* the event it will be posted to your wall with the access permissions you've selected.
But before you do, you can also *preview* the event in a pop-up box. But before you do, you can also *preview* the event in a pop-up box.
### Interaction with Events
When you publish an event, you can choose who shall receive it, as with a regular new posting.
The recipients will see the posting about the event in their network-stream.
Additionally it will be added to their calendar and thus be shown in their events overview page.
Recipients of the event-posting can comment or dis-/like the event, as with a regular posting, but also announce that they will attend, not attend or may-be attend the event with a single click.
### Addons ### Addons
#### OpenStreetMap #### OpenStreetMap
If this addon is activated on you friendica node, the content of the location field will be mathced with the identification service of OSM when you submit the event. If this addon is activated on you friendica node, the content of the location field will be mathced with the identification service of OSM when you submit the event.
Should OSM find anything matching, a map for the location will be embedded automatically at the end of the events view. Should OSM find anything matching, a map for the location will be embedded automatically at the end of the events view.
#### Calendar Export
If this addon is activated the public events you have created will be published in ical or csv file. The URL of the published file is ``example.com/cal/nickname/export/format`` (where format is either ical of csv).

100
doc/htconfig.md Normal file
View file

@ -0,0 +1,100 @@
Config values that can only be set in .htconfig.php
===================================================
There are some config values that haven't found their way into the administration page. This has several reasons. Maybe they are part of a
current development that isn't considered stable and will be added later in the administration page when it is considered safe. Or it triggers
something that isn't expected to be of public interest. Or it is for testing purposes only.
**Attention:** Please be warned that you shouldn't use one of these values without the knowledge what it could trigger. Especially don't do that with
undocumented values.
The header of the section describes the category, the value is the parameter. Example: To set the directory value please add this
line to your .htconfig.php:
$a->config['system']['directory'] = 'http://dir.friendi.ca';
## Jabber ##
* debug (Boolean) - Enable debug level for the jabber account synchronisation.
* logfile - Logfile for the jabber account synchronisation.
## System ##
* birthday_input_format - Default value is "ymd".
* block_local_dir (Boolean) - Blocks the access to the directory of the local users.
* default_service_class -
* delivery_batch_count - Number of deliveries per process. Default value is 1. (Disabled when using the worker)
* diaspora_test (Boolean) - For development only. Disables the message transfer.
* directory - The path to global directory. If not set then "http://dir.friendi.ca" is used.
* disable_email_validation (Boolean) - Disables the check if a mail address is in a valid format and can be resolved via DNS.
* disable_url_validation (Boolean) - Disables the DNS lookup of an URL.
* event_input_format - Default value is "ymd".
* ignore_cache (Boolean) - For development only. Disables the item cache.
* like_no_comment (Boolean) - Don't update the "commented" value of an item when it is liked.
* local_block (Boolean) - Used in conjunction with "block_public".
* local_search (Boolean) - Blocks the search for not logged in users to prevent crawlers from blocking your system.
* max_contact_queue - Default value is 500.
* max_batch_queue - Default value is 1000.
* no_oembed (Boolean) - Don't use OEmbed to fetch more information about a link.
* no_oembed_rich_content (Boolean) - Don't show the rich content (e.g. embedded PDF).
* no_smilies (Boolean) - Don't show smilies.
* no_view_full_size (Boolean) - Don't add the link "View full size" under a resized image.
* optimize_items (Boolean) - Triggers an SQL command to optimize the item table before expiring items.
* ostatus_poll_timeframe - Defines how old an item can be to try to complete the conversation with it.
* paranoia (Boolean) - Log out users if their IP address changed.
* permit_crawling (Boolean) - Restricts the search for not logged in users to one search per minute.
* free_crawls - Number of "free" searches when "permit_crawling" is activated (Default value is 10)
* crawl_permit_period - Period in seconds between allowed searches when the number of free searches is reached and "permit_crawling" is activated (Default value is 60)
* png_quality - Default value is 8.
* proc_windows (Boolean) - Should be enabled if Friendica is running under Windows.
* proxy_cache_time - Time after which the cache is cleared. Default value is one day.
* pushpoll_frequency -
* qsearch_limit - Default value is 100.
* relay_server - Experimental Diaspora feature. Address of the relay server where public posts should be send to. For example https://podrelay.net
* relay_subscribe (Boolean) - Enables the receiving of public posts from the relay. They will be included in the search and on the community page when it is set up to show all public items.
* relay_scope - Can be "all" or "tags". "all" means that every public post should be received. "tags" means that only posts witt selected tags should be received.
* relay_server_tags - Comma separated list of tags for the "tags" subscription (see "relay_scrope")
* relay_user_tags (Boolean) - If enabled, the tags from the saved searches will used for the "tags" subscription in addition to the "relay_server_tags".
* remove_multiplicated_lines (Boolean) - If enabled, multiple linefeeds in items are stripped to a single one.
* show_unsupported_addons (Boolean) - Show all addons including the unsupported ones.
* show_unsupported_themes (Boolean) - Show all themes including the unsupported ones.
* throttle_limit_day - Maximum number of posts that a user can send per day with the API.
* throttle_limit_week - Maximum number of posts that a user can send per week with the API.
* throttle_limit_month - Maximum number of posts that a user can send per month with the API.
* wall-to-wall_share (Boolean) - Displays forwarded posts like "wall-to-wall" posts.
* worker (Boolean) - (Experimental) Use the worker system instead of calling several background processes. Reduces the overall load and speeds up item delivery.
* worker_dont_fork (Boolean) - if enabled, the workers are only called from the poller process. Useful on systems that permit the use of "proc_open".
* worker_queues - Number of parallel workers. Default value is 10 queues.
* xrd_timeout - Timeout for fetching the XRD links. Default value is 20 seconds.
## service_class ##
* upgrade_link -
## experimentals ##
* exp_themes (Boolean) - Show experimental themes as well.
## theme ##
* hide_eventlist (Boolean) - Don't show the birthdays and events on the profile and network page
# Administrator Options #
Enabling the admin panel for an account, and thus making the account holder
admin of the node, is done by setting the variable
$a->config['admin_email'] = "someone@example.com";
where you have to match the email address used for the account with the one you
enter to the .htconfig file. If more then one account should be able to access
the admin panel, seperate the email addresses with a comma.
$a->config['admin_email'] = "someone@example.com,someonelese@example.com";
If you want to have a more personalized closing line for the notification
emails you can set a variable for the admin_name.
$a->config['admin_name'] = "Marvin";

16
doc/html/index.php Normal file
View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>$Projectname Doxygen API Documentation</title>
</head>
<body>
<h1>$Projectname Doxygen API Documentation not rendered</h1>
To get the Doxygen API Documentation you must render it with the program <a href="http://www.doxygen.org">Doxygen</a> (included in most distributions).
<pre>
$ doxygen util/Doxyfile
</pre>
<br>
<a href="javascript:history.back()">back</a>
</body>
</html>

45
doc/install-ejabberd.md Normal file
View file

@ -0,0 +1,45 @@
Install an ejabberd with synchronized credentials
=================================================
* [Home](help)
[Ejabberd](https://www.ejabberd.im/) is a chat server that uses XMPP as messaging protocol that you can use with a large amount of clients. In conjunction
with the "xmpp" addon it can be used for a web based chat solution for your users.
Installation
------------
- Change it's owner to whichever user is running the server, ie. ejabberd
$ chown ejabberd:ejabberd /path/to/friendica/include/auth_ejabberd.php
- Change the access mode so it is readable only to the user ejabberd and has exec
$ chmod 700 /path/to/friendica/include/auth_ejabberd.php
- Edit your ejabberd.cfg file, comment out your auth_method and add:
{auth_method, external}.
{extauth_program, "/path/to/friendica/include/auth_ejabberd.php"}.
- Disable the module "mod_register" and disable the registration:
{access, register, [{deny, all}]}.
- Enable BOSH:
- Enable the module "mod_http_bind"
- Edit this line:
{5280, ejabberd_http, [captcha, http_poll, http_bind]}
- In your apache configuration for your site add this line:
ProxyPass /http-bind http://127.0.0.1:5280/http-bind retry=0
- Restart your ejabberd service, you should be able to login with your friendica credentials
Other hints
-----------
- if a user has a space or a @ in the nickname, the user has to replace these characters:
- " " (space) is replaced with "%20"
- "@" is replaced with "(a)"

View file

@ -30,6 +30,7 @@ Friendica Documentation and Resources
* [Settings](help/Settings) * [Settings](help/Settings)
* [Plugins](help/Plugins) * [Plugins](help/Plugins)
* [Installing Connectors (Twitter/GNU Social)](help/Installing-Connectors) * [Installing Connectors (Twitter/GNU Social)](help/Installing-Connectors)
* [Install an ejabberd server (XMPP chat) with synchronized credentials](help/install-ejabberd)
* [Message Flow](help/Message-Flow) * [Message Flow](help/Message-Flow)
* [Using SSL with Friendica](help/SSL) * [Using SSL with Friendica](help/SSL)
* [Developers](help/Developers) * [Developers](help/Developers)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -191,8 +191,90 @@ function unmark_for_death($contact) {
); );
}} }}
function get_contact_details_by_url($url, $uid = -1) {
if ($uid == -1)
$uid = local_user();
$r = q("SELECT `id` AS `gid`, `url`, `name`, `nick`, `addr`, `photo`, `location`, `about`, `keywords`, `gender`, `community`, `network` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
dbesc(normalise_link($url)));
if ($r) {
$profile = $r[0];
if ((($profile["addr"] == "") OR ($profile["name"] == "")) AND
in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
proc_run('php',"include/update_gcontact.php", $profile["gid"]);
} else {
$r = q("SELECT `url`, `name`, `nick`, `avatar` AS `photo`, `location`, `about` FROM `unique_contacts` WHERE `url` = '%s'",
dbesc(normalise_link($url)));
if (count($r)) {
$profile = $r[0];
$profile["keywords"] = "";
$profile["gender"] = "";
$profile["community"] = false;
$profile["network"] = "";
$profile["addr"] = "";
}
}
// Fetching further contact data from the contact table
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` = '%s'",
dbesc(normalise_link($url)), intval($uid), dbesc($profile["network"]));
if (!count($r))
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
dbesc(normalise_link($url)), intval($uid));
if (!count($r))
$r = q("SELECT `id`, `uid`, `url`, `network`, `name`, `nick`, `addr`, `location`, `about`, `keywords`, `gender`, `photo`, `addr`, `forum`, `prv`, `bd` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
dbesc(normalise_link($url)));
if ($r) {
if (isset($r[0]["url"]) AND $r[0]["url"])
$profile["url"] = $r[0]["url"];
if (isset($r[0]["name"]) AND $r[0]["name"])
$profile["name"] = $r[0]["name"];
if (isset($r[0]["nick"]) AND $r[0]["nick"] AND ($profile["nick"] == ""))
$profile["nick"] = $r[0]["nick"];
if (isset($r[0]["addr"]) AND $r[0]["addr"] AND ($profile["addr"] == ""))
$profile["addr"] = $r[0]["addr"];
if (isset($r[0]["photo"]) AND $r[0]["photo"])
$profile["photo"] = $r[0]["photo"];
if (isset($r[0]["location"]) AND $r[0]["location"])
$profile["location"] = $r[0]["location"];
if (isset($r[0]["about"]) AND $r[0]["about"])
$profile["about"] = $r[0]["about"];
if (isset($r[0]["keywords"]) AND $r[0]["keywords"])
$profile["keywords"] = $r[0]["keywords"];
if (isset($r[0]["gender"]) AND $r[0]["gender"])
$profile["gender"] = $r[0]["gender"];
if (isset($r[0]["forum"]) OR isset($r[0]["prv"]))
$profile["community"] = ($r[0]["forum"] OR $r[0]["prv"]);
if (isset($r[0]["network"]) AND $r[0]["network"])
$profile["network"] = $r[0]["network"];
if (isset($r[0]["addr"]) AND $r[0]["addr"])
$profile["addr"] = $r[0]["addr"];
if (isset($r[0]["bd"]) AND $r[0]["bd"])
$profile["bd"] = $r[0]["bd"];
if ($r[0]["uid"] == 0)
$profile["cid"] = 0;
else
$profile["cid"] = $r[0]["id"];
} else
$profile["cid"] = 0;
if (($profile["cid"] == 0) AND ($profile["network"] == NETWORK_DIASPORA)) {
$profile["location"] = "";
$profile["about"] = "";
}
return($profile);
}
if(! function_exists('contact_photo_menu')){ if(! function_exists('contact_photo_menu')){
function contact_photo_menu($contact) { function contact_photo_menu($contact, $uid = 0) {
$a = get_app(); $a = get_app();
@ -204,6 +286,33 @@ function contact_photo_menu($contact) {
$contact_drop_link = ""; $contact_drop_link = "";
$poke_link=""; $poke_link="";
if ($uid == 0)
$uid = local_user();
if ($contact["uid"] != $uid) {
if ($uid == 0) {
$profile_link = zrl($contact['url']);
$menu = Array('profile' => array(t("View Profile"), $profile_link, true));
return $menu;
}
$r = q("SELECT * FROM `contact` WHERE `nurl` = '%s' AND `network` = '%s' AND `uid` = %d",
dbesc($contact["nurl"]), dbesc($contact["network"]), intval($uid));
if ($r)
return contact_photo_menu($r[0], $uid);
else {
$profile_link = zrl($contact['url']);
$connlnk = 'follow/?url='.$contact['url'];
$menu = Array(
'profile' => array(t("View Profile"), $profile_link, true),
'follow' => array(t("Connect/Follow"), $connlnk, true)
);
return $menu;
}
}
$sparkle = false; $sparkle = false;
if($contact['network'] === NETWORK_DFRN) { if($contact['network'] === NETWORK_DFRN) {
$sparkle = true; $sparkle = true;
@ -219,24 +328,32 @@ function contact_photo_menu($contact) {
$status_link = $profile_link . "?url=status"; $status_link = $profile_link . "?url=status";
$photos_link = $profile_link . "?url=photos"; $photos_link = $profile_link . "?url=photos";
$profile_link = $profile_link . "?url=profile"; $profile_link = $profile_link . "?url=profile";
$pm_url = $a->get_baseurl() . '/message/new/' . $contact['id'];
} }
if (in_array($contact["network"], array(NETWORK_DFRN, NETWORK_DIASPORA)))
$pm_url = $a->get_baseurl() . '/message/new/' . $contact['id'];
if ($contact["network"] == NETWORK_DFRN)
$poke_link = $a->get_baseurl() . '/poke/?f=&c=' . $contact['id']; $poke_link = $a->get_baseurl() . '/poke/?f=&c=' . $contact['id'];
$contact_url = $a->get_baseurl() . '/contacts/' . $contact['id']; $contact_url = $a->get_baseurl() . '/contacts/' . $contact['id'];
$posts_link = $a->get_baseurl() . '/network/0?nets=all&cid=' . $contact['id']; $posts_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/posts';
$contact_drop_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/drop?confirm=1'; $contact_drop_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/drop?confirm=1';
/**
* menu array:
* "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ]
*/
$menu = Array( $menu = Array(
'poke' => array(t("Poke"), $poke_link), 'status' => array(t("View Status"), $status_link, true),
'status' => array(t("View Status"), $status_link), 'profile' => array(t("View Profile"), $profile_link, true),
'profile' => array(t("View Profile"), $profile_link), 'photos' => array(t("View Photos"), $photos_link,true),
'photos' => array(t("View Photos"), $photos_link), 'network' => array(t("Network Posts"), $posts_link,false),
'network' => array(t("Network Posts"), $posts_link), 'edit' => array(t("Edit Contact"), $contact_url, false),
'edit' => array(t("Edit Contact"), $contact_url), 'drop' => array(t("Drop Contact"), $contact_drop_link, false),
'drop' => array(t("Drop Contact"), $contact_drop_link), 'pm' => array(t("Send PM"), $pm_url, false),
'pm' => array(t("Send PM"), $pm_url), 'poke' => array(t("Poke"), $poke_link, false),
); );
@ -244,25 +361,13 @@ function contact_photo_menu($contact) {
call_hooks('contact_photo_menu', $args); call_hooks('contact_photo_menu', $args);
/* $o = ""; $menucondensed = array();
foreach($menu as $k=>$v){
if ($v!="") { foreach ($menu AS $menuname=>$menuitem)
if(($k !== t("Network Posts")) && ($k !== t("Send PM")) && ($k !== t('Edit Contact'))) if ($menuitem[1] != "")
$o .= "<li><a target=\"redir\" href=\"$v\">$k</a></li>\n"; $menucondensed[$menuname] = $menuitem;
else
$o .= "<li><a href=\"$v\">$k</a></li>\n"; return $menucondensed;
}
}
return $o;*/
foreach($menu as $k=>$v){
if ($v[1]!="") {
if(($v[0] !== t("Network Posts")) && ($v[0] !== t("Send PM")) && ($v[0] !== t('Edit Contact')))
$menu[$k][2] = 1;
else
$menu[$k][2] = 0;
}
}
return $menu;
}} }}

View file

@ -371,12 +371,11 @@ class Photo {
if( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') ) if( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') )
return; return;
$exif = @exif_read_data($filename); $exif = @exif_read_data($filename,null,true);
if(! $exif) if(! $exif)
return; return;
$ort = $exif['Orientation']; $ort = $exif['IFD0']['Orientation'];
switch($ort) switch($ort)
{ {
@ -413,6 +412,10 @@ class Photo {
$this->rotate(90); $this->rotate(90);
break; break;
} }
// logger('exif: ' . print_r($exif,true));
return $exif;
} }

View file

@ -4,7 +4,7 @@ require_once('library/HTML5/Parser.php');
require_once('include/crypto.php'); require_once('include/crypto.php');
if(! function_exists('scrape_dfrn')) { if(! function_exists('scrape_dfrn')) {
function scrape_dfrn($url) { function scrape_dfrn($url, $dont_probe = false) {
$a = get_app(); $a = get_app();
@ -17,6 +17,13 @@ function scrape_dfrn($url) {
if(! $s) if(! $s)
return $ret; return $ret;
if (!$dont_probe) {
$probe = probe_url($url);
if (isset($probe["addr"]))
$ret["addr"] = $probe["addr"];
}
$headers = $a->get_curl_headers(); $headers = $a->get_curl_headers();
logger('scrape_dfrn: headers=' . $headers, LOGGER_DEBUG); logger('scrape_dfrn: headers=' . $headers, LOGGER_DEBUG);
@ -407,7 +414,7 @@ function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
$pubkey = $diaspora_key; $pubkey = $diaspora_key;
$diaspora = true; $diaspora = true;
} }
if($link['@attributes']['rel'] === 'http://ostatus.org/schema/1.0/subscribe') { if(($link['@attributes']['rel'] === 'http://ostatus.org/schema/1.0/subscribe') AND ($mode == PROBE_NORMAL)) {
$diaspora = false; $diaspora = false;
} }
} }
@ -524,7 +531,7 @@ function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
if(strlen($dfrn)) { if(strlen($dfrn)) {
$ret = scrape_dfrn(($hcard) ? $hcard : $dfrn); $ret = scrape_dfrn(($hcard) ? $hcard : $dfrn, true);
if(is_array($ret) && x($ret,'dfrn-request')) { if(is_array($ret) && x($ret,'dfrn-request')) {
$network = NETWORK_DFRN; $network = NETWORK_DFRN;
$request = $ret['dfrn-request']; $request = $ret['dfrn-request'];
@ -552,7 +559,7 @@ function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
if($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) { if($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
if($diaspora) if($diaspora)
$network = NETWORK_DIASPORA; $network = NETWORK_DIASPORA;
elseif($has_lrdd) elseif($has_lrdd AND ($notify))
$network = NETWORK_OSTATUS; $network = NETWORK_OSTATUS;
if(strpos($url,'@')) if(strpos($url,'@'))
@ -652,9 +659,10 @@ function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
$feed->set_raw_data(($xml) ? $xml : '<?xml version="1.0" encoding="utf-8" ?><xml></xml>'); $feed->set_raw_data(($xml) ? $xml : '<?xml version="1.0" encoding="utf-8" ?><xml></xml>');
$feed->init(); $feed->init();
if($feed->error()) if($feed->error()) {
logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error()); logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error());
$network = NETWORK_PHANTOM;
}
if(! x($vcard,'photo')) if(! x($vcard,'photo'))
$vcard['photo'] = $feed->get_image_url(); $vcard['photo'] = $feed->get_image_url();
@ -718,6 +726,45 @@ function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
} }
} }
// Workaround for misconfigured Friendica servers
if (($network == "") AND (strstr($url, "/profile/"))) {
$noscrape = str_replace("/profile/", "/noscrape/", $url);
$noscrapejson = fetch_url($noscrape);
if ($noscrapejson) {
$network = NETWORK_DFRN;
$poco = str_replace("/profile/", "/poco/", $url);
$noscrapedata = json_decode($noscrapejson, true);
if (isset($noscrapedata["addr"]))
$addr = $noscrapedata["addr"];
if (isset($noscrapedata["fn"]))
$vcard["fn"] = $noscrapedata["fn"];
if (isset($noscrapedata["key"]))
$pubkey = $noscrapedata["key"];
if (isset($noscrapedata["photo"]))
$vcard["photo"] = $noscrapedata["photo"];
if (isset($noscrapedata["dfrn-request"]))
$request = $noscrapedata["dfrn-request"];
if (isset($noscrapedata["dfrn-confirm"]))
$confirm = $noscrapedata["dfrn-confirm"];
if (isset($noscrapedata["dfrn-notify"]))
$notify = $noscrapedata["dfrn-notify"];
if (isset($noscrapedata["dfrn-poll"]))
$poll = $noscrapedata["dfrn-poll"];
}
}
if((! $vcard['photo']) && strlen($email)) if((! $vcard['photo']) && strlen($email))
$vcard['photo'] = avatar_img($email); $vcard['photo'] = avatar_img($email);
if($poll === $profile) if($poll === $profile)
@ -778,6 +825,9 @@ function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
$baseurl = rtrim($baseurl, "/"); $baseurl = rtrim($baseurl, "/");
if(strpos($url,'@') AND ($addr == "") AND ($network == NETWORK_DFRN))
$addr = str_replace('acct:', '', $url);
$vcard['fn'] = notags($vcard['fn']); $vcard['fn'] = notags($vcard['fn']);
$vcard['nick'] = str_replace(' ','',notags($vcard['nick'])); $vcard['nick'] = str_replace(' ','',notags($vcard['nick']));
@ -820,7 +870,7 @@ function probe_url($url, $mode = PROBE_NORMAL, $level = 1) {
} }
// Only store into the cache if the value seems to be valid // Only store into the cache if the value seems to be valid
if ($result['network'] != NETWORK_FEED) if ($result['network'] != NETWORK_PHANTOM)
Cache::set("probe_url:".$mode.":".$url,serialize($result), CACHE_DAY); Cache::set("probe_url:".$mode.":".$url,serialize($result), CACHE_DAY);
return $result; return $result;

View file

@ -1,6 +1,7 @@
<?php <?php
require_once("include/contact_selectors.php"); require_once("include/contact_selectors.php");
require_once("include/contact_widgets.php");
require_once("include/features.php"); require_once("include/features.php");
require_once("mod/proxy.php"); require_once("mod/proxy.php");
@ -392,7 +393,6 @@ function acl_lookup(&$a, $out_type = 'json') {
if(!local_user()) if(!local_user())
return ""; return "";
$start = (x($_REQUEST,'start')?$_REQUEST['start']:0); $start = (x($_REQUEST,'start')?$_REQUEST['start']:0);
$count = (x($_REQUEST,'count')?$_REQUEST['count']:100); $count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
$search = (x($_REQUEST,'search')?$_REQUEST['search']:""); $search = (x($_REQUEST,'search')?$_REQUEST['search']:"");
@ -426,6 +426,8 @@ function acl_lookup(&$a, $out_type = 'json') {
$group_count = 0; $group_count = 0;
} }
$sql_extra2 .= " ".unavailable_networks();
if ($type=='' || $type=='c'){ if ($type=='' || $type=='c'){
$r = q("SELECT COUNT(*) AS c FROM `contact` $r = q("SELECT COUNT(*) AS c FROM `contact`
WHERE `uid` = %d AND `self` = 0 WHERE `uid` = %d AND `self` = 0
@ -492,7 +494,7 @@ function acl_lookup(&$a, $out_type = 'json') {
$groups[] = array( $groups[] = array(
"type" => "g", "type" => "g",
"photo" => "images/twopeople.png", "photo" => "images/twopeople.png",
"name" => $g['name'], "name" => htmlentities($g['name']),
"id" => intval($g['id']), "id" => intval($g['id']),
"uids" => array_map("intval", explode(",",$g['uids'])), "uids" => array_map("intval", explode(",",$g['uids'])),
"link" => '', "link" => '',
@ -545,9 +547,9 @@ function acl_lookup(&$a, $out_type = 'json') {
$x['data'] = array(); $x['data'] = array();
if(count($r)) { if(count($r)) {
foreach($r as $g) { foreach($r as $g) {
$x['photos'][] = proxy_url($g['micro']); $x['photos'][] = proxy_url($g['micro'], false, PROXY_SIZE_MICRO);
$x['links'][] = $g['url']; $x['links'][] = $g['url'];
$x['suggestions'][] = $g['name']; $x['suggestions'][] = htmlentities($g['name']);
$x['data'][] = intval($g['id']); $x['data'][] = intval($g['id']);
} }
} }
@ -559,12 +561,12 @@ function acl_lookup(&$a, $out_type = 'json') {
foreach($r as $g){ foreach($r as $g){
$contacts[] = array( $contacts[] = array(
"type" => "c", "type" => "c",
"photo" => proxy_url($g['micro']), "photo" => proxy_url($g['micro'], false, PROXY_SIZE_MICRO),
"name" => $g['name'], "name" => htmlentities($g['name']),
"id" => intval($g['id']), "id" => intval($g['id']),
"network" => $g['network'], "network" => $g['network'],
"link" => $g['url'], "link" => $g['url'],
"nick" => ($g['attag']) ? $g['attag'] : $g['nick'], "nick" => htmlentities(($g['attag']) ? $g['attag'] : $g['nick']),
"forum" => $g['forum'] "forum" => $g['forum']
); );
} }
@ -604,12 +606,12 @@ function acl_lookup(&$a, $out_type = 'json') {
// /nickname // /nickname
$unknow_contacts[] = array( $unknow_contacts[] = array(
"type" => "c", "type" => "c",
"photo" => proxy_url($row['author-avatar']), "photo" => proxy_url($row['author-avatar'], false, PROXY_SIZE_MICRO),
"name" => $row['author-name'], "name" => htmlentities($row['author-name']),
"id" => '', "id" => '',
"network" => "unknown", "network" => "unknown",
"link" => $row['author-link'], "link" => $row['author-link'],
"nick" => $nick, "nick" => htmlentities($nick),
"forum" => false "forum" => false
); );
} }

View file

@ -285,7 +285,7 @@
* Unique contact to contact url. * Unique contact to contact url.
*/ */
function api_unique_id_to_url($id){ function api_unique_id_to_url($id){
$r = q("SELECT url FROM unique_contacts WHERE id=%d LIMIT 1", $r = q("SELECT `url` FROM `unique_contacts` WHERE `id`=%d LIMIT 1",
intval($id)); intval($id));
if ($r) if ($r)
return ($r[0]["url"]); return ($r[0]["url"]);
@ -390,9 +390,9 @@
$r = array(); $r = array();
if ($url != "") if ($url != "")
$r = q("SELECT * FROM unique_contacts WHERE url='%s' LIMIT 1", $url); $r = q("SELECT * FROM `unique_contacts` WHERE `url`='%s' LIMIT 1", $url);
elseif ($nick != "") elseif ($nick != "")
$r = q("SELECT * FROM unique_contacts WHERE nick='%s' LIMIT 1", $nick); $r = q("SELECT * FROM `unique_contacts` WHERE `nick`='%s' LIMIT 1", $nick);
if ($r) { if ($r) {
// If no nick where given, extract it from the address // If no nick where given, extract it from the address
@ -505,14 +505,14 @@
} }
// Fetching unique id // Fetching unique id
$r = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", dbesc(normalise_link($uinfo[0]['url']))); $r = q("SELECT id FROM `unique_contacts` WHERE `url`='%s' LIMIT 1", dbesc(normalise_link($uinfo[0]['url'])));
// If not there, then add it // If not there, then add it
if (count($r) == 0) { if (count($r) == 0) {
q("INSERT INTO unique_contacts (url, name, nick, avatar) VALUES ('%s', '%s', '%s', '%s')", q("INSERT INTO `unique_contacts` (`url`, `name`, `nick`, `avatar`) VALUES ('%s', '%s', '%s', '%s')",
dbesc(normalise_link($uinfo[0]['url'])), dbesc($uinfo[0]['name']),dbesc($uinfo[0]['nick']), dbesc($uinfo[0]['micro'])); dbesc(normalise_link($uinfo[0]['url'])), dbesc($uinfo[0]['name']),dbesc($uinfo[0]['nick']), dbesc($uinfo[0]['micro']));
$r = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", dbesc(normalise_link($uinfo[0]['url']))); $r = q("SELECT `id` FROM `unique_contacts` WHERE `url`='%s' LIMIT 1", dbesc(normalise_link($uinfo[0]['url'])));
} }
$network_name = network_to_name($uinfo[0]['network'], $uinfo[0]['url']); $network_name = network_to_name($uinfo[0]['network'], $uinfo[0]['url']);
@ -539,7 +539,8 @@
'verified' => true, 'verified' => true,
'statusnet_blocking' => false, 'statusnet_blocking' => false,
'notifications' => false, 'notifications' => false,
'statusnet_profile_url' => $a->get_baseurl()."/contacts/".$uinfo[0]['cid'], //'statusnet_profile_url' => $a->get_baseurl()."/contacts/".$uinfo[0]['cid'],
'statusnet_profile_url' => $uinfo[0]['url'],
'uid' => intval($uinfo[0]['uid']), 'uid' => intval($uinfo[0]['uid']),
'cid' => intval($uinfo[0]['cid']), 'cid' => intval($uinfo[0]['cid']),
'self' => $uinfo[0]['self'], 'self' => $uinfo[0]['self'],
@ -552,32 +553,44 @@
function api_item_get_user(&$a, $item) { function api_item_get_user(&$a, $item) {
$author = q("SELECT * FROM unique_contacts WHERE url='%s' LIMIT 1", $author = q("SELECT * FROM `unique_contacts` WHERE `url`='%s' LIMIT 1",
dbesc(normalise_link($item['author-link']))); dbesc(normalise_link($item['author-link'])));
if (count($author) == 0) { if (count($author) == 0) {
q("INSERT INTO unique_contacts (url, name, avatar) VALUES ('%s', '%s', '%s')", q("INSERT INTO `unique_contacts` (`url`, `name`, `avatar`) VALUES ('%s', '%s', '%s')",
dbesc(normalise_link($item["author-link"])), dbesc($item["author-name"]), dbesc($item["author-avatar"])); dbesc(normalise_link($item["author-link"])), dbesc($item["author-name"]), dbesc($item["author-avatar"]));
$author = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", $author = q("SELECT `id` FROM `unique_contacts` WHERE `url`='%s' LIMIT 1",
dbesc(normalise_link($item['author-link']))); dbesc(normalise_link($item['author-link'])));
} else if ($item["author-link"].$item["author-name"] != $author[0]["url"].$author[0]["name"]) { } else if ($item["author-link"].$item["author-name"] != $author[0]["url"].$author[0]["name"]) {
q("UPDATE unique_contacts SET name = '%s', avatar = '%s' WHERE url = '%s'", $r = q("SELECT `id` FROM `unique_contacts` WHERE `name` = '%s' AND `avatar` = '%s' AND url = '%s'",
dbesc($item["author-name"]), dbesc($item["author-avatar"]), dbesc(normalise_link($item["author-link"]))); dbesc($item["author-name"]), dbesc($item["author-avatar"]),
dbesc(normalise_link($item["author-link"])));
if (!$r)
q("UPDATE `unique_contacts` SET `name` = '%s', `avatar` = '%s' WHERE `url` = '%s'",
dbesc($item["author-name"]), dbesc($item["author-avatar"]),
dbesc(normalise_link($item["author-link"])));
} }
$owner = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", $owner = q("SELECT `id` FROM `unique_contacts` WHERE `url`='%s' LIMIT 1",
dbesc(normalise_link($item['owner-link']))); dbesc(normalise_link($item['owner-link'])));
if (count($owner) == 0) { if (count($owner) == 0) {
q("INSERT INTO unique_contacts (url, name, avatar) VALUES ('%s', '%s', '%s')", q("INSERT INTO `unique_contacts` (`url`, `name`, `avatar`) VALUES ('%s', '%s', '%s')",
dbesc(normalise_link($item["owner-link"])), dbesc($item["owner-name"]), dbesc($item["owner-avatar"])); dbesc(normalise_link($item["owner-link"])), dbesc($item["owner-name"]), dbesc($item["owner-avatar"]));
$owner = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1", $owner = q("SELECT `id` FROM `unique_contacts` WHERE `url`='%s' LIMIT 1",
dbesc(normalise_link($item['owner-link']))); dbesc(normalise_link($item['owner-link'])));
} else if ($item["owner-link"].$item["owner-name"] != $owner[0]["url"].$owner[0]["name"]) { } else if ($item["owner-link"].$item["owner-name"] != $owner[0]["url"].$owner[0]["name"]) {
q("UPDATE unique_contacts SET name = '%s', avatar = '%s' WHERE url = '%s'", $r = q("SELECT `id` FROM `unique_contacts` WHERE `name` = '%s' AND `avatar` = '%s' AND url = '%s'",
dbesc($item["owner-name"]), dbesc($item["owner-avatar"]), dbesc(normalise_link($item["owner-link"]))); dbesc($item["owner-name"]), dbesc($item["owner-avatar"]),
dbesc(normalise_link($item["owner-link"])));
if (!$r)
q("UPDATE `unique_contacts` SET `name` = '%s', `avatar` = '%s' WHERE `url` = '%s'",
dbesc($item["owner-name"]), dbesc($item["owner-avatar"]),
dbesc(normalise_link($item["owner-link"])));
} }
// Comments in threads may appear as wall-to-wall postings. // Comments in threads may appear as wall-to-wall postings.
@ -914,14 +927,18 @@
logger('api_status_show: user_info: '.print_r($user_info, true), LOGGER_DEBUG); logger('api_status_show: user_info: '.print_r($user_info, true), LOGGER_DEBUG);
if ($type == "raw")
$privacy_sql = "AND `item`.`allow_cid`='' AND `item`.`allow_gid`='' AND `item`.`deny_cid`='' AND `item`.`deny_gid`=''";
else
$privacy_sql = "";
// get last public wall message // get last public wall message
$lastwall = q("SELECT `item`.*, `i`.`contact-id` as `reply_uid`, `i`.`author-link` AS `item-author` $lastwall = q("SELECT `item`.*, `i`.`contact-id` as `reply_uid`, `i`.`author-link` AS `item-author`
FROM `item`, `item` as `i` FROM `item`, `item` as `i`
WHERE `item`.`contact-id` = %d AND `item`.`uid` = %d WHERE `item`.`contact-id` = %d AND `item`.`uid` = %d
AND ((`item`.`author-link` IN ('%s', '%s')) OR (`item`.`owner-link` IN ('%s', '%s'))) AND ((`item`.`author-link` IN ('%s', '%s')) OR (`item`.`owner-link` IN ('%s', '%s')))
AND `i`.`id` = `item`.`parent` AND `i`.`id` = `item`.`parent`
AND `item`.`type`!='activity' AND `item`.`type`!='activity' $privacy_sql
AND `item`.`allow_cid`='' AND `item`.`allow_gid`='' AND `item`.`deny_cid`='' AND `item`.`deny_gid`=''
ORDER BY `item`.`created` DESC ORDER BY `item`.`created` DESC
LIMIT 1", LIMIT 1",
intval($user_info['cid']), intval($user_info['cid']),
@ -944,7 +961,7 @@
$in_reply_to_status_id= intval($lastwall['parent']); $in_reply_to_status_id= intval($lastwall['parent']);
$in_reply_to_status_id_str = (string) intval($lastwall['parent']); $in_reply_to_status_id_str = (string) intval($lastwall['parent']);
$r = q("SELECT * FROM unique_contacts WHERE `url` = '%s'", dbesc(normalise_link($lastwall['item-author']))); $r = q("SELECT * FROM `unique_contacts` WHERE `url` = '%s'", dbesc(normalise_link($lastwall['item-author'])));
if ($r) { if ($r) {
if ($r[0]['nick'] == "") if ($r[0]['nick'] == "")
$r[0]['nick'] = api_get_nick($r[0]["url"]); $r[0]['nick'] = api_get_nick($r[0]["url"]);
@ -967,7 +984,7 @@
$in_reply_to_screen_name = NULL; $in_reply_to_screen_name = NULL;
} }
$converted = api_convert_item($item); $converted = api_convert_item($lastwall);
$status_info = array( $status_info = array(
'created_at' => api_date($lastwall['created']), 'created_at' => api_date($lastwall['created']),
@ -1013,6 +1030,8 @@
unset($status_info["user"]["self"]); unset($status_info["user"]["self"]);
} }
logger('status_info: '.print_r($status_info, true), LOGGER_DEBUG);
if ($type == "raw") if ($type == "raw")
return($status_info); return($status_info);
@ -1064,7 +1083,7 @@
$in_reply_to_status_id = intval($lastwall['parent']); $in_reply_to_status_id = intval($lastwall['parent']);
$in_reply_to_status_id_str = (string) intval($lastwall['parent']); $in_reply_to_status_id_str = (string) intval($lastwall['parent']);
$r = q("SELECT * FROM unique_contacts WHERE `url` = '%s'", dbesc(normalise_link($reply[0]['item-author']))); $r = q("SELECT * FROM `unique_contacts` WHERE `url` = '%s'", dbesc(normalise_link($reply[0]['item-author'])));
if ($r) { if ($r) {
if ($r[0]['nick'] == "") if ($r[0]['nick'] == "")
$r[0]['nick'] = api_get_nick($r[0]["url"]); $r[0]['nick'] = api_get_nick($r[0]["url"]);
@ -1076,7 +1095,7 @@
} }
} }
$converted = api_convert_item($item); $converted = api_convert_item($lastwall);
$user_info['status'] = array( $user_info['status'] = array(
'text' => $converted["text"], 'text' => $converted["text"],
@ -1125,9 +1144,9 @@
$userlist = array(); $userlist = array();
if (isset($_GET["q"])) { if (isset($_GET["q"])) {
$r = q("SELECT id FROM unique_contacts WHERE name='%s'", dbesc($_GET["q"])); $r = q("SELECT id FROM `unique_contacts` WHERE `name`='%s'", dbesc($_GET["q"]));
if (!count($r)) if (!count($r))
$r = q("SELECT id FROM unique_contacts WHERE nick='%s'", dbesc($_GET["q"])); $r = q("SELECT `id` FROM `unique_contacts` WHERE `nick`='%s'", dbesc($_GET["q"]));
if (count($r)) { if (count($r)) {
foreach ($r AS $user) { foreach ($r AS $user) {
@ -2170,7 +2189,7 @@
intval(api_user()), intval(api_user()),
intval($in_reply_to_status_id)); intval($in_reply_to_status_id));
if ($r) { if ($r) {
$r = q("SELECT * FROM unique_contacts WHERE `url` = '%s'", dbesc(normalise_link($r[0]['author-link']))); $r = q("SELECT * FROM `unique_contacts` WHERE `url` = '%s'", dbesc(normalise_link($r[0]['author-link'])));
if ($r) { if ($r) {
if ($r[0]['nick'] == "") if ($r[0]['nick'] == "")
@ -2429,7 +2448,7 @@
$stringify_ids = (x($_REQUEST,'stringify_ids')?$_REQUEST['stringify_ids']:false); $stringify_ids = (x($_REQUEST,'stringify_ids')?$_REQUEST['stringify_ids']:false);
$r = q("SELECT unique_contacts.id FROM contact, unique_contacts WHERE contact.nurl = unique_contacts.url AND `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 $sql_extra", $r = q("SELECT `unique_contact`.`id` FROM contact, `unique_contacts` WHERE contact.nurl = unique_contacts.url AND `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 $sql_extra",
intval(api_user()) intval(api_user())
); );
@ -2831,15 +2850,29 @@ function api_share_as_retweet(&$item) {
function api_get_nick($profile) { function api_get_nick($profile) {
/* To-Do: /* To-Do:
- remove trailing jung from profile url - remove trailing junk from profile url
- pump.io check has to check the website - pump.io check has to check the website
*/ */
$nick = ""; $nick = "";
$r = q("SELECT `nick` FROM `gcontact` WHERE `nurl` = '%s'",
dbesc(normalise_link($profile)));
if ($r)
$nick = $r[0]["nick"];
if (!$nick == "") {
$r = q("SELECT `nick` FROM `contact` WHERE `uid` = 0 AND `nurl` = '%s'",
dbesc(normalise_link($profile)));
if ($r)
$nick = $r[0]["nick"];
}
if (!$nick == "") {
$friendica = preg_replace("=https?://(.*)/profile/(.*)=ism", "$2", $profile); $friendica = preg_replace("=https?://(.*)/profile/(.*)=ism", "$2", $profile);
if ($friendica != $profile) if ($friendica != $profile)
$nick = $friendica; $nick = $friendica;
}
if (!$nick == "") { if (!$nick == "") {
$diaspora = preg_replace("=https?://(.*)/u/(.*)=ism", "$2", $profile); $diaspora = preg_replace("=https?://(.*)/u/(.*)=ism", "$2", $profile);
@ -2877,8 +2910,8 @@ function api_get_nick($profile) {
//} //}
if ($nick != "") { if ($nick != "") {
q("UPDATE unique_contacts SET nick = '%s' WHERE url = '%s'", q("UPDATE `unique_contacts` SET `nick` = '%s' WHERE `nick` != '%s' AND url = '%s'",
dbesc($nick), dbesc(normalise_link($profile))); dbesc($nick), dbesc($nick), dbesc(normalise_link($profile)));
return($nick); return($nick);
} }

View file

@ -108,7 +108,7 @@ class exAuth
// ovdje provjeri je li korisnik OK // ovdje provjeri je li korisnik OK
$sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]); $sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]);
$this->writeDebugLog("[debug] checking isuser for ". $sUser); $this->writeDebugLog("[debug] checking isuser for ". $sUser);
$sQuery = "select * from user where nickname='". $db->escape($sUser) ."'"; $sQuery = "SELECT `uid` FROM `user` WHERE `nickname`='". $db->escape($sUser) ."'";
$this->writeDebugLog("[debug] using query ". $sQuery); $this->writeDebugLog("[debug] using query ". $sQuery);
if ($oResult = q($sQuery)){ if ($oResult = q($sQuery)){
if ($oResult) { if ($oResult) {
@ -120,7 +120,7 @@ class exAuth
$this->writeLog("[exAuth] invalid user: ". $sUser); $this->writeLog("[exAuth] invalid user: ". $sUser);
fwrite(STDOUT, pack("nn", 2, 0)); fwrite(STDOUT, pack("nn", 2, 0));
} }
$oResult->close(); //$oResult->close();
} else { } else {
$this->writeLog("[MySQL] invalid query: ". $sQuery); $this->writeLog("[MySQL] invalid query: ". $sQuery);
fwrite(STDOUT, pack("nn", 2, 0)); fwrite(STDOUT, pack("nn", 2, 0));
@ -136,10 +136,14 @@ class exAuth
// ovdje provjeri prijavu // ovdje provjeri prijavu
$sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]); $sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]);
$this->writeDebugLog("[debug] doing auth for ". $sUser); $this->writeDebugLog("[debug] doing auth for ". $sUser);
$sQuery = "select * from user where password='".hash('whirlpool',$aCommand[3])."' and nickname='". $db->escape($sUser) ."'"; //$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `password`='".hash('whirlpool',$aCommand[3])."' AND `nickname`='". $db->escape($sUser) ."'";
$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `nickname`='". $db->escape($sUser) ."'";
$this->writeDebugLog("[debug] using query ". $sQuery); $this->writeDebugLog("[debug] using query ". $sQuery);
if ($oResult = q($sQuery)){ if ($oResult = q($sQuery)){
if ($oResult) { $uid = $oResult[0]["uid"];
$Error = ($oResult[0]["password"] != hash('whirlpool',$aCommand[3]));
/*
if ($oResult[0]["password"] == hash('whirlpool',$aCommand[3])) {
// korisnik OK // korisnik OK
$this->writeLog("[exAuth] authentificated user ". $sUser ."@". $aCommand[2]); $this->writeLog("[exAuth] authentificated user ". $sUser ."@". $aCommand[2]);
fwrite(STDOUT, pack("nn", 2, 1)); fwrite(STDOUT, pack("nn", 2, 1));
@ -149,9 +153,24 @@ class exAuth
fwrite(STDOUT, pack("nn", 2, 0)); fwrite(STDOUT, pack("nn", 2, 0));
} }
$oResult->close(); $oResult->close();
*/
} else { } else {
$this->writeLog("[MySQL] invalid query: ". $sQuery); $this->writeLog("[MySQL] invalid query: ". $sQuery);
$Error = true;
$uid = -1;
}
if ($Error) {
$oConfig = q("SELECT `v` FROM `pconfig` WHERE `uid`=%d AND `cat` = 'xmpp' AND `k`='password' LIMIT 1;", intval($uid));
$this->writeLog("[exAuth] got password ".$oConfig[0]["v"]);
$Error = ($aCommand[3] != $oConfig[0]["v"]);
}
if ($Error) {
$this->writeLog("[exAuth] authentification failed for user ". $sUser ."@". $aCommand[2]);
fwrite(STDOUT, pack("nn", 2, 0)); fwrite(STDOUT, pack("nn", 2, 0));
} else {
$this->writeLog("[exAuth] authentificated user ". $sUser ."@". $aCommand[2]);
fwrite(STDOUT, pack("nn", 2, 1));
} }
} }
break; break;

View file

@ -83,7 +83,6 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
'return \'#\'. str_replace(\' \', \'_\', $match[2]);' 'return \'#\'. str_replace(\' \', \'_\', $match[2]);'
), $Text); ), $Text);
// Converting images with size parameters to simple images. Markdown doesn't know it. // Converting images with size parameters to simple images. Markdown doesn't know it.
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text); $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
@ -94,11 +93,12 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
// Add all tags that maybe were removed // Add all tags that maybe were removed
if (preg_match_all("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",$OriginalText, $tags)) { if (preg_match_all("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism",$OriginalText, $tags)) {
$tagline = ""; $tagline = "";
foreach($tags[2] as $tag) foreach($tags[2] as $tag) {
if (!strpos($Text, "#".$tag)) $tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8');
if (!strpos(html_entity_decode($Text, ENT_QUOTES, 'UTF-8'), "#".$tag))
$tagline .= "#".$tag." "; $tagline .= "#".$tag." ";
}
$Text = $Text."<br />".$tagline; $Text = $Text." ".$tagline;
} }
} else } else

View file

@ -2,7 +2,23 @@
require_once("include/oembed.php"); require_once("include/oembed.php");
require_once('include/event.php'); require_once('include/event.php');
require_once('include/map.php'); require_once('include/map.php');
require_once('mod/proxy.php');
function bb_PictureCacheExt($matches) {
if (strpos($matches[3], "data:image/") === 0)
return ($matches[0]);
$matches[3] = proxy_url($matches[3]);
return "[img=".$matches[1]."x".$matches[2]."]".$matches[3]."[/img]";
}
function bb_PictureCache($matches) {
if (strpos($matches[1], "data:image/") === 0)
return ($matches[0]);
$matches[1] = proxy_url($matches[1]);
return "[img]".$matches[1]."[/img]";
}
function bb_map_coords($match) { function bb_map_coords($match) {
// the extra space in the following line is intentional // the extra space in the following line is intentional
@ -83,10 +99,19 @@ function bb_attachment($Text, $simplehtml = false, $tryoembed = true) {
$image = ""; $image = "";
} }
if ($simplehtml == 7) if ($simplehtml == 7) {
$text = sprintf('<a href="%s" title="%s" class="attachment thumbnail" rel="nofollow external">%s</a>', $title2 = $title;
$url, $title, $title);
elseif (($simplehtml != 4) AND ($simplehtml != 0)) $test1 = trim(html_entity_decode($match[1],ENT_QUOTES,'UTF-8'));
$test2 = trim(html_entity_decode($title,ENT_QUOTES,'UTF-8'));
// If the link description is similar to the text above then don't add the link description
if (($title != "") AND ((strpos($test1,$test2) !== false) OR
(similar_text($test1,$test2) / strlen($title)) > 0.9))
$title2 = $url;
$text = sprintf('<a href="%s" title="%s" class="attachment thumbnail" rel="nofollow external">%s</a><br />',
$url, $title, $title2);
} elseif (($simplehtml != 4) AND ($simplehtml != 0))
$text = sprintf('<a href="%s" target="_blank">%s</a><br>', $url, $title); $text = sprintf('<a href="%s" target="_blank">%s</a><br>', $url, $title);
else { else {
$text = sprintf('<span class="type-%s">', $type); $text = sprintf('<span class="type-%s">', $type);
@ -101,9 +126,9 @@ function bb_attachment($Text, $simplehtml = false, $tryoembed = true) {
$text = $oembed; $text = $oembed;
else { else {
if (($image != "") AND !strstr(strtolower($oembed), "<img ")) if (($image != "") AND !strstr(strtolower($oembed), "<img "))
$text .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $url, $image, $title); $text .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-image" /></a><br />', $url, proxy_url($image), $title);
elseif (($preview != "") AND !strstr(strtolower($oembed), "<img ")) elseif (($preview != "") AND !strstr(strtolower($oembed), "<img "))
$text .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $url, $preview, $title); $text .= sprintf('<a href="%s" target="_blank"><img src="%s" alt="" title="%s" class="attachment-preview" /></a><br />', $url, proxy_url($preview), $title);
$text .= $oembed; $text .= $oembed;
@ -455,7 +480,7 @@ function bb_replace_images($body, $images) {
// We're depending on the property of 'foreach' (specified on the PHP website) that // We're depending on the property of 'foreach' (specified on the PHP website) that
// it loops over the array starting from the first element and going sequentially // it loops over the array starting from the first element and going sequentially
// to the last element // to the last element
$newbody = str_replace('[$#saved_image' . $cnt . '#$]', '<img src="' . $image .'" alt="' . t('Image/photo') . '" />', $newbody); $newbody = str_replace('[$#saved_image' . $cnt . '#$]', '<img src="' . proxy_url($image) .'" alt="' . t('Image/photo') . '" />', $newbody);
$cnt++; $cnt++;
} }
@ -585,7 +610,7 @@ function bb_ShareAttributes($share, $simplehtml) {
default: default:
$headline = trim($share[1]).'<div class="shared_header">'; $headline = trim($share[1]).'<div class="shared_header">';
if ($avatar != "") if ($avatar != "")
$headline .= '<img src="'.$avatar.'" height="32" width="32" >'; $headline .= '<img src="'.proxy_url($avatar, false, PROXY_SIZE_MICRO).'" height="32" width="32" >';
$headline .= sprintf(t('<span><a href="%s" target="_blank">%s</a> wrote the following <a href="%s" target="_blank">post</a>'.$reldate.':</span>'), $profile, $author, $link); $headline .= sprintf(t('<span><a href="%s" target="_blank">%s</a> wrote the following <a href="%s" target="_blank">post</a>'.$reldate.':</span>'), $profile, $author, $link);
$headline .= "</div>"; $headline .= "</div>";
@ -934,12 +959,14 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
$Text = preg_replace_callback("&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi", 'bb_DiasporaLinks', $Text); $Text = preg_replace_callback("&\[url=/posts/([^\[\]]*)\](.*)\[\/url\]&Usi", 'bb_DiasporaLinks', $Text);
// if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text // if the HTML is used to generate plain text, then don't do this search, but replace all URL of that kind to text
// if ($simplehtml != 7) {
if (!$forplaintext) if (!$forplaintext)
$Text = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" target="_blank">$2</a>', $Text); $Text = preg_replace("/([^\]\='".'"'."]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1<a href="$2" target="_blank">$2</a>', $Text);
else { else {
$Text = preg_replace("(\[url\]([$URLSearchString]*)\[\/url\])ism"," $1 ",$Text); $Text = preg_replace("(\[url\]([$URLSearchString]*)\[\/url\])ism"," $1 ",$Text);
$Text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'bb_RemovePictureLinks', $Text); $Text = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'bb_RemovePictureLinks', $Text);
} }
// }
if ($tryoembed) if ($tryoembed)
$Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism",'tryoembed',$Text); $Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism",'tryoembed',$Text);
@ -1102,13 +1129,17 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
"<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>", "<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>",
$Text); $Text);
// [img=widthxheight]image source[/img] // [img=widthxheight]image source[/img]
//$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="height: $2px; width: $1px;" >', $Text); $Text = preg_replace_callback("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", 'bb_PictureCacheExt', $Text);
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="width: $1px;" >', $Text); $Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="width: $1px;" >', $Text);
$Text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*)\](.*?)\[\/zmg\]/ism", '<img class="zrl" src="$3" style="width: $1px;" >', $Text); $Text = preg_replace("/\[zmg\=([0-9]*)x([0-9]*)\](.*?)\[\/zmg\]/ism", '<img class="zrl" src="$3" style="width: $1px;" >', $Text);
// Images // Images
// [img]pathtoimage[/img] // [img]pathtoimage[/img]
$Text = preg_replace_callback("/\[img\](.*?)\[\/img\]/ism", 'bb_PictureCache', $Text);
$Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text); $Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text);
$Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text); $Text = preg_replace("/\[zmg\](.*?)\[\/zmg\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text);
@ -1190,7 +1221,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// start which is always required). Allow desc with a missing summary for compatibility. // start which is always required). Allow desc with a missing summary for compatibility.
if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) { if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
$sub = format_event_html($ev); $sub = format_event_html($ev, $simplehtml);
$Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text); $Text = preg_replace("/\[event\-summary\](.*?)\[\/event\-summary\]/ism",'',$Text);
$Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text); $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",'',$Text);

View file

@ -88,7 +88,7 @@ function network_to_name($s, $profile = "") {
NETWORK_PUMPIO => t('pump.io'), NETWORK_PUMPIO => t('pump.io'),
NETWORK_TWITTER => t('Twitter'), NETWORK_TWITTER => t('Twitter'),
NETWORK_DIASPORA2 => t('Diaspora Connector'), NETWORK_DIASPORA2 => t('Diaspora Connector'),
NETWORK_STATUSNET => t('Statusnet'), NETWORK_STATUSNET => t('GNU Social'),
NETWORK_APPNET => t('App.net') NETWORK_APPNET => t('App.net')
); );

View file

@ -40,18 +40,55 @@ function findpeople_widget() {
} }
function unavailable_networks() {
$network_filter = "";
$networks = array();
if (!plugin_enabled("appnet"))
$networks[] = NETWORK_APPNET;
if (!plugin_enabled("fbpost") AND !plugin_enabled("facebook"))
$networks[] = NETWORK_FACEBOOK;
if (!plugin_enabled("statusnet"))
$networks[] = NETWORK_STATUSNET;
if (!plugin_enabled("pumpio"))
$networks[] = NETWORK_PUMPIO;
if (!plugin_enabled("twitter"))
$networks[] = NETWORK_TWITTER;
if (get_config("system","ostatus_disabled"))
$networks[] = NETWORK_OSTATUS;
if (!get_config("system","diaspora_enabled"))
$networks[] = NETWORK_DIASPORA;
if (!sizeof($networks))
return "";
$network_filter = implode("','", $networks);
$network_filter = "AND `network` NOT IN ('$network_filter')";
return $network_filter;
}
function networks_widget($baseurl,$selected = '') { function networks_widget($baseurl,$selected = '') {
$a = get_app(); $a = get_app();
if(! local_user()) if(!local_user())
return ''; return '';
if(! feature_enabled(local_user(),'networks')) if(!feature_enabled(local_user(),'networks'))
return ''; return '';
$r = q("SELECT DISTINCT(`network`) FROM `contact` WHERE `uid` = %d AND `self` = 0 ORDER BY `network`", $extra_sql = unavailable_networks();
$r = q("SELECT DISTINCT(`network`) FROM `contact` WHERE `uid` = %d AND NOT `self` $extra_sql ORDER BY `network`",
intval(local_user()) intval(local_user())
); );

View file

@ -100,7 +100,11 @@ function localize_item(&$item){
$item['body'] = item_redir_and_replace_images($extracted['body'], $extracted['images'], $item['contact-id']); $item['body'] = item_redir_and_replace_images($extracted['body'], $extracted['images'], $item['contact-id']);
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">"; $xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
if (activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE)){ if (activity_match($item['verb'],ACTIVITY_LIKE)
|| activity_match($item['verb'],ACTIVITY_DISLIKE)
|| activity_match($item['verb'],ACTIVITY_ATTEND)
|| activity_match($item['verb'],ACTIVITY_ATTENDNO)
|| activity_match($item['verb'],ACTIVITY_ATTENDMAYBE)){
$r = q("SELECT * from `item`,`contact` WHERE $r = q("SELECT * from `item`,`contact` WHERE
`item`.`contact-id`=`contact`.`id` AND `item`.`uri`='%s';", `item`.`contact-id`=`contact`.`id` AND `item`.`uri`='%s';",
@ -139,6 +143,15 @@ function localize_item(&$item){
elseif(activity_match($item['verb'],ACTIVITY_DISLIKE)) { elseif(activity_match($item['verb'],ACTIVITY_DISLIKE)) {
$bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
} }
elseif(activity_match($item['verb'],ACTIVITY_ATTEND)) {
$bodyverb = t('%1$s attends %2$s\'s %3$s');
}
elseif(activity_match($item['verb'],ACTIVITY_ATTENDNO)) {
$bodyverb = t('%1$s doesn\'t attend %2$s\'s %3$s');
}
elseif(activity_match($item['verb'],ACTIVITY_ATTENDMAYBE)) {
$bodyverb = t('%1$s attends maybe %2$s\'s %3$s');
}
$item['body'] = sprintf($bodyverb, $author, $objauthor, $plink); $item['body'] = sprintf($bodyverb, $author, $objauthor, $plink);
} }
@ -341,8 +354,15 @@ function count_descendants($item) {
function visible_activity($item) { function visible_activity($item) {
if(activity_match($item['verb'],ACTIVITY_LIKE) || activity_match($item['verb'],ACTIVITY_DISLIKE)) // likes (etc.) can apply to other things besides posts. Check if they are post children,
// in which case we handle them specially
$hidden_activities = array(ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE);
foreach($hidden_activities as $act) {
if(activity_match($item['verb'],$act)) {
return false; return false;
}
}
if(activity_match($item['verb'],ACTIVITY_FOLLOW) && $item['object-type'] === ACTIVITY_OBJ_NOTE) { if(activity_match($item['verb'],ACTIVITY_FOLLOW) && $item['object-type'] === ACTIVITY_OBJ_NOTE) {
if(! (($item['self']) && ($item['uid'] == local_user()))) { if(! (($item['self']) && ($item['uid'] == local_user()))) {
@ -484,8 +504,10 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
$cmnt_tpl = get_markup_template('comment_item.tpl'); $cmnt_tpl = get_markup_template('comment_item.tpl');
$hide_comments_tpl = get_markup_template('hide_comments.tpl'); $hide_comments_tpl = get_markup_template('hide_comments.tpl');
$alike = array(); $conv_responses = array(
$dlike = array(); 'like' => array('title' => t('Likes','title')), 'dislike' => array('title' => t('Dislikes','title')),
'attendyes' => array('title' => t('Attending','title')), 'attendno' => array('title' => t('Not attending','title')), 'attendmaybe' => array('title' => t('Might attend','title'))
);
// array with html for each thread (parent+comments) // array with html for each thread (parent+comments)
$threads = array(); $threads = array();
@ -656,7 +678,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
'name' => $profile_name_e, 'name' => $profile_name_e,
'sparkle' => $sparkle, 'sparkle' => $sparkle,
'lock' => $lock, 'lock' => $lock,
'thumb' => proxy_url($profile_avatar), 'thumb' => proxy_url($profile_avatar, false, PROXY_SIZE_THUMB),
'title' => $item['title_e'], 'title' => $item['title_e'],
'body' => $body_e, 'body' => $body_e,
'tags' => $tags_e, 'tags' => $tags_e,
@ -675,7 +697,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
'indent' => '', 'indent' => '',
'owner_name' => $owner_name_e, 'owner_name' => $owner_name_e,
'owner_url' => $owner_url, 'owner_url' => $owner_url,
'owner_photo' => proxy_url($owner_photo), 'owner_photo' => proxy_url($owner_photo, false, PROXY_SIZE_THUMB),
'plink' => get_plink($item), 'plink' => get_plink($item),
'edpost' => false, 'edpost' => false,
'isstarred' => $isstarred, 'isstarred' => $isstarred,
@ -734,8 +756,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
// Can we put this after the visibility check? // Can we put this after the visibility check?
like_puller($a,$item,$alike,'like'); builtin_activity_puller($item, $conv_responses);
like_puller($a,$item,$dlike,'dislike');
// Only add what is visible // Only add what is visible
if($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) { if($item['network'] === NETWORK_MAIL && local_user() != $item['uid']) {
@ -755,7 +776,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
} }
} }
$threads = $conv->get_template_data($alike, $dlike); $threads = $conv->get_template_data($conv_responses);
if(!$threads) { if(!$threads) {
logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG); logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG);
@ -792,10 +813,16 @@ function best_link_url($item,&$sparkle,$ssl_state = false) {
if($a->contacts[$clean_url]['network'] === NETWORK_DFRN) { if($a->contacts[$clean_url]['network'] === NETWORK_DFRN) {
$best_url = $a->get_baseurl($ssl_state) . '/redir/' . $a->contacts[$clean_url]['id']; $best_url = $a->get_baseurl($ssl_state) . '/redir/' . $a->contacts[$clean_url]['id'];
$sparkle = true; $sparkle = true;
} } else
else
$best_url = $a->contacts[$clean_url]['url']; $best_url = $a->contacts[$clean_url]['url'];
} }
} elseif (local_user()) {
$r = q("SELECT `id`, `network` FROM `contact` WHERE `network` = '%s' AND `uid` = %d AND `nurl` = '%s'",
dbesc(NETWORK_DFRN), intval(local_user()), dbesc(normalise_link($clean_url)));
if ($r) {
$best_url = $a->get_baseurl($ssl_state).'/redir/'.$r[0]['id'];
$sparkle = true;
}
} }
if(! $best_url) { if(! $best_url) {
if(strlen($item['author-link'])) if(strlen($item['author-link']))
@ -848,15 +875,23 @@ function item_photo_menu($item){
$profile_link = zrl($profile_link); $profile_link = zrl($profile_link);
if(local_user() && local_user() == $item['uid'] && link_compare($item['url'],$item['author-link'])) { if(local_user() && local_user() == $item['uid'] && link_compare($item['url'],$item['author-link'])) {
$cid = $item['contact-id']; $cid = $item['contact-id'];
} } else {
else { $r = q("SELECT `id`, `network` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' ORDER BY `uid` DESC LIMIT 1",
intval(local_user()), dbesc(normalise_link($item['author-link'])));
if ($r) {
$cid = $r[0]["id"];
if ($r[0]["network"] == NETWORK_DIASPORA)
$pm_url = $a->get_baseurl($ssl_state) . '/message/new/' . $cid;
} else
$cid = 0; $cid = 0;
} }
} }
if(($cid) && (! $item['self'])) { if(($cid) && (! $item['self'])) {
$poke_link = $a->get_baseurl($ssl_state) . '/poke/?f=&c=' . $cid; $poke_link = $a->get_baseurl($ssl_state) . '/poke/?f=&c=' . $cid;
$contact_url = $a->get_baseurl($ssl_state) . '/contacts/' . $cid; $contact_url = $a->get_baseurl($ssl_state) . '/contacts/' . $cid;
$posts_link = $a->get_baseurl($ssl_state) . '/network/0?nets=all&cid=' . $cid; $posts_link = $a->get_baseurl($ssl_state) . '/contacts/' . $cid . '/posts';
$clean_url = normalise_link($item['author-link']); $clean_url = normalise_link($item['author-link']);
@ -870,6 +905,7 @@ function item_photo_menu($item){
} }
if (local_user()) {
$menu = Array( $menu = Array(
t("Follow Thread") => $sub_link, t("Follow Thread") => $sub_link,
t("View Status") => $status_link, t("View Status") => $status_link,
@ -877,10 +913,17 @@ function item_photo_menu($item){
t("View Photos") => $photos_link, t("View Photos") => $photos_link,
t("Network Posts") => $posts_link, t("Network Posts") => $posts_link,
t("Edit Contact") => $contact_url, t("Edit Contact") => $contact_url,
t("Send PM") => $pm_url, t("Send PM") => $pm_url
t("Poke") => $poke_link
); );
if ($a->contacts[$clean_url]['network'] === NETWORK_DFRN)
$menu[t("Poke")] = $poke_link;
if ((($cid == 0) OR ($a->contacts[$clean_url]['rel'] == CONTACT_IS_FOLLOWER)) AND
in_array($item['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
$menu[t("Connect/Follow")] = $a->get_baseurl($ssl_state)."/follow?url=".urlencode($item['author-link']);
} else
$menu = array(t("View Profile") => $item['author-link']);
$args = array('item' => $item, 'menu' => $menu); $args = array('item' => $item, 'menu' => $menu);
@ -899,65 +942,114 @@ function item_photo_menu($item){
return $o; return $o;
}} }}
if(! function_exists('like_puller')) { /**
function like_puller($a,$item,&$arr,$mode) { * @brief Checks item to see if it is one of the builtin activities (like/dislike, event attendance, consensus items, etc.)
* Increments the count of each matching activity and adds a link to the author as needed.
*
* @param array $a (not used)
* @param array $item
* @param array &$conv_responses (already created with builtin activity structure)
* @return void
*/
if(! function_exists('builtin_activity_puller')) {
function builtin_activity_puller($item, &$conv_responses) {
foreach($conv_responses as $mode => $v) {
$url = ''; $url = '';
$sparkle = ''; $sparkle = '';
$verb = (($mode === 'like') ? ACTIVITY_LIKE : ACTIVITY_DISLIKE);
if((activity_match($item['verb'],$verb)) && ($item['id'] != $item['parent'])) { switch($mode) {
case 'like':
$verb = ACTIVITY_LIKE;
break;
case 'dislike':
$verb = ACTIVITY_DISLIKE;
break;
case 'attendyes':
$verb = ACTIVITY_ATTEND;
break;
case 'attendno':
$verb = ACTIVITY_ATTENDNO;
break;
case 'attendmaybe':
$verb = ACTIVITY_ATTENDMAYBE;
break;
default:
return;
break;
}
if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) {
$url = $item['author-link']; $url = $item['author-link'];
if((local_user()) && (local_user() == $item['uid']) && ($item['network'] === NETWORK_DFRN) && (! $item['self']) && (link_compare($item['author-link'],$item['url']))) { if((local_user()) && (local_user() == $item['uid']) && ($item['network'] === NETWORK_DFRN) && (! $item['self']) && (link_compare($item['author-link'],$item['url']))) {
$url = $a->get_baseurl(true) . '/redir/' . $item['contact-id']; $url = z_root(true) . '/redir/' . $item['contact-id'];
$sparkle = ' class="sparkle" '; $sparkle = ' class="sparkle" ';
} }
else else
$url = zrl($url); $url = zrl($url);
$url = '<a href="'. $url . '"'. $sparkle .'>' . htmlentities($item['author-name']) . '</a>';
if(! $item['thr-parent']) if(! $item['thr-parent'])
$item['thr-parent'] = $item['parent-uri']; $item['thr-parent'] = $item['parent-uri'];
if(! ((isset($arr[$item['thr-parent'] . '-l'])) && (is_array($arr[$item['thr-parent'] . '-l'])))) if(! ((isset($conv_responses[$mode][$item['thr-parent'] . '-l']))
$arr[$item['thr-parent'] . '-l'] = array(); && (is_array($conv_responses[$mode][$item['thr-parent'] . '-l']))))
if(! isset($arr[$item['thr-parent']])) $conv_responses[$mode][$item['thr-parent'] . '-l'] = array();
$arr[$item['thr-parent']] = 1;
// only list each unique author once
if(in_array($url,$conv_responses[$mode][$item['thr-parent'] . '-l']))
continue;
if(! isset($conv_responses[$mode][$item['thr-parent']]))
$conv_responses[$mode][$item['thr-parent']] = 1;
else else
$arr[$item['thr-parent']] ++; $conv_responses[$mode][$item['thr-parent']] ++;
$arr[$item['thr-parent'] . '-l'][] = '<a href="'. $url . '"'. $sparkle .'>' . $item['author-name'] . '</a>';
} $conv_responses[$mode][$item['thr-parent'] . '-l'][] = $url;
// there can only be one activity verb per item so if we found anything, we can stop looking
return; return;
}
}
}} }}
// Format the like/dislike text for a profile item // Format the vote text for a profile item
// $cnt = number of people who like/dislike the item // $cnt = number of people who vote the item
// $arr = array of pre-linked names of likers/dislikers // $arr = array of pre-linked names of likers/dislikers
// $type = one of 'like, 'dislike' // $type = one of 'like, 'dislike', 'attendyes', 'attendno', 'attendmaybe'
// $id = item id // $id = item id
// returns formatted text // returns formatted text
if(! function_exists('format_like')) { if(! function_exists('format_like')) {
function format_like($cnt,$arr,$type,$id) { function format_like($cnt,$arr,$type,$id) {
$o = ''; $o = '';
if($cnt == 1) $expanded = '';
$o .= (($type === 'like') ? sprintf( t('%s likes this.'), $arr[0]) : sprintf( t('%s doesn\'t like this.'), $arr[0])) . EOL ;
else { if($cnt == 1) {
$spanatts = "class=\"fakelink\" onclick=\"openClose('{$type}list-$id');\""; $likers = $arr[0];
// Phrase if there is only one liker. In other cases it will be uses for the expanded
// list which show all likers
switch($type) { switch($type) {
case 'like': case 'like' :
$phrase = sprintf( t('<span %1$s>%2$d people</span> like this'), $spanatts, $cnt); $phrase = sprintf( t('%s likes this.'), $likers);
break; break;
case 'dislike': case 'dislike' :
$phrase = sprintf( t('<span %1$s>%2$d people</span> don\'t like this'), $spanatts, $cnt); $phrase = sprintf( t('%s doesn\'t like this.'), $likers);
break;
case 'attendyes' :
$phrase = sprintf( t('%s attends.'), $likers);
break;
case 'attendno' :
$phrase = sprintf( t('%s doesn\'t attend.'), $likers);
break;
case 'attendmaybe' :
$phrase = sprintf( t('%s attends maybe.'), $likers);
break; break;
} }
$phrase .= EOL ; }
$o .= replace_macros(get_markup_template('voting_fakelink.tpl'), array(
'$phrase' => $phrase,
'$type' => $type,
'$id' => $id
));
if($cnt > 1) {
$total = count($arr); $total = count($arr);
if($total >= MAX_LIKERS) if($total >= MAX_LIKERS)
$arr = array_slice($arr, 0, MAX_LIKERS - 1); $arr = array_slice($arr, 0, MAX_LIKERS - 1);
@ -970,9 +1062,45 @@ function format_like($cnt,$arr,$type,$id) {
$str = implode(', ', $arr); $str = implode(', ', $arr);
$str .= sprintf( t(', and %d other people'), $total - MAX_LIKERS ); $str .= sprintf( t(', and %d other people'), $total - MAX_LIKERS );
} }
$str = (($type === 'like') ? sprintf( t('%s like this.'), $str) : sprintf( t('%s don\'t like this.'), $str));
$o .= "\t" . '<div class="wall-item-' . $type . '-expanded" id="' . $type . 'list-' . $id . '" style="display: none;" >' . $str . '</div>'; $likers = $str;
$spanatts = "class=\"fakelink\" onclick=\"openClose('{$type}list-$id');\"";
switch($type) {
case 'like':
$phrase = sprintf( t('<span %1$s>%2$d people</span> like this'), $spanatts, $cnt);
$explikers = sprintf( t('%s like this.'), $likers);
break;
case 'dislike':
$phrase = sprintf( t('<span %1$s>%2$d people</span> don\'t like this'), $spanatts, $cnt);
$explikers = sprintf( t('%s don\'t like this.'), $likers);
break;
case 'attendyes':
$phrase = sprintf( t('<span %1$s>%2$d people</span> attend'), $spanatts, $cnt);
$explikers = sprintf( t('%s attend.'), $likers);
break;
case 'attendno':
$phrase = sprintf( t('<span %1$s>%2$d people</span> don\'t attend'), $spanatts, $cnt);
$explikers = sprintf( t('%s don\'t attend.'), $likers);
break;
case 'attendmaybe':
$phrase = sprintf( t('<span %1$s>%2$d people</span> anttend maybe'), $spanatts, $cnt);
$explikers = sprintf( t('%s anttend maybe.'), $likers);
break;
} }
$expanded .= "\t" . '<div class="wall-item-' . $type . '-expanded" id="' . $type . 'list-' . $id . '" style="display: none;" >' . $explikers . EOL . '</div>';
}
$phrase .= EOL ;
$o .= replace_macros(get_markup_template('voting_fakelink.tpl'), array(
'$phrase' => $phrase,
'$type' => $type,
'$id' => $id
));
$o .= $expanded;
return $o; return $o;
}} }}
@ -1163,6 +1291,15 @@ function conv_sort($arr,$order) {
$parents = array(); $parents = array();
$children = array(); $children = array();
$newarr = array();
// This is a preparation for having two different items with the same uri in one thread
// This will otherwise lead to an endless loop.
foreach($arr as $x)
if (!isset($newarr[$x['uri']]))
$newarr[$x['uri']] = $x;
$arr = $newarr;
foreach($arr as $x) foreach($arr as $x)
if($x['id'] == $x['parent']) if($x['id'] == $x['parent'])
@ -1236,3 +1373,51 @@ function render_location_dummy($item) {
if ($item['coord'] != "") if ($item['coord'] != "")
return $item['coord']; return $item['coord'];
} }
function get_responses($conv_responses,$response_verbs,$ob,$item) {
$ret = array();
foreach($response_verbs as $v) {
$ret[$v] = array();
$ret[$v]['count'] = ((x($conv_responses[$v],$item['uri'])) ? $conv_responses[$v][$item['uri']] : '');
$ret[$v]['list'] = ((x($conv_responses[$v],$item['uri'])) ? $conv_responses[$v][$item['uri'] . '-l'] : '');
if(count($ret[$v]['list']) > MAX_LIKERS) {
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'
. (($ob) ? $ob->get_id() : $item['id']) . '"><b>' . t('View all') . '</b></a>');
}
else {
$ret[$v]['list_part'] = '';
}
$ret[$v]['button'] = get_response_button_text($v,$ret[$v]['count']);
$ret[$v]['title'] = $conv_responses[$v]['title'];
}
$count = 0;
foreach($ret as $key) {
if ($key['count'] == true)
$count++;
}
$ret['count'] = $count;
return $ret;
}
function get_response_button_text($v,$count) {
switch($v) {
case 'like':
return tt('Like','Likes',$count,'noun');
break;
case 'dislike':
return tt('Dislike','Dislikes',$count,'noun');
break;
case 'attendyes':
return tt('Attending','Attending',$count,'noun');
break;
case 'attendno':
return tt('Not Attending','Not Attending',$count,'noun');
break;
case 'attendmaybe':
return tt('Undecided','Undecided',$count,'noun');
break;
}
}

379
include/cron.php Normal file
View file

@ -0,0 +1,379 @@
<?php
if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
$directory = dirname($_SERVER["argv"][0]);
if (substr($directory, 0, 1) != "/")
$directory = $_SERVER["PWD"]."/".$directory;
$directory = realpath($directory."/..");
chdir($directory);
}
require_once("boot.php");
function cron_run(&$argv, &$argc){
global $a, $db;
if(is_null($a)) {
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("include/dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once('include/session.php');
require_once('include/datetime.php');
require_once('library/simplepie/simplepie.inc');
require_once('include/items.php');
require_once('include/Contact.php');
require_once('include/email.php');
require_once('include/socgraph.php');
require_once('include/pidfile.php');
require_once('mod/nodeinfo.php');
load_config('config');
load_config('system');
$maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1)
$maxsysload = 50;
$load = current_load();
if($load) {
if(intval($load) > $maxsysload) {
logger('system: load ' . $load . ' too high. cron deferred to next scheduled run.');
return;
}
}
$last = get_config('system','last_cron');
$poll_interval = intval(get_config('system','cron_interval'));
if(! $poll_interval)
$poll_interval = 10;
if($last) {
$next = $last + ($poll_interval * 60);
if($next > time()) {
logger('cron intervall not reached');
return;
}
}
$lockpath = get_lockpath();
if ($lockpath != '') {
$pidfile = new pidfile($lockpath, 'cron');
if($pidfile->is_already_running()) {
logger("cron: Already running");
if ($pidfile->running_time() > 9*60) {
$pidfile->kill();
logger("cron: killed stale process");
// Calling a new instance
proc_run('php','include/cron.php');
}
exit;
}
}
$a->set_baseurl(get_config('system','url'));
load_hooks();
logger('cron: start');
// run queue delivery process in the background
proc_run('php',"include/queue.php");
// run diaspora photo queue process in the background
proc_run('php',"include/dsprphotoq.php");
// run the process to discover global contacts in the background
proc_run('php',"include/discover_poco.php");
// run the process to update locally stored global contacts in the background
proc_run('php',"include/discover_poco.php", "checkcontact");
// expire any expired accounts
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` != '0000-00-00 00:00:00'
AND `account_expires_on` < UTC_TIMESTAMP() ");
// delete user and contact records for recently removed accounts
$r = q("SELECT * FROM `user` WHERE `account_removed` = 1 AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if ($r) {
foreach($r as $user) {
q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
}
}
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
// Check OStatus conversations
// Check only conversations with mentions (for a longer time)
check_conversations(true);
// Check every conversation
check_conversations(false);
// Follow your friends from your legacy OStatus account
// Doesn't work
// ostatus_check_follow_friends();
// update nodeinfo data
nodeinfo_cron();
// To-Do: Regenerate usage statistics
// q("ANALYZE TABLE `item`");
// once daily run birthday_updates and then expire in background
$d1 = get_config('system','last_expire_day');
$d2 = intval(datetime_convert('UTC','UTC','now','d'));
if($d2 != intval($d1)) {
update_contact_birthdays();
proc_run('php',"include/discover_poco.php", "suggestions");
set_config('system','last_expire_day',$d2);
proc_run('php','include/expire.php');
}
$last = get_config('system','cache_last_cleared');
if($last) {
$next = $last + (3600); // Once per hour
$clear_cache = ($next <= time());
} else
$clear_cache = true;
if ($clear_cache) {
// clear old cache
Cache::clear();
// clear old item cache files
clear_cache();
// clear cache for photos
clear_cache($a->get_basepath(), $a->get_basepath()."/photo");
// clear smarty cache
clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled");
// clear cache for image proxy
if (!get_config("system", "proxy_disabled")) {
clear_cache($a->get_basepath(), $a->get_basepath()."/proxy");
$cachetime = get_config('system','proxy_cache_time');
if (!$cachetime) $cachetime = PROXY_DEFAULT_TIME;
q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime);
}
// Maximum table size in megabyte
$max_tablesize = intval(get_config('system','optimize_max_tablesize')) * 1000000;
if ($max_tablesize == 0)
$max_tablesize = 100 * 1000000; // Default are 100 MB
// Minimum fragmentation level in percent
$fragmentation_level = intval(get_config('system','optimize_fragmentation')) / 100;
if ($fragmentation_level == 0)
$fragmentation_level = 0.3; // Default value is 30%
// Optimize some tables that need to be optimized
$r = q("SHOW TABLE STATUS");
foreach($r as $table) {
// Don't optimize tables that are too large
if ($table["Data_length"] > $max_tablesize)
continue;
// Don't optimize empty tables
if ($table["Data_length"] == 0)
continue;
// Calculate fragmentation
$fragmentation = $table["Data_free"] / $table["Data_length"];
logger("Table ".$table["Name"]." - Fragmentation level: ".round($fragmentation * 100, 2), LOGGER_DEBUG);
// Don't optimize tables that needn't to be optimized
if ($fragmentation < $fragmentation_level)
continue;
// So optimize it
logger("Optimize Table ".$table["Name"], LOGGER_DEBUG);
q("OPTIMIZE TABLE `%s`", dbesc($table["Name"]));
}
set_config('system','cache_last_cleared', time());
}
$manual_id = 0;
$generation = 0;
$force = false;
$restart = false;
if(($argc > 1) && ($argv[1] == 'force'))
$force = true;
if(($argc > 1) && ($argv[1] == 'restart')) {
$restart = true;
$generation = intval($argv[2]);
if(! $generation)
killme();
}
if(($argc > 1) && intval($argv[1])) {
$manual_id = intval($argv[1]);
$force = true;
}
$interval = intval(get_config('system','poll_interval'));
if(! $interval)
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
// If we are using the worker we don't need a delivery interval
if (get_config("system", "worker"))
$interval = false;
$sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
reload_plugins();
$d = datetime_convert();
// Only poll from those with suitable relationships,
// and which have a polling address and ignore Diaspora since
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
$abandon_sql = (($abandon_days)
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
: ''
);
$contacts = q("SELECT `contact`.`id` FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `rel` IN (%d, %d) AND `poll` != '' AND `network` IN ('%s', '%s', '%s', '%s', '%s', '%s')
$sql_extra
AND NOT `self` AND NOT `contact`.`blocked` AND NOT `contact`.`readonly` AND NOT `contact`.`archive`
AND NOT `user`.`account_expired` AND NOT `user`.`account_removed` $abandon_sql ORDER BY RAND()",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_ZOT),
dbesc(NETWORK_OSTATUS),
dbesc(NETWORK_FEED),
dbesc(NETWORK_MAIL),
dbesc(NETWORK_MAIL2)
);
if(! count($contacts)) {
return;
}
foreach($contacts as $c) {
$res = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($c['id'])
);
if((! $res) || (! count($res)))
continue;
foreach($res as $contact) {
$xml = false;
if($manual_id)
$contact['last-update'] = '0000-00-00 00:00:00';
if(in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS)))
$contact['priority'] = 2;
if($contact['subhub'] AND in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) {
// We should be getting everything via a hub. But just to be sure, let's check once a day.
// (You can make this more or less frequent if desired by setting 'pushpoll_frequency' appropriately)
// This also lets us update our subscription to the hub, and add or replace hubs in case it
// changed. We will only update hubs once a day, regardless of 'pushpoll_frequency'.
$poll_interval = get_config('system','pushpoll_frequency');
$contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3);
}
if($contact['priority'] AND !$force) {
$update = false;
$t = $contact['last-update'];
/**
* Based on $contact['priority'], should we poll this site now? Or later?
*/
switch ($contact['priority']) {
case 5:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 month"))
$update = true;
break;
case 4:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 week"))
$update = true;
break;
case 3:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
$update = true;
break;
case 2:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 12 hour"))
$update = true;
break;
case 1:
default:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 hour"))
$update = true;
break;
}
if(!$update)
continue;
}
logger("Polling ".$contact["network"]." ".$contact["id"]." ".$contact["nick"]." ".$contact["name"]);
proc_run('php','include/onepoll.php',$contact['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
logger('cron: end');
set_config('system','last_cron', time());
return;
}
if (array_search(__file__,get_included_files())===0){
cron_run($_SERVER["argv"],$_SERVER["argc"]);
killme();
}

View file

@ -27,10 +27,25 @@ function cronhooks_run(&$argv, &$argc){
$maxsysload = intval(get_config('system','maxloadavg')); $maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1) if($maxsysload < 1)
$maxsysload = 50; $maxsysload = 50;
if(function_exists('sys_getloadavg')) {
$load = sys_getloadavg(); $load = current_load();
if(intval($load[0]) > $maxsysload) { if($load) {
logger('system: load ' . $load[0] . ' too high. Cronhooks deferred to next scheduled run.'); if(intval($load) > $maxsysload) {
logger('system: load ' . $load . ' too high. Cronhooks deferred to next scheduled run.');
return;
}
}
$last = get_config('system','last_cronhook');
$poll_interval = intval(get_config('system','cronhook_interval'));
if(! $poll_interval)
$poll_interval = 9;
if($last) {
$next = $last + ($poll_interval * 60);
if($next > time()) {
logger('cronhook intervall not reached');
return; return;
} }
} }
@ -62,6 +77,8 @@ function cronhooks_run(&$argv, &$argc){
logger('cronhooks: end'); logger('cronhooks: end');
set_config('system','last_cronhook', time());
return; return;
} }

View file

@ -210,6 +210,18 @@ function timesel($format, $h, $m, $id='timepicker') {
if(! function_exists('datetimesel')) { if(! function_exists('datetimesel')) {
function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false) { function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false) {
$a = get_app();
// First day of the week (0 = Sunday)
$firstDay = get_pconfig(local_user(),'system','first_day_of_week');
if ($firstDay === false) $firstDay=0;
$lang = substr(get_browser_language(), 0, 2);
// Check if the detected language is supported by the picker
if (!in_array($lang, array("ar", "ro", "id", "bg", "fa", "ru", "uk", "en", "el", "de", "nl", "tr", "fr", "es", "th", "pl", "pt", "ch", "se", "kr", "it", "da", "no", "ja", "vi", "sl", "cs", "hu")))
$lang = ((isset($a->config['system']['language'])) ? $a->config['system']['language'] : 'en');
$o = ''; $o = '';
$dateformat = ''; $dateformat = '';
if($pickdate) $dateformat .= 'Y-m-d'; if($pickdate) $dateformat .= 'Y-m-d';
@ -224,6 +236,7 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
if(!$pickdate) $pickers .= ',datepicker: false'; if(!$pickdate) $pickers .= ',datepicker: false';
if(!$picktime) $pickers .= ',timepicker: false'; if(!$picktime) $pickers .= ',timepicker: false';
$extra_js = ''; $extra_js = '';
$pickers .= ",dayOfWeekStart: ".$firstDay.",lang:'".$lang."'";
if($minfrom != '') if($minfrom != '')
$extra_js .= "\$('#$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})"; $extra_js .= "\$('#$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})";
if($maxfrom != '') if($maxfrom != '')
@ -236,7 +249,9 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
$readable_format = str_replace('i','MM',$readable_format); $readable_format = str_replace('i','MM',$readable_format);
$o .= "<div class='date'><input type='text' placeholder='$readable_format' name='$id' id='$id' $input_text />"; $o .= "<div class='date'><input type='text' placeholder='$readable_format' name='$id' id='$id' $input_text />";
$o .= '</div>'; $o .= '</div>';
$o .= "<script type='text/javascript'>\$(function () {var picker = \$('#$id').datetimepicker({step:5,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs}); $extra_js})</script>"; $o .= "<script type='text/javascript'>";
$o .= "\$(function () {var picker = \$('#$id').datetimepicker({step:5,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs}); $extra_js})";
$o .= "</script>";
return $o; return $o;
}} }}

View file

@ -641,6 +641,7 @@ function db_definition() {
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""), "gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"community" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "community" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "network" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"addr" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"generation" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"), "generation" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"),
"server_url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "server_url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
), ),
@ -1381,6 +1382,20 @@ function db_definition() {
"username" => array("username"), "username" => array("username"),
) )
); );
$database["workerqueue"] = array(
"fields" => array(
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
"parameter" => array("type" => "text", "not null" => "1"),
"priority" => array("type" => "tinyint(3) unsigned", "not null" => "1", "default" => "0"),
"created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
"pid" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"executed" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"),
),
"indexes" => array(
"PRIMARY" => array("id"),
"created" => array("created"),
)
);
return($database); return($database);
} }

View file

@ -2,6 +2,7 @@
require_once("boot.php"); require_once("boot.php");
require_once('include/queue_fn.php'); require_once('include/queue_fn.php');
require_once('include/html2plain.php'); require_once('include/html2plain.php');
require_once("include/ostatus.php");
function delivery_run(&$argv, &$argc){ function delivery_run(&$argv, &$argc){
global $a, $db; global $a, $db;
@ -57,10 +58,11 @@ function delivery_run(&$argv, &$argc){
$maxsysload = intval(get_config('system','maxloadavg')); $maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1) if($maxsysload < 1)
$maxsysload = 50; $maxsysload = 50;
if(function_exists('sys_getloadavg')) {
$load = sys_getloadavg(); $load = current_load();
if(intval($load[0]) > $maxsysload) { if($load) {
logger('system: load ' . $load[0] . ' too high. Delivery deferred to next queue run.'); if(intval($load) > $maxsysload) {
logger('system: load ' . $load . ' too high. Delivery deferred to next queue run.');
return; return;
} }
} }
@ -340,9 +342,9 @@ function delivery_run(&$argv, &$argc){
$ssl_policy = get_config('system','ssl_policy'); $ssl_policy = get_config('system','ssl_policy');
fix_contact_ssl_policy($x[0],$ssl_policy); fix_contact_ssl_policy($x[0],$ssl_policy);
// If we are setup as a soapbox we aren't accepting input from this person // If we are setup as a soapbox we aren't accepting top level posts from this person
if($x[0]['page-flags'] == PAGE_SOAPBOX) if (($x[0]['page-flags'] == PAGE_SOAPBOX) AND $top_level)
break; break;
require_once('library/simplepie/simplepie.inc'); require_once('library/simplepie/simplepie.inc');
@ -391,7 +393,8 @@ function delivery_run(&$argv, &$argc){
continue; continue;
if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire)) if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
$slaps[] = atom_entry($item,'html',null,$owner,true); $slaps[] = ostatus_salmon($item,$owner);
//$slaps[] = atom_entry($item,'html',null,$owner,true);
} }
logger('notifier: slapdelivery: ' . $contact['name']); logger('notifier: slapdelivery: ' . $contact['name']);
@ -520,11 +523,16 @@ function delivery_run(&$argv, &$argc){
if((! $contact['pubkey']) && (! $public_message)) if((! $contact['pubkey']) && (! $public_message))
break; break;
if($target_item['verb'] === ACTIVITY_DISLIKE) { $unsupported_activities = array(ACTIVITY_DISLIKE, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE);
// unsupported
break; //don't transmit activities which are not supported by diaspora
foreach($unsupported_activities as $act) {
if(activity_match($target_item['verb'],$act)) {
break 2;
} }
elseif(($target_item['deleted']) && ($target_item['uri'] === $target_item['parent-uri'])) { }
if(($target_item['deleted']) && ($target_item['uri'] === $target_item['parent-uri'])) {
// top-level retraction // top-level retraction
logger('delivery: diaspora retract: ' . $loc); logger('delivery: diaspora retract: ' . $loc);

View file

@ -110,6 +110,9 @@ function diaspora_dispatch($importer,$msg,$attempt=1) {
elseif($xmlbase->message) { elseif($xmlbase->message) {
$ret = diaspora_message($importer,$xmlbase->message,$msg); $ret = diaspora_message($importer,$xmlbase->message,$msg);
} }
elseif($xmlbase->participation) {
$ret = diaspora_participation($importer,$xmlbase->participation);
}
else { else {
logger('diaspora_dispatch: unknown message type: ' . print_r($xmlbase,true)); logger('diaspora_dispatch: unknown message type: ' . print_r($xmlbase,true));
} }
@ -589,7 +592,7 @@ function diaspora_request($importer,$xml) {
// perhaps we were already sharing with this person. Now they're sharing with us. // perhaps we were already sharing with this person. Now they're sharing with us.
// That makes us friends. // That makes us friends.
if($contact['rel'] == CONTACT_IS_FOLLOWER && !in_array($importer['page-flags'], array(PAGE_COMMUNITY, PAGE_SOAPBOX))) { if($contact['rel'] == CONTACT_IS_FOLLOWER && in_array($importer['page-flags'], array(PAGE_FREELOVE))) {
q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d", q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d",
intval(CONTACT_IS_FRIEND), intval(CONTACT_IS_FRIEND),
intval($contact['id']), intval($contact['id']),
@ -771,7 +774,7 @@ function diaspora_post_allow($importer,$contact, $is_comment = false) {
// perhaps we were already sharing with this person. Now they're sharing with us. // perhaps we were already sharing with this person. Now they're sharing with us.
// That makes us friends. // That makes us friends.
// Normally this should have handled by getting a request - but this could get lost // Normally this should have handled by getting a request - but this could get lost
if($contact['rel'] == CONTACT_IS_FOLLOWER && !in_array($importer['page-flags'], array(PAGE_COMMUNITY, PAGE_SOAPBOX))) { if($contact['rel'] == CONTACT_IS_FOLLOWER && in_array($importer['page-flags'], array(PAGE_FREELOVE))) {
q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d", q("UPDATE `contact` SET `rel` = %d, `writable` = 1 WHERE `id` = %d AND `uid` = %d",
intval(CONTACT_IS_FRIEND), intval(CONTACT_IS_FRIEND),
intval($contact['id']), intval($contact['id']),
@ -1383,11 +1386,6 @@ function diaspora_asphoto($importer,$xml,$msg) {
} }
function diaspora_comment($importer,$xml,$msg) { function diaspora_comment($importer,$xml,$msg) {
$a = get_app(); $a = get_app();
@ -1507,16 +1505,27 @@ function diaspora_comment($importer,$xml,$msg) {
} }
} }
// Fetch the contact id - if we know this contact
$r = q("SELECT `id`, `network` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1",
dbesc(normalise_link($person['url'])), intval($importer['uid']));
if ($r) {
$cid = $r[0]['id'];
$network = $r[0]['network'];
} else {
$cid = $contact['id'];
$network = NETWORK_DIASPORA;
}
$body = diaspora2bb($text); $body = diaspora2bb($text);
$message_id = $diaspora_handle . ':' . $guid; $message_id = $diaspora_handle . ':' . $guid;
$datarray = array(); $datarray = array();
$datarray['uid'] = $importer['uid']; $datarray['uid'] = $importer['uid'];
$datarray['contact-id'] = $contact['id']; $datarray['contact-id'] = $cid;
$datarray['type'] = 'remote-comment'; $datarray['type'] = 'remote-comment';
$datarray['wall'] = $parent_item['wall']; $datarray['wall'] = $parent_item['wall'];
$datarray['network'] = NETWORK_DIASPORA; $datarray['network'] = $network;
$datarray['verb'] = ACTIVITY_POST; $datarray['verb'] = ACTIVITY_POST;
$datarray['gravity'] = GRAVITY_COMMENT; $datarray['gravity'] = GRAVITY_COMMENT;
$datarray['guid'] = $guid; $datarray['guid'] = $guid;
@ -1881,6 +1890,9 @@ function diaspora_message($importer,$xml,$msg) {
return; return;
} }
function diaspora_participation($importer,$xml) {
logger("Unsupported message type 'participation' ".print_r($xml, true));
}
function diaspora_photo($importer,$xml,$msg,$attempt=1) { function diaspora_photo($importer,$xml,$msg,$attempt=1) {
@ -2149,13 +2161,24 @@ function diaspora_like($importer,$xml,$msg) {
EOT; EOT;
$bodyverb = t('%1$s likes %2$s\'s %3$s'); $bodyverb = t('%1$s likes %2$s\'s %3$s');
// Fetch the contact id - if we know this contact
$r = q("SELECT `id`, `network` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1",
dbesc(normalise_link($person['url'])), intval($importer['uid']));
if ($r) {
$cid = $r[0]['id'];
$network = $r[0]['network'];
} else {
$cid = $contact['id'];
$network = NETWORK_DIASPORA;
}
$arr = array(); $arr = array();
$arr['uri'] = $uri; $arr['uri'] = $uri;
$arr['uid'] = $importer['uid']; $arr['uid'] = $importer['uid'];
$arr['guid'] = $guid; $arr['guid'] = $guid;
$arr['network'] = NETWORK_DIASPORA; $arr['network'] = $network;
$arr['contact-id'] = $contact['id']; $arr['contact-id'] = $cid;
$arr['type'] = 'activity'; $arr['type'] = 'activity';
$arr['wall'] = $parent_item['wall']; $arr['wall'] = $parent_item['wall'];
$arr['gravity'] = GRAVITY_LIKE; $arr['gravity'] = GRAVITY_LIKE;
@ -2231,8 +2254,23 @@ function diaspora_retraction($importer,$xml) {
if($type === 'Person') { if($type === 'Person') {
require_once('include/Contact.php'); require_once('include/Contact.php');
contact_remove($contact['id']); contact_remove($contact['id']);
} elseif($type === 'StatusMessage') {
$guid = notags(unxmlify($xml->post_guid));
$r = q("SELECT * FROM `item` WHERE `guid` = '%s' AND `uid` = %d AND NOT `file` LIKE '%%[%%' LIMIT 1",
dbesc($guid),
intval($importer['uid'])
);
if(count($r)) {
if(link_compare($r[0]['author-link'],$contact['url'])) {
q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d",
dbesc(datetime_convert()),
intval($r[0]['id'])
);
delete_thread($r[0]['id'], $r[0]['parent-uri']);
} }
elseif($type === 'Post') { }
} elseif($type === 'Post') {
$r = q("select * from item where guid = '%s' and uid = %d and not file like '%%[%%' limit 1", $r = q("select * from item where guid = '%s' and uid = %d and not file like '%%[%%' limit 1",
dbesc('guid'), dbesc('guid'),
intval($importer['uid']) intval($importer['uid'])
@ -2415,6 +2453,7 @@ function diaspora_profile($importer,$xml,$msg) {
$birthday = str_replace('1000','1901',$birthday); $birthday = str_replace('1000','1901',$birthday);
if ($birthday != "")
$birthday = datetime_convert('UTC','UTC',$birthday,'Y-m-d'); $birthday = datetime_convert('UTC','UTC',$birthday,'Y-m-d');
// this is to prevent multiple birthday notifications in a single year // this is to prevent multiple birthday notifications in a single year

View file

@ -28,10 +28,11 @@ function discover_poco_run(&$argv, &$argc){
$maxsysload = intval(get_config('system','maxloadavg')); $maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1) if($maxsysload < 1)
$maxsysload = 50; $maxsysload = 50;
if(function_exists('sys_getloadavg')) {
$load = sys_getloadavg(); $load = current_load();
if(intval($load[0]) > $maxsysload) { if($load) {
logger('system: load ' . $load[0] . ' too high. discover_poco deferred to next scheduled run.'); if(intval($load) > $maxsysload) {
logger('system: load ' . $load . ' too high. discover_poco deferred to next scheduled run.');
return; return;
} }
} }
@ -41,6 +42,8 @@ function discover_poco_run(&$argv, &$argc){
$mode = 1; $mode = 1;
} elseif(($argc == 2) && ($argv[1] == "checkcontact")) { } elseif(($argc == 2) && ($argv[1] == "checkcontact")) {
$mode = 2; $mode = 2;
} elseif(($argc == 2) && ($argv[1] == "suggestions")) {
$mode = 3;
} elseif ($argc == 1) { } elseif ($argc == 1) {
$search = ""; $search = "";
$mode = 0; $mode = 0;
@ -69,7 +72,9 @@ function discover_poco_run(&$argv, &$argc){
logger('start '.$search); logger('start '.$search);
if (($mode == 2) AND get_config('system','poco_completion')) if ($mode==3)
update_suggestions();
elseif (($mode == 2) AND get_config('system','poco_completion'))
discover_users(); discover_users();
elseif (($mode == 1) AND ($search != "") and get_config('system','poco_local_search')) elseif (($mode == 1) AND ($search != "") and get_config('system','poco_local_search'))
discover_directory($search); discover_directory($search);

View file

@ -20,7 +20,11 @@ function notification($params) {
$siteurl = $a->get_baseurl(true); $siteurl = $a->get_baseurl(true);
$thanks = t('Thank You,'); $thanks = t('Thank You,');
$sitename = $a->config['sitename']; $sitename = $a->config['sitename'];
if (!x($a->config['admin_name'])) {
$site_admin = sprintf( t('%s Administrator'), $sitename); $site_admin = sprintf( t('%s Administrator'), $sitename);
} else {
$site_admin = sprintf( t('%1$s, %2$s Administrator'), $a->config['admin_name'], $sitename);
}
$nickname = ""; $nickname = "";
$sender_name = $sitename; $sender_name = $sitename;

View file

@ -3,7 +3,7 @@
require_once('include/bbcode.php'); require_once('include/bbcode.php');
require_once('include/map.php'); require_once('include/map.php');
function format_event_html($ev) { function format_event_html($ev, $simple = false) {
@ -12,6 +12,32 @@ function format_event_html($ev) {
$bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM $bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM
$event_start = (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
$ev['start'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format)));
$event_end = (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
$ev['finish'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format )));
if ($simple) {
$o = "<h3>".bbcode($ev['summary'])."</h3>";
$o .= "<p>".bbcode($ev['desc'])."</p>";
$o .= "<h4>".t('Starts:')."</h4><p>".$event_start."</p>";
if(! $ev['nofinish'])
$o .= "<h4>".t('Finishes:')."</h4><p>".$event_end."</p>";
if(strlen($ev['location']))
$o .= "<h4>".t('Location:')."</h4><p>".$ev['location']."</p>";
return $o;
}
$o = '<div class="vevent">' . "\r\n"; $o = '<div class="vevent">' . "\r\n";
@ -21,21 +47,13 @@ function format_event_html($ev) {
$o .= '<p class="event-start">' . t('Starts:') . ' <abbr class="dtstart" title="' $o .= '<p class="event-start">' . t('Starts:') . ' <abbr class="dtstart" title="'
. datetime_convert('UTC','UTC',$ev['start'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )) . datetime_convert('UTC','UTC',$ev['start'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
. '" >' . '" >'.$event_start
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
$ev['start'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format)))
. '</abbr></p>' . "\r\n"; . '</abbr></p>' . "\r\n";
if(! $ev['nofinish']) if(! $ev['nofinish'])
$o .= '<p class="event-end" >' . t('Finishes:') . ' <abbr class="dtend" title="' $o .= '<p class="event-end" >' . t('Finishes:') . ' <abbr class="dtend" title="'
. datetime_convert('UTC','UTC',$ev['finish'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' )) . datetime_convert('UTC','UTC',$ev['finish'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
. '" >' . '" >'.$event_end
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
$ev['finish'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format )))
. '</abbr></p>' . "\r\n"; . '</abbr></p>' . "\r\n";
if(strlen($ev['location'])){ if(strlen($ev['location'])){
@ -204,7 +222,13 @@ function ev_compare($a,$b) {
return strcmp($date_a,$date_b); return strcmp($date_a,$date_b);
} }
function event_delete($event_id) {
if ($event_id == 0)
return;
q("DELETE FROM `event` WHERE `id` = %d", intval($event_id));
logger("Deleted event ".$event_id, LOGGER_DEBUG);
}
function event_store($arr) { function event_store($arr) {
@ -362,6 +386,7 @@ function event_store($arr) {
$item_arr['contact-id'] = $arr['cid']; $item_arr['contact-id'] = $arr['cid'];
$item_arr['uri'] = $arr['uri']; $item_arr['uri'] = $arr['uri'];
$item_arr['parent-uri'] = $arr['uri']; $item_arr['parent-uri'] = $arr['uri'];
$item_arr['guid'] = $arr['guid'];
$item_arr['type'] = 'activity'; $item_arr['type'] = 'activity';
$item_arr['wall'] = (($arr['cid']) ? 0 : 1); $item_arr['wall'] = (($arr['cid']) ? 0 : 1);
$item_arr['contact-id'] = $contact['id']; $item_arr['contact-id'] = $contact['id'];

View file

@ -1,19 +1,54 @@
<?php <?php
/* /**
* Features management * @file include/features.php *
* @brief Features management
*/ */
/**
* @brief check if feature is enabled
*
* return boolean
*/
function feature_enabled($uid,$feature) { function feature_enabled($uid,$feature) {
//return true; //return true;
$x = get_pconfig($uid,'feature',$feature); $x = get_pconfig($uid,'feature',$feature);
if($x === false) {
$x = get_config('feature',$feature);
if($x === false)
$x = get_feature_default($feature);
}
$arr = array('uid' => $uid, 'feature' => $feature, 'enabled' => $x); $arr = array('uid' => $uid, 'feature' => $feature, 'enabled' => $x);
call_hooks('feature_enabled',$arr); call_hooks('feature_enabled',$arr);
return($arr['enabled']); return($arr['enabled']);
} }
/**
* @brief check if feature is enabled or disabled by default
*
* @param string $feature
* @return boolean
*/
function get_feature_default($feature) {
$f = get_features();
foreach($f as $cat) {
foreach($cat as $feat) {
if(is_array($feat) && $feat[0] === $feature)
return $feat[3];
}
}
return false;
}
/**
* @ brief get a list of all available features
* The array includes the setting group, the setting name,
* explainations for the setting and if it's enabled or disabled
* by default
*
* @return array
*/
function get_features() { function get_features() {
$arr = array( $arr = array(
@ -22,45 +57,53 @@ function get_features() {
'general' => array( 'general' => array(
t('General Features'), t('General Features'),
//array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')), //array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')),
array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles')), array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'),false),
array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'),false),
), ),
// Post composition // Post composition
'composition' => array( 'composition' => array(
t('Post Composition Features'), t('Post Composition Features'),
array('richtext', t('Richtext Editor'), t('Enable richtext editor')), array('richtext', t('Richtext Editor'), t('Enable richtext editor'),false),
array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them')), array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them'),false),
array('aclautomention', t('Auto-mention Forums'), t('Add/remove mention when a fourm page is selected/deselected in ACL window.')), array('aclautomention', t('Auto-mention Forums'), t('Add/remove mention when a fourm page is selected/deselected in ACL window.'),false),
), ),
// Network sidebar widgets // Network sidebar widgets
'widgets' => array( 'widgets' => array(
t('Network Sidebar Widgets'), t('Network Sidebar Widgets'),
array('archives', t('Search by Date'), t('Ability to select posts by date ranges')), array('archives', t('Search by Date'), t('Ability to select posts by date ranges'),false),
array('groups', t('Group Filter'), t('Enable widget to display Network posts only from selected group')), array('forumlist_widget', t('List Forums'), t('Enable widget to display the forums your are connected with'),true),
array('networks', t('Network Filter'), t('Enable widget to display Network posts only from selected network')), array('groups', t('Group Filter'), t('Enable widget to display Network posts only from selected group'),false),
array('savedsearch', t('Saved Searches'), t('Save search terms for re-use')), array('networks', t('Network Filter'), t('Enable widget to display Network posts only from selected network'),false),
array('savedsearch', t('Saved Searches'), t('Save search terms for re-use'),false),
), ),
// Network tabs // Network tabs
'net_tabs' => array( 'net_tabs' => array(
t('Network Tabs'), t('Network Tabs'),
array('personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on')), array('personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on'),false),
array('new_tab', t('Network New Tab'), t('Enable tab to display only new Network posts (from the last 12 hours)')), array('new_tab', t('Network New Tab'), t('Enable tab to display only new Network posts (from the last 12 hours)'),false),
array('link_tab', t('Network Shared Links Tab'), t('Enable tab to display only Network posts with links in them')), array('link_tab', t('Network Shared Links Tab'), t('Enable tab to display only Network posts with links in them'),false),
), ),
// Item tools // Item tools
'tools' => array( 'tools' => array(
t('Post/Comment Tools'), t('Post/Comment Tools'),
array('multi_delete', t('Multiple Deletion'), t('Select and delete multiple posts/comments at once')), array('multi_delete', t('Multiple Deletion'), t('Select and delete multiple posts/comments at once'),false),
array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending')), array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending'),false),
array('commtag', t('Tagging'), t('Ability to tag existing posts')), array('commtag', t('Tagging'), t('Ability to tag existing posts'),false),
array('categories', t('Post Categories'), t('Add categories to your posts')), array('categories', t('Post Categories'), t('Add categories to your posts'),false),
array('filing', t('Saved Folders'), t('Ability to file posts under folders')), array('filing', t('Saved Folders'), t('Ability to file posts under folders'),false),
array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments')), array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments')),
array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator')), array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator'),false),
array('ignore_posts', t('Mute Post Notifications'), t('Ability to mute notifications for a thread')), array('ignore_posts', t('Mute Post Notifications'), t('Ability to mute notifications for a thread'),false),
),
// Advanced Profile Settings
'advanced_profile' => array(
t('Advanced Profile Settings'),
array('forumlist_profile', t('List Forums'), t('Show visitors public community forums at the Advanced Profile Page'),false),
), ),
); );

285
include/feed.php Normal file
View file

@ -0,0 +1,285 @@
<?php
require_once("include/html2bbcode.php");
require_once("include/items.php");
function feed_import($xml,$importer,&$contact, &$hub) {
$a = get_app();
logger("Import Atom/RSS feed", LOGGER_DEBUG);
if ($xml == "")
return;
$doc = new DOMDocument();
@$doc->loadXML($xml);
$xpath = new DomXPath($doc);
$xpath->registerNamespace('atom', "http://www.w3.org/2005/Atom");
$xpath->registerNamespace('dc', "http://purl.org/dc/elements/1.1/");
$xpath->registerNamespace('content', "http://purl.org/rss/1.0/modules/content/");
$xpath->registerNamespace('rdf', "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
$xpath->registerNamespace('rss', "http://purl.org/rss/1.0/");
$xpath->registerNamespace('media', "http://search.yahoo.com/mrss/");
$author = array();
// Is it RDF?
if ($xpath->query('/rdf:RDF/rss:channel')->length > 0) {
//$author["author-link"] = $xpath->evaluate('/rdf:RDF/rss:channel/rss:link/text()')->item(0)->nodeValue;
$author["author-name"] = $xpath->evaluate('/rdf:RDF/rss:channel/rss:title/text()')->item(0)->nodeValue;
if ($author["author-name"] == "")
$author["author-name"] = $xpath->evaluate('/rdf:RDF/rss:channel/rss:description/text()')->item(0)->nodeValue;
$entries = $xpath->query('/rdf:RDF/rss:item');
}
// Is it Atom?
if ($xpath->query('/atom:feed/atom:entry')->length > 0) {
//$self = $xpath->query("/atom:feed/atom:link[@rel='self']")->item(0)->attributes;
//if (is_object($self))
// foreach($self AS $attributes)
// if ($attributes->name == "href")
// $author["author-link"] = $attributes->textContent;
//if ($author["author-link"] == "") {
// $alternate = $xpath->query("/atom:feed/atom:link[@rel='alternate']")->item(0)->attributes;
// if (is_object($alternate))
// foreach($alternate AS $attributes)
// if ($attributes->name == "href")
// $author["author-link"] = $attributes->textContent;
//}
$author["author-name"] = $xpath->evaluate('/atom:feed/atom:title/text()')->item(0)->nodeValue;
if ($author["author-name"] == "")
$author["author-name"] = $xpath->evaluate('/atom:feed/atom:subtitle/text()')->item(0)->nodeValue;
if ($author["author-name"] == "")
$author["author-name"] = $xpath->evaluate('/atom:feed/atom:author/atom:name/text()')->item(0)->nodeValue;
//$author["author-avatar"] = $xpath->evaluate('/atom:feed/atom:logo/text()')->item(0)->nodeValue;
$author["edited"] = $author["created"] = $xpath->query('/atom:feed/atom:updated/text()')->item(0)->nodeValue;
$author["app"] = $xpath->evaluate('/atom:feed/atom:generator/text()')->item(0)->nodeValue;
$entries = $xpath->query('/atom:feed/atom:entry');
}
// Is it RSS?
if ($xpath->query('/rss/channel')->length > 0) {
//$author["author-link"] = $xpath->evaluate('/rss/channel/link/text()')->item(0)->nodeValue;
$author["author-name"] = $xpath->evaluate('/rss/channel/title/text()')->item(0)->nodeValue;
//$author["author-avatar"] = $xpath->evaluate('/rss/channel/image/url/text()')->item(0)->nodeValue;
if ($author["author-name"] == "")
$author["author-name"] = $xpath->evaluate('/rss/channel/copyright/text()')->item(0)->nodeValue;
if ($author["author-name"] == "")
$author["author-name"] = $xpath->evaluate('/rss/channel/description/text()')->item(0)->nodeValue;
$author["edited"] = $author["created"] = $xpath->query('/rss/channel/pubDate/text()')->item(0)->nodeValue;
$author["app"] = $xpath->evaluate('/rss/channel/generator/text()')->item(0)->nodeValue;
$entries = $xpath->query('/rss/channel/item');
}
//if ($author["author-link"] == "")
$author["author-link"] = $contact["url"];
if ($author["author-name"] == "")
$author["author-name"] = $contact["name"];
//if ($author["author-avatar"] == "")
$author["author-avatar"] = $contact["thumb"];
$author["owner-link"] = $contact["url"];
$author["owner-name"] = $contact["name"];
$author["owner-avatar"] = $contact["thumb"];
$header = array();
$header["uid"] = $importer["uid"];
$header["network"] = NETWORK_FEED;
$header["type"] = "remote";
$header["wall"] = 0;
$header["origin"] = 0;
$header["gravity"] = GRAVITY_PARENT;
$header["private"] = 2;
$header["verb"] = ACTIVITY_POST;
$header["object-type"] = ACTIVITY_OBJ_NOTE;
$header["contact-id"] = $contact["id"];
if(!strlen($contact["notify"])) {
// one way feed - no remote comment ability
$header["last-child"] = 0;
}
if (!is_object($entries))
return;
$entrylist = array();
foreach ($entries AS $entry)
$entrylist[] = $entry;
foreach (array_reverse($entrylist) AS $entry) {
$item = array_merge($header, $author);
$item["title"] = $xpath->evaluate('atom:title/text()', $entry)->item(0)->nodeValue;
if ($item["title"] == "")
$item["title"] = $xpath->evaluate('title/text()', $entry)->item(0)->nodeValue;
if ($item["title"] == "")
$item["title"] = $xpath->evaluate('rss:title/text()', $entry)->item(0)->nodeValue;
$alternate = $xpath->query("atom:link[@rel='alternate']", $entry)->item(0)->attributes;
if (!is_object($alternate))
$alternate = $xpath->query("atom:link", $entry)->item(0)->attributes;
if (is_object($alternate))
foreach($alternate AS $attributes)
if ($attributes->name == "href")
$item["plink"] = $attributes->textContent;
if ($item["plink"] == "")
$item["plink"] = $xpath->evaluate('link/text()', $entry)->item(0)->nodeValue;
if ($item["plink"] == "")
$item["plink"] = $xpath->evaluate('rss:link/text()', $entry)->item(0)->nodeValue;
$item["plink"] = original_url($item["plink"]);
$item["uri"] = $xpath->evaluate('atom:id/text()', $entry)->item(0)->nodeValue;
if ($item["uri"] == "")
$item["uri"] = $xpath->evaluate('guid/text()', $entry)->item(0)->nodeValue;
if ($item["uri"] == "")
$item["uri"] = $item["plink"];
$item["parent-uri"] = $item["uri"];
$published = $xpath->query('atom:published/text()', $entry)->item(0)->nodeValue;
if ($published == "")
$published = $xpath->query('pubDate/text()', $entry)->item(0)->nodeValue;
if ($published == "")
$published = $xpath->query('dc:date/text()', $entry)->item(0)->nodeValue;
$updated = $xpath->query('atom:updated/text()', $entry)->item(0)->nodeValue;
if ($updated == "")
$updated = $published;
if ($published != "")
$item["created"] = $published;
if ($updated != "")
$item["edited"] = $updated;
$creator = $xpath->query('author/text()', $entry)->item(0)->nodeValue;
if ($creator == "")
$creator = $xpath->query('atom:author/atom:name/text()', $entry)->item(0)->nodeValue;
if ($creator == "")
$creator = $xpath->query('dc:creator/text()', $entry)->item(0)->nodeValue;
if ($creator != "")
$item["author-name"] = $creator;
if ($pubDate != "")
$item["edited"] = $item["created"] = $pubDate;
$creator = $xpath->query('dc:creator/text()', $entry)->item(0)->nodeValue;
if ($creator != "")
$item["author-name"] = $creator;
//$item["object"] = $xml;
$r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `uri` = '%s' AND `network` IN ('%s', '%s')",
intval($importer["uid"]), dbesc($item["uri"]), dbesc(NETWORK_FEED), dbesc(NETWORK_DFRN));
if ($r) {
logger("Item with uri ".$item["uri"]." for user ".$importer["uid"]." already existed under id ".$r[0]["id"], LOGGER_DEBUG);
continue;
}
// To-Do?
// <category>Ausland</category>
// <media:thumbnail width="152" height="76" url="http://www.taz.de/picture/667875/192/14388767.jpg"/>
$attachments = array();
$enclosures = $xpath->query("enclosure", $entry);
foreach ($enclosures AS $enclosure) {
$href = "";
$length = "";
$type = "";
$title = "";
foreach($enclosure->attributes AS $attributes) {
if ($attributes->name == "url")
$href = $attributes->textContent;
elseif ($attributes->name == "length")
$length = $attributes->textContent;
elseif ($attributes->name == "type")
$type = $attributes->textContent;
}
if(strlen($item["attach"]))
$item["attach"] .= ',';
$attachments[] = array("link" => $href, "type" => $type, "length" => $length);
$item["attach"] .= '[attach]href="'.$href.'" length="'.$length.'" type="'.$type.'"[/attach]';
}
if ($contact["fetch_further_information"]) {
$preview = "";
// Handle enclosures and treat them as preview picture
foreach ($attachments AS $attachment)
if ($attachment["type"] == "image/jpeg")
$preview = $attachment["link"];
$item["body"] = $item["title"].add_page_info($item["plink"], false, $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
$item["tag"] = add_page_keywords($item["plink"], false, $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
$item["title"] = "";
$item["object-type"] = ACTIVITY_OBJ_BOOKMARK;
unset($item["attach"]);
} else {
$body = trim($xpath->evaluate('atom:content/text()', $entry)->item(0)->nodeValue);
if ($body == "")
$body = trim($xpath->evaluate('content:encoded/text()', $entry)->item(0)->nodeValue);
if ($body == "")
$body = trim($xpath->evaluate('description/text()', $entry)->item(0)->nodeValue);
if ($body == "")
$body = trim($xpath->evaluate('atom:summary/text()', $entry)->item(0)->nodeValue);
// remove the content of the title if it is identically to the body
// This helps with auto generated titles e.g. from tumblr
if (title_is_body($item["title"], $body))
$item["title"] = "";
$item["body"] = html2bbcode($body);
}
logger("Stored feed: ".print_r($item, true), LOGGER_DEBUG);
$notify = item_is_remote_self($contact, $item);
$id = item_store($item, false, $notify);
//print_r($item);
logger("Feed for contact ".$contact["url"]." stored under id ".$id);
}
}
?>

View file

@ -9,13 +9,13 @@ function update_contact($id) {
$r = q("SELECT `url`, `nurl`, `addr`, `alias`, `batch`, `notify`, `poll`, `poco`, `network` FROM `contact` WHERE `id` = %d", intval($id)); $r = q("SELECT `url`, `nurl`, `addr`, `alias`, `batch`, `notify`, `poll`, `poco`, `network` FROM `contact` WHERE `id` = %d", intval($id));
if (!$r) if (!$r)
return; return false;
$ret = probe_url($r[0]["url"]); $ret = probe_url($r[0]["url"]);
// If probe_url fails the network code will be different // If probe_url fails the network code will be different
if ($ret["network"] != $r[0]["network"]) if ($ret["network"] != $r[0]["network"])
return; return false;
$update = false; $update = false;
@ -29,7 +29,7 @@ function update_contact($id) {
} }
if (!$update) if (!$update)
return; return true;
q("UPDATE `contact` SET `url` = '%s', `nurl` = '%s', `addr` = '%s', `alias` = '%s', `batch` = '%s', `notify` = '%s', `poll` = '%s', `poco` = '%s' WHERE `id` = %d", q("UPDATE `contact` SET `url` = '%s', `nurl` = '%s', `addr` = '%s', `alias` = '%s', `batch` = '%s', `notify` = '%s', `poll` = '%s', `poco` = '%s' WHERE `id` = %d",
dbesc($ret['url']), dbesc($ret['url']),
@ -42,6 +42,8 @@ function update_contact($id) {
dbesc($ret['poco']), dbesc($ret['poco']),
intval($id) intval($id)
); );
return true;
} }
// //
@ -152,11 +154,7 @@ function new_contact($uid,$url,$interactive = false) {
$hidden = (($ret['network'] === NETWORK_MAIL) ? 1 : 0); $hidden = (($ret['network'] === NETWORK_MAIL) ? 1 : 0);
if($ret['network'] === NETWORK_MAIL) { if(in_array($ret['network'], array(NETWORK_MAIL, NETWORK_DIASPORA)))
$writeable = 1;
}
if($ret['network'] === NETWORK_DIASPORA)
$writeable = 1; $writeable = 1;
// check if we already have a contact // check if we already have a contact
@ -213,9 +211,7 @@ function new_contact($uid,$url,$interactive = false) {
return $result; return $result;
} }
$new_relation = (($ret['network'] === NETWORK_MAIL) ? CONTACT_IS_FRIEND : CONTACT_IS_SHARING); $new_relation = ((in_array($ret['network'], array(NETWORK_MAIL, NETWORK_DIASPORA))) ? CONTACT_IS_FRIEND : CONTACT_IS_SHARING);
if($ret['network'] === NETWORK_DIASPORA)
$new_relation = CONTACT_IS_FOLLOWER;
// create contact record // create contact record
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `batch`, `notify`, `poll`, `poco`, `name`, `nick`, `network`, `pubkey`, `rel`, `priority`, $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `batch`, `notify`, `poll`, `poco`, `name`, `nick`, `network`, `pubkey`, `rel`, `priority`,

182
include/forums.php Normal file
View file

@ -0,0 +1,182 @@
<?php
/**
* @file include/forums.php
* @brief Functions related to forum functionality *
*/
/**
* @brief Function to list all forums a user is connected with
*
* @param int $uid of the profile owner
* @param boolean $showhidden
* Show frorums which are not hidden
* @param boolean $lastitem
* Sort by lastitem
* @param boolean $showprivate
* Show private groups
*
* @returns array
* 'url' => forum url
* 'name' => forum name
* 'id' => number of the key from the array
* 'micro' => contact photo in format micro
*/
function get_forumlist($uid, $showhidden = true, $lastitem, $showprivate = false) {
$forumlist = array();
$order = (($showhidden) ? '' : ' AND NOT `hidden` ');
$order .= (($lastitem) ? ' ORDER BY `last-item` DESC ' : ' ORDER BY `name` ASC ');
$select = '`forum` ';
if ($showprivate) {
$select = '(`forum` OR `prv`)';
}
$contacts = q("SELECT `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`micro` FROM `contact`
WHERE `network`= 'dfrn' AND $select AND `uid` = %d
AND NOT `blocked` AND NOT `hidden` AND NOT `pending` AND NOT `archive`
AND `success_update` > `failure_update`
$order ",
intval($uid)
);
foreach($contacts as $contact) {
$forumlist[] = array(
'url' => $contact['url'],
'name' => $contact['name'],
'id' => $contact['id'],
'micro' => $contact['micro'],
);
}
return($forumlist);
}
/**
* @brief Forumlist widget
*
* Sidebar widget to show subcribed friendica forums. If activated
* in the settings, it appears at the notwork page sidebar
*
* @param int $uid
* @param int $cid
* The contact id which is used to mark a forum as "selected"
* @return string
*/
function widget_forumlist($uid,$cid = 0) {
if(! intval(feature_enabled(local_user(),'forumlist_widget')))
return;
$o = '';
//sort by last updated item
$lastitem = true;
$contacts = get_forumlist($uid,true,$lastitem, true);
$total = count($contacts);
$visible_forums = 10;
if(count($contacts)) {
$id = 0;
foreach($contacts as $contact) {
$selected = (($cid == $contact['id']) ? ' forum-selected' : '');
$entry = array(
'url' => z_root() . '/network?f=&cid=' . $contact['id'],
'external_url' => z_root() . '/redir/' . $contact['id'],
'name' => $contact['name'],
'cid' => $contact['id'],
'selected' => $selected,
'micro' => proxy_url($contact['micro'], false, PROXY_SIZE_MICRO),
'id' => ++$id,
);
$entries[] = $entry;
}
$tpl = get_markup_template('widget_forumlist.tpl');
$o .= replace_macros($tpl,array(
'$title' => t('Forums'),
'$forums' => $entries,
'$link_desc' => t('External link to forum'),
'$total' => $total,
'$visible_forums' => $visible_forums,
'$showmore' => t('show more'),
));
}
return $o;
}
/**
* @brief Format forumlist as contact block
*
* This function is used to show the forumlist in
* the advanced profile.
*
* @param int $uid
* @return string
*
*/
function forumlist_profile_advanced($uid) {
$profile = intval(feature_enabled($uid,'forumlist_profile'));
if(! $profile)
return;
$o = '';
// place holder in case somebody wants configurability
$show_total = 9999;
//don't sort by last updated item
$lastitem = false;
$contacts = get_forumlist($uid,false,$lastitem,false);
$total_shown = 0;
foreach($contacts as $contact) {
$forumlist .= micropro($contact,false,'forumlist-profile-advanced');
$total_shown ++;
if($total_shown == $show_total)
break;
}
if(count($contacts) > 0)
$o .= $forumlist;
return $o;
}
/**
* @brief count unread forum items
*
* Count unread items of connected forums and private groups
*
* @return array
* 'id' => contact id
* 'name' => contact/forum name
* 'count' => counted unseen forum items
*
*/
function forums_count_unseen() {
$r = q("SELECT `contact`.`id`, `contact`.`name`, COUNT(*) AS `count` FROM `item`
INNER JOIN `contact` ON `item`.`contact-id` = `contact`.`id`
WHERE `item`.`uid` = %d AND `item`.`visible` AND NOT `item`.`deleted` AND `item`.`unseen`
AND `contact`.`network`= 'dfrn' AND (`contact`.`forum` OR `contact`.`prv`)
AND NOT `contact`.`blocked` AND NOT `contact`.`hidden`
AND NOT `contact`.`pending` AND NOT `contact`.`archive`
AND `contact`.`success_update` > `failure_update`
GROUP BY `contact`.`id` ",
intval(local_user())
);
return $r;
}

View file

@ -2,6 +2,7 @@
require_once "object/TemplateEngine.php"; require_once "object/TemplateEngine.php";
require_once("library/Smarty/libs/Smarty.class.php"); require_once("library/Smarty/libs/Smarty.class.php");
require_once "include/plugin.php";
define('SMARTY3_TEMPLATE_FOLDER','templates'); define('SMARTY3_TEMPLATE_FOLDER','templates');
@ -59,6 +60,15 @@ class FriendicaSmartyEngine implements ITemplateEngine {
$template = $s; $template = $s;
$s = new FriendicaSmarty(); $s = new FriendicaSmarty();
} }
// "middleware": inject variables into templates
$arr = array(
"template"=> basename($s->filename),
"vars" => $r
);
call_hooks("template_vars", $arr);
$r = $arr['vars'];
foreach($r as $key=>$value) { foreach($r as $key=>$value) {
if($key[0] === '$') { if($key[0] === '$') {
$key = substr($key, 1); $key = substr($key, 1);

View file

@ -47,7 +47,7 @@ function gprobe_run(&$argv, &$argc){
$result = Cache::get("gprobe:".$urlparts["host"]); $result = Cache::get("gprobe:".$urlparts["host"]);
if (!is_null($result)) { if (!is_null($result)) {
$result = unserialize($result); $result = unserialize($result);
if ($result["network"] == NETWORK_FEED) { if (in_array($result["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) {
logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG); logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG);
return; return;
} }

View file

@ -158,7 +158,9 @@ function group_get_members($gid) {
if(intval($gid)) { if(intval($gid)) {
$r = q("SELECT `group_member`.`contact-id`, `contact`.* FROM `group_member` $r = q("SELECT `group_member`.`contact-id`, `contact`.* FROM `group_member`
INNER JOIN `contact` ON `contact`.`id` = `group_member`.`contact-id` INNER JOIN `contact` ON `contact`.`id` = `group_member`.`contact-id`
WHERE `gid` = %d AND `group_member`.`uid` = %d ORDER BY `contact`.`name` ASC ", WHERE `gid` = %d AND `group_member`.`uid` = %d AND
NOT `contact`.`self` AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
ORDER BY `contact`.`name` ASC ",
intval($gid), intval($gid),
intval(local_user()) intval(local_user())
); );
@ -211,9 +213,20 @@ function mini_group_select($uid,$gid = 0) {
} }
/**
* @brief Create group sidebar widget
function group_side($every="contacts",$each="group",$edit = false, $group_id = 0, $cid = 0) { *
* @param string $every
* @param string $each
* @param string $editmode
* 'standard' => include link 'Edit groups'
* 'extended' => include link 'Create new group'
* 'full' => include link 'Create new group' and provide for each group a link to edit this group
* @param int $group_id
* @param int $cid
* @return string
*/
function group_side($every="contacts",$each="group",$editmode = "standard", $group_id = 0, $cid = 0) {
$o = ''; $o = '';
@ -243,7 +256,7 @@ function group_side($every="contacts",$each="group",$edit = false, $group_id = 0
foreach($r as $rr) { foreach($r as $rr) {
$selected = (($group_id == $rr['id']) ? ' group-selected' : ''); $selected = (($group_id == $rr['id']) ? ' group-selected' : '');
if ($edit) { if ($editmode == "full") {
$groupedit = array( $groupedit = array(
'href' => "group/".$rr['id'], 'href' => "group/".$rr['id'],
'title' => t('edit'), 'title' => t('edit'),
@ -268,6 +281,9 @@ function group_side($every="contacts",$each="group",$edit = false, $group_id = 0
$tpl = get_markup_template("group_side.tpl"); $tpl = get_markup_template("group_side.tpl");
$o = replace_macros($tpl, array( $o = replace_macros($tpl, array(
'$title' => t('Groups'), '$title' => t('Groups'),
'newgroup' => (($editmode == "extended") || ($editmode == "full") ? 1 : ''),
'$editgroupstext' => t('Edit groups'),
'grouppage' => "group/",
'$edittext' => t('Edit group'), '$edittext' => t('Edit group'),
'$createtext' => t('Create a new group'), '$createtext' => t('Create a new group'),
'$creategroup' => t('Group Name: '), '$creategroup' => t('Group Name: '),
@ -324,3 +340,30 @@ function groups_containing($uid,$c) {
return $ret; return $ret;
} }
/**
* @brief count unread group items
*
* Count unread items of each groups
*
* @return array
* 'id' => group id
* 'name' => group name
* 'count' => counted unseen group items
*
*/
function groups_count_unseen() {
$r = q("SELECT `group`.`id`, `group`.`name`, COUNT(`item`.`id`) AS `count` FROM `group`, `group_member`, `item`
WHERE `group`.`uid` = %d
AND `item`.`uid` = %d
AND `item`.`unseen` AND `item`.`visible`
AND NOT `item`.`deleted`
AND `item`.`contact-id` = `group_member`.`contact-id`
AND `group_member`.`gid` = `group`.`id`
GROUP BY `group`.`id` ",
intval(local_user()),
intval(local_user())
);
return $r;
}

View file

@ -85,14 +85,16 @@ function deletenode(&$doc, $node)
$child->parentNode->removeChild($child); $child->parentNode->removeChild($child);
}} }}
function _replace_code_cb($m){
return "<code>".str_replace("\n","<br>\n",$m[1]). "</code>";
}
function html2bbcode($message) function html2bbcode($message)
{ {
$message = str_replace("\r", "", $message); $message = str_replace("\r", "", $message);
$message = preg_replace_callback("|<pre><code>([^<]*)</code></pre>|ism", function($m) { $message = preg_replace_callback("|<pre><code>([^<]*)</code></pre>|ism", "_replace_code_cb", $message);
return "<code>".str_replace("\n","<br>\n",$m[1]). "</code>";
}, $message);
$message = str_replace(array( $message = str_replace(array(
"<li><p>", "<li><p>",

View file

@ -1,5 +1,11 @@
<?php <?php
/**
* @file include/identity.php
*/
require_once('include/forums.php');
require_once('include/bbcode.php');
require_once("mod/proxy.php");
/** /**
* *
@ -40,39 +46,9 @@ if(! function_exists('profile_load')) {
return; return;
} }
if(remote_user() && count($_SESSION['remote'])) { $pdata = get_profiledata_by_nick($nickname, $user[0]['uid'], $profile);
foreach($_SESSION['remote'] as $visitor) {
if($visitor['uid'] == $user[0]['uid']) {
$r = q("SELECT `profile-id` FROM `contact` WHERE `id` = %d LIMIT 1",
intval($visitor['cid'])
);
if(count($r))
$profile = $r[0]['profile-id'];
break;
}
}
}
$r = null; if(($pdata === false) || (!count($pdata)) && !count($profiledata)) {
if($profile) {
$profile_int = intval($profile);
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile`
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d and `contact`.`self` = 1 LIMIT 1",
dbesc($nickname),
intval($profile_int)
);
}
if((!$r) && (!count($r))) {
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile`
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 and `contact`.`self` = 1 LIMIT 1",
dbesc($nickname)
);
}
if(($r === false) || (!count($r)) && !count($profiledata)) {
logger('profile error: ' . $a->query_string, LOGGER_DEBUG); logger('profile error: ' . $a->query_string, LOGGER_DEBUG);
notice( t('Requested profile is not available.') . EOL ); notice( t('Requested profile is not available.') . EOL );
$a->error = 404; $a->error = 404;
@ -81,16 +57,16 @@ if(! function_exists('profile_load')) {
// fetch user tags if this isn't the default profile // fetch user tags if this isn't the default profile
if(!$r[0]['is-default']) { if(!$pdata['is-default']) {
$x = q("select `pub_keywords` from `profile` where uid = %d and `is-default` = 1 limit 1", $x = q("SELECT `pub_keywords` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
intval($r[0]['profile_uid']) intval($pdata['profile_uid'])
); );
if($x && count($x)) if($x && count($x))
$r[0]['pub_keywords'] = $x[0]['pub_keywords']; $pdata['pub_keywords'] = $x[0]['pub_keywords'];
} }
$a->profile = $r[0]; $a->profile = $pdata;
$a->profile_uid = $r[0]['profile_uid']; $a->profile_uid = $pdata['profile_uid'];
$a->profile['mobile-theme'] = get_pconfig($a->profile['profile_uid'], 'system', 'mobile_theme'); $a->profile['mobile-theme'] = get_pconfig($a->profile['profile_uid'], 'system', 'mobile_theme');
$a->profile['network'] = NETWORK_DFRN; $a->profile['network'] = NETWORK_DFRN;
@ -133,7 +109,6 @@ if(! function_exists('profile_load')) {
else else
$a->page['aside'] .= profile_sidebar($a->profile, $block); $a->page['aside'] .= profile_sidebar($a->profile, $block);
/*if(! $block) /*if(! $block)
$a->page['aside'] .= contact_block();*/ $a->page['aside'] .= contact_block();*/
@ -142,6 +117,58 @@ if(! function_exists('profile_load')) {
} }
/**
* @brief Get all profil data of a local user
* If the viewer is an authenticated remote viewer, the profile displayed is the
* one that has been configured for his/her viewing in the Contact manager.
* Passing a non-zero profile ID can also allow a preview of a selected profile
* by the owner
*
* @param string $nickname
* @param int $uid
* @param int $profile
* ID of the profile
* @returns array
* Includes all available profile data
*/
function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0) {
if(remote_user() && count($_SESSION['remote'])) {
foreach($_SESSION['remote'] as $visitor) {
if($visitor['uid'] == $uid) {
$r = q("SELECT `profile-id` FROM `contact` WHERE `id` = %d LIMIT 1",
intval($visitor['cid'])
);
if(count($r))
$profile = $r[0]['profile-id'];
break;
}
}
}
$r = null;
if($profile) {
$profile_int = intval($profile);
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.* FROM `profile`
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d AND `contact`.`self` = 1 LIMIT 1",
dbesc($nickname),
intval($profile_int)
);
}
if((!$r) && (!count($r))) {
$r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.* FROM `profile`
INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 AND `contact`.`self` = 1 LIMIT 1",
dbesc($nickname)
);
}
return $r[0];
}
/** /**
* *
* Function: profile_sidebar * Function: profile_sidebar
@ -156,8 +183,6 @@ if(! function_exists('profile_load')) {
* Exceptions: Returns empty string if passed $profile is wrong type or not populated * Exceptions: Returns empty string if passed $profile is wrong type or not populated
* *
*/ */
if(! function_exists('profile_sidebar')) { if(! function_exists('profile_sidebar')) {
function profile_sidebar($profile, $block = 0) { function profile_sidebar($profile, $block = 0) {
$a = get_app(); $a = get_app();
@ -165,7 +190,7 @@ if(! function_exists('profile_sidebar')) {
$o = ''; $o = '';
$location = false; $location = false;
$address = false; $address = false;
$pdesc = true; // $pdesc = true;
if((! is_array($profile)) && (! count($profile))) if((! is_array($profile)) && (! count($profile)))
return $o; return $o;
@ -173,11 +198,7 @@ if(! function_exists('profile_sidebar')) {
$profile['picdate'] = urlencode($profile['picdate']); $profile['picdate'] = urlencode($profile['picdate']);
if (($profile['network'] != "") AND ($profile['network'] != NETWORK_DFRN)) { if (($profile['network'] != "") AND ($profile['network'] != NETWORK_DFRN)) {
require_once('include/contact_selectors.php'); $profile['network_name'] = format_network_name($profile['network'],$profile['url']);
if ($profile['url'] != "")
$profile['network_name'] = '<a href="'.$profile['url'].'">'.network_to_name($profile['network'], $profile['url'])."</a>";
else
$profile['network_name'] = network_to_name($profile['network']);
} else } else
$profile['network_name'] = ""; $profile['network_name'] = "";
@ -216,7 +237,12 @@ if(! function_exists('profile_sidebar')) {
if (isset($profile['remoteconnect'])) if (isset($profile['remoteconnect']))
$remoteconnect = $profile['remoteconnect']; $remoteconnect = $profile['remoteconnect'];
if( get_my_url() && $profile['unkmail'] && ($profile['uid'] != local_user()) ) if ($connect AND ($profile['network'] == NETWORK_DFRN) AND !isset($remoteconnect))
$subscribe_feed = t("Atom feed");
else
$subscribe_feed = false;
if(get_my_url() && $profile['unkmail'] && ($profile['uid'] != local_user()))
$wallmessage = t('Message'); $wallmessage = t('Message');
else else
$wallmessage = false; $wallmessage = false;
@ -260,6 +286,16 @@ if(! function_exists('profile_sidebar')) {
); );
} }
// check if profile is a forum
if((intval($profile['page-flags']) == PAGE_COMMUNITY)
|| (intval($profile['page-flags']) == PAGE_PRVGROUP)
|| (intval($profile['forum']))
|| (intval($profile['prv']))
|| (intval($profile['community'])))
$account_type = t('Forum');
else
$account_type = "";
if((x($profile,'address') == 1) if((x($profile,'address') == 1)
|| (x($profile,'locality') == 1) || (x($profile,'locality') == 1)
|| (x($profile,'region') == 1) || (x($profile,'region') == 1)
@ -306,7 +342,7 @@ if(! function_exists('profile_sidebar')) {
if(count($r)) if(count($r))
$updated = date("c", strtotime($r[0]['updated'])); $updated = date("c", strtotime($r[0]['updated']));
$r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0 AND `archive` = 0 $r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
AND `network` IN ('%s', '%s', '%s', '')", AND `network` IN ('%s', '%s', '%s', '')",
intval($profile['uid']), intval($profile['uid']),
dbesc(NETWORK_DFRN), dbesc(NETWORK_DFRN),
@ -324,6 +360,15 @@ if(! function_exists('profile_sidebar')) {
$p[$k] = $v; $p[$k] = $v;
} }
if (isset($p["about"]))
$p["about"] = bbcode($p["about"]);
if (isset($p["location"]))
$p["location"] = bbcode($p["location"]);
if (isset($p["photo"]))
$p["photo"] = proxy_url($p["photo"], false, PROXY_SIZE_SMALL);
if($a->theme['template_engine'] === 'internal') if($a->theme['template_engine'] === 'internal')
$location = template_escape($location); $location = template_escape($location);
@ -332,10 +377,12 @@ if(! function_exists('profile_sidebar')) {
'$profile' => $p, '$profile' => $p,
'$connect' => $connect, '$connect' => $connect,
'$remoteconnect' => $remoteconnect, '$remoteconnect' => $remoteconnect,
'$subscribe_feed' => $subscribe_feed,
'$wallmessage' => $wallmessage, '$wallmessage' => $wallmessage,
'$account_type' => $account_type,
'$location' => $location, '$location' => $location,
'$gender' => $gender, '$gender' => $gender,
'$pdesc' => $pdesc, // '$pdesc' => $pdesc,
'$marital' => $marital, '$marital' => $marital,
'$homepage' => $homepage, '$homepage' => $homepage,
'$about' => $about, '$about' => $about,
@ -525,8 +572,9 @@ if(! function_exists('get_events')) {
function advanced_profile(&$a) { function advanced_profile(&$a) {
$o = ''; $o = '';
$uid = $a->profile['uid'];
$o .= replace_macros(get_markup_template("section_title.tpl"),array( $o .= replace_macros(get_markup_template('section_title.tpl'),array(
'$title' => t('Profile') '$title' => t('Profile')
)); ));
@ -604,6 +652,11 @@ function advanced_profile(&$a) {
if($txt = prepare_text($a->profile['education'])) $profile['education'] = array( t('School/education:'), $txt ); if($txt = prepare_text($a->profile['education'])) $profile['education'] = array( t('School/education:'), $txt );
//show subcribed forum if it is enabled in the usersettings
if (feature_enabled($uid,'forumlist_profile')) {
$profile['forumlist'] = array( t('Forums:'), forumlist_profile_advanced($uid));
}
if ($a->profile['uid'] == local_user()) if ($a->profile['uid'] == local_user())
$profile['edit'] = array($a->get_baseurl(). '/profiles/'.$a->profile['id'], t('Edit profile'),"", t('Edit profile')); $profile['edit'] = array($a->get_baseurl(). '/profiles/'.$a->profile['id'], t('Edit profile'),"", t('Edit profile'));
@ -664,6 +717,7 @@ if(! function_exists('profile_tabs')){
); );
if ($is_owner){ if ($is_owner){
if ($a->theme_events_in_profile)
$tabs[] = array( $tabs[] = array(
'label' => t('Events'), 'label' => t('Events'),
'url' => $a->get_baseurl() . '/events', 'url' => $a->get_baseurl() . '/events',
@ -682,6 +736,16 @@ if(! function_exists('profile_tabs')){
); );
} }
if ((! $is_owner) && ((count($a->profile)) || (! $a->profile['hide-friends']))) {
$tabs[] = array(
'label' => t('Contacts'),
'url' => $a->get_baseurl() . '/viewcontacts/' . $nickname,
'sel' => ((!isset($tab)&&$a->argv[0]=='viewcontacts')?'active':''),
'title' => t('Contacts'),
'id' => 'viewcontacts-tab',
'accesskey' => 'k',
);
}
$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs); $arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
call_hooks('profile_tabs', $arr); call_hooks('profile_tabs', $arr);
@ -709,7 +773,7 @@ function zrl_init(&$a) {
$result = Cache::get("gprobe:".$urlparts["host"]); $result = Cache::get("gprobe:".$urlparts["host"]);
if (!is_null($result)) { if (!is_null($result)) {
$result = unserialize($result); $result = unserialize($result);
if ($result["network"] == NETWORK_FEED) { if (in_array($result["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) {
logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG); logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG);
return; return;
} }

View file

@ -13,6 +13,7 @@ require_once('include/threads.php');
require_once('include/socgraph.php'); require_once('include/socgraph.php');
require_once('include/plaintext.php'); require_once('include/plaintext.php');
require_once('include/ostatus.php'); require_once('include/ostatus.php');
require_once('include/feed.php');
require_once('mod/share.php'); require_once('mod/share.php');
require_once('library/defuse/php-encryption-1.2.1/Crypto.php'); require_once('library/defuse/php-encryption-1.2.1/Crypto.php');
@ -1096,6 +1097,48 @@ function add_guid($item) {
dbesc($item["uri"]), dbesc($item["network"])); dbesc($item["uri"]), dbesc($item["network"]));
} }
// Adds a "lang" specification in a "postopts" element of given $arr,
// if possible and not already present.
// Expects "body" element to exist in $arr.
// TODO: add a parameter to request forcing override
function item_add_language_opt(&$arr) {
if (version_compare(PHP_VERSION, '5.3.0', '<')) return; // LanguageDetect.php not available ?
if ( x($arr, 'postopts') )
{
if ( strstr($arr['postopts'], 'lang=') )
{
// do not override
// TODO: add parameter to request overriding
return;
}
$postopts = $arr['postopts'];
}
else
{
$postopts = "";
}
require_once('library/langdet/Text/LanguageDetect.php');
$naked_body = preg_replace('/\[(.+?)\]/','',$arr['body']);
$l = new Text_LanguageDetect;
//$lng = $l->detectConfidence($naked_body);
//$arr['postopts'] = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : '');
$lng = $l->detect($naked_body, 3);
if (sizeof($lng) > 0) {
if ($postopts != "") $postopts .= '&'; // arbitrary separator, to be reviewed
$postopts .= 'lang=';
$sep = "";
foreach ($lng as $language => $score) {
$postopts .= $sep . $language.";".$score;
$sep = ':';
}
$arr['postopts'] = $postopts;
}
}
function item_store($arr,$force_parent = false, $notify = false, $dontcache = false) { function item_store($arr,$force_parent = false, $notify = false, $dontcache = false) {
// If it is a posting where users should get notifications, then define it as wall posting // If it is a posting where users should get notifications, then define it as wall posting
@ -1153,6 +1196,24 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
} }
} }
// Do we already have this item?
// We have to check several networks since Friendica posts could be repeated via OStatus (maybe Diasporsa as well)
if (in_array(trim($arr['network']), array(NETWORK_DIASPORA, NETWORK_DFRN, NETWORK_OSTATUS, ""))) {
$r = q("SELECT `id`, `network` FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` IN ('%s', '%s', '%s') LIMIT 1",
dbesc(trim($arr['uri'])),
intval($uid),
dbesc(NETWORK_DIASPORA),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_OSTATUS)
);
if ($r) {
// We only log the entries with a different user id than 0. Otherwise we would have too many false positives
if ($uid != 0)
logger("Item with uri ".$arr['uri']." already existed for user ".$uid." with id ".$r[0]["id"]." target network ".$r[0]["network"]." - new network: ".$arr['network']);
return($r[0]["id"]);
}
}
// If there is no guid then take the same guid that was taken before for the same uri // If there is no guid then take the same guid that was taken before for the same uri
if ((trim($arr['guid']) == "") AND (trim($arr['uri']) != "") AND (trim($arr['network']) != "")) { if ((trim($arr['guid']) == "") AND (trim($arr['uri']) != "") AND (trim($arr['network']) != "")) {
logger('item_store: checking for an existing guid for uri '.$arr['uri'], LOGGER_DEBUG); logger('item_store: checking for an existing guid for uri '.$arr['uri'], LOGGER_DEBUG);
@ -1185,43 +1246,23 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
//if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false)) //if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false))
// $arr['body'] = strip_tags($arr['body']); // $arr['body'] = strip_tags($arr['body']);
item_add_language_opt($arr);
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
require_once('library/langdet/Text/LanguageDetect.php');
$naked_body = preg_replace('/\[(.+?)\]/','',$arr['body']);
$l = new Text_LanguageDetect;
//$lng = $l->detectConfidence($naked_body);
//$arr['postopts'] = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : '');
$lng = $l->detect($naked_body, 3);
if (sizeof($lng) > 0) {
$postopts = "";
foreach ($lng as $language => $score) {
if ($postopts == "")
$postopts = "lang=";
else
$postopts .= ":";
$postopts .= $language.";".$score;
}
$arr['postopts'] = $postopts;
}
}
if ($notify) if ($notify)
$guid_prefix = ""; $guid_prefix = "";
else else {
$guid_prefix = $arr['network']; $parsed = parse_url($arr["author-link"]);
$guid_prefix = hash("crc32", $parsed["host"]);
}
$arr['wall'] = ((x($arr,'wall')) ? intval($arr['wall']) : 0); $arr['wall'] = ((x($arr,'wall')) ? intval($arr['wall']) : 0);
$arr['guid'] = ((x($arr,'guid')) ? notags(trim($arr['guid'])) : get_guid(32, $guid_prefix)); $arr['guid'] = ((x($arr,'guid')) ? notags(trim($arr['guid'])) : get_guid(32, $guid_prefix));
$arr['uri'] = ((x($arr,'uri')) ? notags(trim($arr['uri'])) : $arr['guid']); $arr['uri'] = ((x($arr,'uri')) ? notags(trim($arr['uri'])) : $arr['guid']);
$arr['extid'] = ((x($arr,'extid')) ? notags(trim($arr['extid'])) : ''); $arr['extid'] = ((x($arr,'extid')) ? notags(trim($arr['extid'])) : '');
$arr['author-name'] = ((x($arr,'author-name')) ? notags(trim($arr['author-name'])) : ''); $arr['author-name'] = ((x($arr,'author-name')) ? trim($arr['author-name']) : '');
$arr['author-link'] = ((x($arr,'author-link')) ? notags(trim($arr['author-link'])) : ''); $arr['author-link'] = ((x($arr,'author-link')) ? notags(trim($arr['author-link'])) : '');
$arr['author-avatar'] = ((x($arr,'author-avatar')) ? notags(trim($arr['author-avatar'])) : ''); $arr['author-avatar'] = ((x($arr,'author-avatar')) ? notags(trim($arr['author-avatar'])) : '');
$arr['owner-name'] = ((x($arr,'owner-name')) ? notags(trim($arr['owner-name'])) : ''); $arr['owner-name'] = ((x($arr,'owner-name')) ? trim($arr['owner-name']) : '');
$arr['owner-link'] = ((x($arr,'owner-link')) ? notags(trim($arr['owner-link'])) : ''); $arr['owner-link'] = ((x($arr,'owner-link')) ? notags(trim($arr['owner-link'])) : '');
$arr['owner-avatar'] = ((x($arr,'owner-avatar')) ? notags(trim($arr['owner-avatar'])) : ''); $arr['owner-avatar'] = ((x($arr,'owner-avatar')) ? notags(trim($arr['owner-avatar'])) : '');
$arr['created'] = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert()); $arr['created'] = ((x($arr,'created') !== false) ? datetime_convert('UTC','UTC',$arr['created']) : datetime_convert());
@ -1229,8 +1270,8 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
$arr['commented'] = ((x($arr,'commented') !== false) ? datetime_convert('UTC','UTC',$arr['commented']) : datetime_convert()); $arr['commented'] = ((x($arr,'commented') !== false) ? datetime_convert('UTC','UTC',$arr['commented']) : datetime_convert());
$arr['received'] = ((x($arr,'received') !== false) ? datetime_convert('UTC','UTC',$arr['received']) : datetime_convert()); $arr['received'] = ((x($arr,'received') !== false) ? datetime_convert('UTC','UTC',$arr['received']) : datetime_convert());
$arr['changed'] = ((x($arr,'changed') !== false) ? datetime_convert('UTC','UTC',$arr['changed']) : datetime_convert()); $arr['changed'] = ((x($arr,'changed') !== false) ? datetime_convert('UTC','UTC',$arr['changed']) : datetime_convert());
$arr['title'] = ((x($arr,'title')) ? notags(trim($arr['title'])) : ''); $arr['title'] = ((x($arr,'title')) ? trim($arr['title']) : '');
$arr['location'] = ((x($arr,'location')) ? notags(trim($arr['location'])) : ''); $arr['location'] = ((x($arr,'location')) ? trim($arr['location']) : '');
$arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : ''); $arr['coord'] = ((x($arr,'coord')) ? notags(trim($arr['coord'])) : '');
$arr['last-child'] = ((x($arr,'last-child')) ? intval($arr['last-child']) : 0 ); $arr['last-child'] = ((x($arr,'last-child')) ? intval($arr['last-child']) : 0 );
$arr['visible'] = ((x($arr,'visible') !== false) ? intval($arr['visible']) : 1 ); $arr['visible'] = ((x($arr,'visible') !== false) ? intval($arr['visible']) : 1 );
@ -1266,6 +1307,19 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
} }
if ($arr['network'] == "") { if ($arr['network'] == "") {
$r = q("SELECT `network` FROM `contact` WHERE `network` IN ('%s', '%s', '%s') AND `nurl` = '%s' AND `uid` = %d LIMIT 1",
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS),
dbesc(normalise_link($arr['author-link'])),
intval($arr['uid'])
);
if(!count($r))
$r = q("SELECT `network` FROM `gcontact` WHERE `network` IN ('%s', '%s', '%s') AND `nurl` = '%s' LIMIT 1",
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS),
dbesc(normalise_link($arr['author-link']))
);
if(!count($r))
$r = q("SELECT `network` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", $r = q("SELECT `network` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($arr['contact-id']), intval($arr['contact-id']),
intval($arr['uid']) intval($arr['uid'])
@ -1391,9 +1445,10 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
} }
} }
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `network` = '%s' AND `uid` = %d LIMIT 1", $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `network` IN ('%s', '%s') AND `uid` = %d LIMIT 1",
dbesc($arr['uri']), dbesc($arr['uri']),
dbesc($arr['network']), dbesc($arr['network']),
dbesc(NETWORK_DFRN),
intval($arr['uid']) intval($arr['uid'])
); );
if($r && count($r)) { if($r && count($r)) {
@ -1454,13 +1509,24 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
// And restore it // And restore it
$arr = $unescaped; $arr = $unescaped;
// find the item we just created // find the item that we just created
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = %d ORDER BY `id` ASC ", $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` = '%s' ORDER BY `id` ASC",
dbesc($arr['uri']), dbesc($arr['uri']),
intval($arr['uid']) intval($arr['uid']),
dbesc($arr['network'])
); );
if(count($r)) { if(count($r) > 1) {
// There are duplicates. Keep the oldest one, delete the others
logger('item_store: duplicated post occurred. Removing newer duplicates. uri = '.$arr['uri'].' uid = '.$arr['uid']);
q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `network` = '%s' AND `id` > %d",
dbesc($arr['uri']),
intval($arr['uid']),
dbesc($arr['network']),
intval($r[0]["id"])
);
return 0;
} elseif(count($r)) {
// Store the guid and other relevant data // Store the guid and other relevant data
add_guid($arr); add_guid($arr);
@ -1493,14 +1559,6 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
logger('item_store: could not locate created item'); logger('item_store: could not locate created item');
return 0; return 0;
} }
if(count($r) > 1) {
logger('item_store: duplicated post occurred. Removing duplicates. uri = '.$arr['uri'].' uid = '.$arr['uid']);
q("DELETE FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `id` != %d ",
dbesc($arr['uri']),
intval($arr['uid']),
intval($current_post)
);
}
if((! $parent_id) || ($arr['parent-uri'] === $arr['uri'])) if((! $parent_id) || ($arr['parent-uri'] === $arr['uri']))
$parent_id = $current_post; $parent_id = $current_post;
@ -2265,15 +2323,22 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
if ($contact['network'] === NETWORK_OSTATUS) { if ($contact['network'] === NETWORK_OSTATUS) {
if ($pass < 2) { if ($pass < 2) {
// Test - remove before flight // Test - remove before flight
//$tempfile = tempnam(get_temppath(), "ostatus"); //$tempfile = tempnam(get_temppath(), "ostatus2");
//file_put_contents($tempfile, $xml); //file_put_contents($tempfile, $xml);
logger("Consume OStatus messages ", LOGGER_DEBUG); logger("Consume OStatus messages ", LOGGER_DEBUG);
ostatus_import($xml,$importer,$contact, $hub); ostatus_import($xml,$importer,$contact, $hub);
} }
return; return;
} }
if ($contact['network'] === NETWORK_FEED) {
if ($pass < 2) {
logger("Consume feeds", LOGGER_DEBUG);
feed_import($xml,$importer,$contact, $hub);
}
return;
}
require_once('library/simplepie/simplepie.inc'); require_once('library/simplepie/simplepie.inc');
require_once('include/contact_selectors.php'); require_once('include/contact_selectors.php');
@ -2342,85 +2407,45 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
$contact_updated = $photo_timestamp; $contact_updated = $photo_timestamp;
require_once("include/Photo.php"); require_once("include/Photo.php");
$photo_failure = false; $photos = import_profile_photo($photo_url,$contact['uid'],$contact['id']);
$have_photo = false;
$r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1",
intval($contact['id']),
intval($contact['uid'])
);
if(count($r)) {
$resource_id = $r[0]['resource-id'];
$have_photo = true;
}
else {
$resource_id = photo_new_resource();
}
$img_str = fetch_url($photo_url,true);
// guess mimetype from headers or filename
$type = guess_image_type($photo_url,true);
$img = new Photo($img_str, $type);
if($img->is_valid()) {
if($have_photo) {
q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d",
dbesc($resource_id),
intval($contact['id']),
intval($contact['uid'])
);
}
$img->scaleImageSquare(175);
$hash = $resource_id;
$r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 4);
$img->scaleImage(80);
$r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 5);
$img->scaleImage(48);
$r = $img->store($contact['uid'], $contact['id'], $hash, basename($photo_url), 'Contact Photos', 6);
$a = get_app();
q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s' q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
WHERE `uid` = %d AND `id` = %d", WHERE `uid` = %d AND `id` = %d AND NOT `self`",
dbesc(datetime_convert()), dbesc(datetime_convert()),
dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()), dbesc($photos[0]),
dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.'.$img->getExt()), dbesc($photos[1]),
dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.'.$img->getExt()), dbesc($photos[2]),
intval($contact['uid']), intval($contact['uid']),
intval($contact['id']) intval($contact['id'])
); );
} }
}
if((is_array($contact)) && ($name_updated) && (strlen($new_name)) && ($name_updated > $contact['name-date'])) { if((is_array($contact)) && ($name_updated) && (strlen($new_name)) && ($name_updated > $contact['name-date'])) {
if ($name_updated > $contact_updated) if ($name_updated > $contact_updated)
$contact_updated = $name_updated; $contact_updated = $name_updated;
$r = q("select * from contact where uid = %d and id = %d limit 1", $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1",
intval($contact['uid']), intval($contact['uid']),
intval($contact['id']) intval($contact['id'])
); );
$x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d", $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d AND `name` != '%s' AND NOT `self`",
dbesc(notags(trim($new_name))), dbesc(notags(trim($new_name))),
dbesc(datetime_convert()), dbesc(datetime_convert()),
intval($contact['uid']), intval($contact['uid']),
intval($contact['id']) intval($contact['id']),
dbesc(notags(trim($new_name)))
); );
// do our best to update the name on content items // do our best to update the name on content items
if(count($r)) { if(count($r) AND (notags(trim($new_name)) != $r[0]['name'])) {
q("update item set `author-name` = '%s' where `author-name` = '%s' and `author-link` = '%s' and uid = %d", q("UPDATE `item` SET `author-name` = '%s' WHERE `author-name` = '%s' AND `author-link` = '%s' AND `uid` = %d AND `author-name` != '%s'",
dbesc(notags(trim($new_name))), dbesc(notags(trim($new_name))),
dbesc($r[0]['name']), dbesc($r[0]['name']),
dbesc($r[0]['url']), dbesc($r[0]['url']),
intval($contact['uid']) intval($contact['uid']),
dbesc(notags(trim($new_name)))
); );
} }
} }
@ -2519,6 +2544,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
if(! $item['deleted']) if(! $item['deleted'])
logger('consume_feed: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG); logger('consume_feed: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
if($item['object-type'] === ACTIVITY_OBJ_EVENT) {
logger("Deleting event ".$item['event-id'], LOGGER_DEBUG);
event_delete($item['event-id']);
}
if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) { if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
$xo = parse_xml_string($item['object'],false); $xo = parse_xml_string($item['object'],false);
$xt = parse_xml_string($item['target'],false); $xt = parse_xml_string($item['target'],false);
@ -2726,7 +2756,11 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
$datarray['parent-uri'] = $parent_uri; $datarray['parent-uri'] = $parent_uri;
$datarray['uid'] = $importer['uid']; $datarray['uid'] = $importer['uid'];
$datarray['contact-id'] = $contact['id']; $datarray['contact-id'] = $contact['id'];
if((activity_match($datarray['verb'],ACTIVITY_LIKE)) || (activity_match($datarray['verb'],ACTIVITY_DISLIKE))) { if(($datarray['verb'] === ACTIVITY_LIKE)
|| ($datarray['verb'] === ACTIVITY_DISLIKE)
|| ($datarray['verb'] === ACTIVITY_ATTEND)
|| ($datarray['verb'] === ACTIVITY_ATTENDNO)
|| ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
$datarray['type'] = 'activity'; $datarray['type'] = 'activity';
$datarray['gravity'] = GRAVITY_LIKE; $datarray['gravity'] = GRAVITY_LIKE;
// only one like or dislike per person // only one like or dislike per person
@ -2806,11 +2840,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
if((x($datarray,'object-type')) && ($datarray['object-type'] === ACTIVITY_OBJ_EVENT)) { if((x($datarray,'object-type')) && ($datarray['object-type'] === ACTIVITY_OBJ_EVENT)) {
$ev = bbtoevent($datarray['body']); $ev = bbtoevent($datarray['body']);
if(x($ev,'desc') && x($ev,'start')) { if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
$ev['uid'] = $importer['uid']; $ev['uid'] = $importer['uid'];
$ev['uri'] = $item_id; $ev['uri'] = $item_id;
$ev['edited'] = $datarray['edited']; $ev['edited'] = $datarray['edited'];
$ev['private'] = $datarray['private']; $ev['private'] = $datarray['private'];
$ev['guid'] = $datarray['guid'];
if(is_array($contact)) if(is_array($contact))
$ev['cid'] = $contact['id']; $ev['cid'] = $contact['id'];
@ -3070,85 +3105,46 @@ function local_delivery($importer,$data) {
logger('local_delivery: Updating photo for ' . $importer['name']); logger('local_delivery: Updating photo for ' . $importer['name']);
require_once("include/Photo.php"); require_once("include/Photo.php");
$photo_failure = false;
$have_photo = false;
$r = q("SELECT `resource-id` FROM `photo` WHERE `contact-id` = %d AND `uid` = %d LIMIT 1", $photos = import_profile_photo($photo_url,$importer['importer_uid'],$importer['id']);
intval($importer['id']),
intval($importer['importer_uid'])
);
if(count($r)) {
$resource_id = $r[0]['resource-id'];
$have_photo = true;
}
else {
$resource_id = photo_new_resource();
}
$img_str = fetch_url($photo_url,true);
// guess mimetype from headers or filename
$type = guess_image_type($photo_url,true);
$img = new Photo($img_str, $type);
if($img->is_valid()) {
if($have_photo) {
q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `contact-id` = %d AND `uid` = %d",
dbesc($resource_id),
intval($importer['id']),
intval($importer['importer_uid'])
);
}
$img->scaleImageSquare(175);
$hash = $resource_id;
$r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 4);
$img->scaleImage(80);
$r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 5);
$img->scaleImage(48);
$r = $img->store($importer['importer_uid'], $importer['id'], $hash, basename($photo_url), 'Contact Photos', 6);
$a = get_app();
q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s' q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
WHERE `uid` = %d AND `id` = %d", WHERE `uid` = %d AND `id` = %d AND NOT `self`",
dbesc(datetime_convert()), dbesc(datetime_convert()),
dbesc($a->get_baseurl() . '/photo/' . $hash . '-4.'.$img->getExt()), dbesc($photos[0]),
dbesc($a->get_baseurl() . '/photo/' . $hash . '-5.'.$img->getExt()), dbesc($photos[1]),
dbesc($a->get_baseurl() . '/photo/' . $hash . '-6.'.$img->getExt()), dbesc($photos[2]),
intval($importer['importer_uid']), intval($importer['importer_uid']),
intval($importer['id']) intval($importer['id'])
); );
} }
}
if(($name_updated) && (strlen($new_name)) && ($name_updated > $importer['name-date'])) { if(($name_updated) && (strlen($new_name)) && ($name_updated > $importer['name-date'])) {
if ($name_updated > $contact_updated) if ($name_updated > $contact_updated)
$contact_updated = $name_updated; $contact_updated = $name_updated;
$r = q("select * from contact where uid = %d and id = %d limit 1", $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1",
intval($importer['importer_uid']), intval($importer['importer_uid']),
intval($importer['id']) intval($importer['id'])
); );
$x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d", $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d AND `name` != '%s' AND NOT `self`",
dbesc(notags(trim($new_name))), dbesc(notags(trim($new_name))),
dbesc(datetime_convert()), dbesc(datetime_convert()),
intval($importer['importer_uid']), intval($importer['importer_uid']),
intval($importer['id']) intval($importer['id']),
dbesc(notags(trim($new_name)))
); );
// do our best to update the name on content items // do our best to update the name on content items
if(count($r)) { if(count($r) AND (notags(trim($new_name)) != $r[0]['name'])) {
q("update item set `author-name` = '%s' where `author-name` = '%s' and `author-link` = '%s' and uid = %d", q("UPDATE `item` SET `author-name` = '%s' WHERE `author-name` = '%s' AND `author-link` = '%s' AND `uid` = %d AND `author-name` != '%s'",
dbesc(notags(trim($new_name))), dbesc(notags(trim($new_name))),
dbesc($r[0]['name']), dbesc($r[0]['name']),
dbesc($r[0]['url']), dbesc($r[0]['url']),
intval($importer['importer_uid']) intval($importer['importer_uid']),
dbesc(notags(trim($new_name)))
); );
} }
} }
@ -3500,6 +3496,11 @@ function local_delivery($importer,$data) {
logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG); logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
if($item['object-type'] === ACTIVITY_OBJ_EVENT) {
logger("Deleting event ".$item['event-id'], LOGGER_DEBUG);
event_delete($item['event-id']);
}
if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) { if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
$xo = parse_xml_string($item['object'],false); $xo = parse_xml_string($item['object'],false);
$xt = parse_xml_string($item['target'],false); $xt = parse_xml_string($item['target'],false);
@ -3713,7 +3714,11 @@ function local_delivery($importer,$data) {
$datarray['owner-avatar'] = $own[0]['thumb']; $datarray['owner-avatar'] = $own[0]['thumb'];
$datarray['contact-id'] = $importer['id']; $datarray['contact-id'] = $importer['id'];
if(($datarray['verb'] === ACTIVITY_LIKE) || ($datarray['verb'] === ACTIVITY_DISLIKE)) { if(($datarray['verb'] === ACTIVITY_LIKE)
|| ($datarray['verb'] === ACTIVITY_DISLIKE)
|| ($datarray['verb'] === ACTIVITY_ATTEND)
|| ($datarray['verb'] === ACTIVITY_ATTENDNO)
|| ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
$is_like = true; $is_like = true;
$datarray['type'] = 'activity'; $datarray['type'] = 'activity';
$datarray['gravity'] = GRAVITY_LIKE; $datarray['gravity'] = GRAVITY_LIKE;
@ -3902,7 +3907,11 @@ function local_delivery($importer,$data) {
$datarray['parent-uri'] = $parent_uri; $datarray['parent-uri'] = $parent_uri;
$datarray['uid'] = $importer['importer_uid']; $datarray['uid'] = $importer['importer_uid'];
$datarray['contact-id'] = $importer['id']; $datarray['contact-id'] = $importer['id'];
if(($datarray['verb'] == ACTIVITY_LIKE) || ($datarray['verb'] == ACTIVITY_DISLIKE)) { if(($datarray['verb'] === ACTIVITY_LIKE)
|| ($datarray['verb'] === ACTIVITY_DISLIKE)
|| ($datarray['verb'] === ACTIVITY_ATTEND)
|| ($datarray['verb'] === ACTIVITY_ATTENDNO)
|| ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
$datarray['type'] = 'activity'; $datarray['type'] = 'activity';
$datarray['gravity'] = GRAVITY_LIKE; $datarray['gravity'] = GRAVITY_LIKE;
// only one like or dislike per person // only one like or dislike per person
@ -4022,12 +4031,13 @@ function local_delivery($importer,$data) {
if((x($datarray,'object-type')) && ($datarray['object-type'] === ACTIVITY_OBJ_EVENT)) { if((x($datarray,'object-type')) && ($datarray['object-type'] === ACTIVITY_OBJ_EVENT)) {
$ev = bbtoevent($datarray['body']); $ev = bbtoevent($datarray['body']);
if(x($ev,'desc') && x($ev,'start')) { if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
$ev['cid'] = $importer['id']; $ev['cid'] = $importer['id'];
$ev['uid'] = $importer['uid']; $ev['uid'] = $importer['uid'];
$ev['uri'] = $item_id; $ev['uri'] = $item_id;
$ev['edited'] = $datarray['edited']; $ev['edited'] = $datarray['edited'];
$ev['private'] = $datarray['private']; $ev['private'] = $datarray['private'];
$ev['guid'] = $datarray['guid'];
$r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1", $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
dbesc($item_id), dbesc($item_id),
@ -4187,14 +4197,13 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
); );
} }
// send email notification to owner? // send email notification to owner?
} } else {
else {
// create contact record // create contact record
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `name`, `nick`, `photo`, `network`, `rel`, $r = q("INSERT INTO `contact` (`uid`, `created`, `url`, `nurl`, `name`, `nick`, `photo`, `network`, `rel`,
`blocked`, `readonly`, `pending`, `writable` ) `blocked`, `readonly`, `pending`, `writable`)
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 0, 1, 1 ) ", VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, 0, 0, 1, 1)",
intval($importer['uid']), intval($importer['uid']),
dbesc(datetime_convert()), dbesc(datetime_convert()),
dbesc($url), dbesc($url),
@ -4209,9 +4218,26 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
intval($importer['uid']), intval($importer['uid']),
dbesc($url) dbesc($url)
); );
if(count($r)) if(count($r)) {
$contact_record = $r[0]; $contact_record = $r[0];
$photos = import_profile_photo($photo,$importer["uid"],$contact_record["id"]);
q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s' WHERE `id` = %d",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
intval($contact_record["id"])
);
}
$r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
intval($importer['uid'])
);
$a = get_app();
if(count($r) AND !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
// create notification // create notification
$hash = random_string(); $hash = random_string();
@ -4225,19 +4251,13 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
); );
} }
$r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
intval($importer['uid'])
);
$a = get_app();
if(count($r)) {
if(intval($r[0]['def_gid'])) { if(intval($r[0]['def_gid'])) {
require_once('include/group.php'); require_once('include/group.php');
group_add_member($r[0]['uid'],'',$contact_record['id'],$r[0]['def_gid']); group_add_member($r[0]['uid'],'',$contact_record['id'],$r[0]['def_gid']);
} }
if(($r[0]['notify-flags'] & NOTIFY_INTRO) && if(($r[0]['notify-flags'] & NOTIFY_INTRO) &&
in_array($r[0]['page-flags'], array(PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE))) { in_array($r[0]['page-flags'], array(PAGE_NORMAL))) {
notification(array( notification(array(
'type' => NOTIFY_INTRO, 'type' => NOTIFY_INTRO,
@ -4255,7 +4275,13 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
)); ));
} }
} elseif (count($r) AND in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
$r = q("UPDATE `contact` SET `pending` = 0 WHERE `uid` = %d AND `url` = '%s' AND `pending` LIMIT 1",
intval($importer['uid']),
dbesc($url)
);
} }
} }
} }
@ -4329,7 +4355,7 @@ function subscribe_to_hub($url,$importer,$contact,$hubmode = 'subscribe') {
} }
function atom_author($tag,$name,$uri,$h,$w,$photo) { function atom_author($tag,$name,$uri,$h,$w,$photo,$geo) {
$o = ''; $o = '';
if(! $tag) if(! $tag)
return $o; return $o;
@ -4347,6 +4373,10 @@ function atom_author($tag,$name,$uri,$h,$w,$photo) {
$o .= "\t".'<link rel="avatar" type="image/jpeg" media:width="' . $w . '" media:height="' . $h . '" href="' . $photo . '" />' . "\r\n"; $o .= "\t".'<link rel="avatar" type="image/jpeg" media:width="' . $w . '" media:height="' . $h . '" href="' . $photo . '" />' . "\r\n";
if ($tag == "author") { if ($tag == "author") {
if($geo)
$o .= '<georss:point>'.xmlify($geo).'</georss:point>'."\r\n";
$r = q("SELECT `profile`.`locality`, `profile`.`region`, `profile`.`country-name`, $r = q("SELECT `profile`.`locality`, `profile`.`region`, `profile`.`country-name`,
`profile`.`name`, `profile`.`pub_keywords`, `profile`.`about`, `profile`.`name`, `profile`.`pub_keywords`, `profile`.`about`,
`profile`.`homepage`,`contact`.`nick` FROM `profile` `profile`.`homepage`,`contact`.`nick` FROM `profile`
@ -4372,7 +4402,7 @@ function atom_author($tag,$name,$uri,$h,$w,$photo) {
$o .= "\t<poco:preferredUsername>".xmlify($r[0]["nick"])."</poco:preferredUsername>\r\n"; $o .= "\t<poco:preferredUsername>".xmlify($r[0]["nick"])."</poco:preferredUsername>\r\n";
$o .= "\t<poco:displayName>".xmlify($r[0]["name"])."</poco:displayName>\r\n"; $o .= "\t<poco:displayName>".xmlify($r[0]["name"])."</poco:displayName>\r\n";
$o .= "\t<poco:note>".xmlify($r[0]["about"])."</poco:note>\r\n"; $o .= "\t<poco:note>".xmlify(bbcode($r[0]["about"]))."</poco:note>\r\n";
$o .= "\t<poco:address>\r\n"; $o .= "\t<poco:address>\r\n";
$o .= "\t\t<poco:formatted>".xmlify($location)."</poco:formatted>\r\n"; $o .= "\t\t<poco:formatted>".xmlify($location)."</poco:formatted>\r\n";
$o .= "\t</poco:address>\r\n"; $o .= "\t</poco:address>\r\n";
@ -4410,11 +4440,11 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
$o = "\r\n\r\n<entry>\r\n"; $o = "\r\n\r\n<entry>\r\n";
if(is_array($author)) if(is_array($author))
$o .= atom_author('author',$author['name'],$author['url'],80,80,$author['thumb']); $o .= atom_author('author',$author['name'],$author['url'],80,80,$author['thumb'], $item['coord']);
else else
$o .= atom_author('author',(($item['author-name']) ? $item['author-name'] : $item['name']),(($item['author-link']) ? $item['author-link'] : $item['url']),80,80,(($item['author-avatar']) ? $item['author-avatar'] : $item['thumb'])); $o .= atom_author('author',(($item['author-name']) ? $item['author-name'] : $item['name']),(($item['author-link']) ? $item['author-link'] : $item['url']),80,80,(($item['author-avatar']) ? $item['author-avatar'] : $item['thumb']), $item['coord']);
if(strlen($item['owner-name'])) if(strlen($item['owner-name']))
$o .= atom_author('dfrn:owner',$item['owner-name'],$item['owner-link'],80,80,$item['owner-avatar']); $o .= atom_author('dfrn:owner',$item['owner-name'],$item['owner-link'],80,80,$item['owner-avatar'], $item['coord']);
if(($item['parent'] != $item['id']) || ($item['parent-uri'] !== $item['uri']) || (($item['thr-parent'] !== '') && ($item['thr-parent'] !== $item['uri']))) { if(($item['parent'] != $item['id']) || ($item['parent-uri'] !== $item['uri']) || (($item['thr-parent'] !== '') && ($item['thr-parent'] !== $item['uri']))) {
$parent = q("SELECT `guid` FROM `item` WHERE `id` = %d", intval($item["parent"])); $parent = q("SELECT `guid` FROM `item` WHERE `id` = %d", intval($item["parent"]));
@ -4491,7 +4521,8 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
//$o .= "\t".'<link rel="self" type="application/atom+xml" href="'.xmlify($a->get_baseurl().'/api/statuses/show/'.$item['id'].'.atom').'"/>'."\r\n"; //$o .= "\t".'<link rel="self" type="application/atom+xml" href="'.xmlify($a->get_baseurl().'/api/statuses/show/'.$item['id'].'.atom').'"/>'."\r\n";
//$o .= "\t".'<link rel="edit" type="application/atom+xml" href="'.xmlify($a->get_baseurl().'/api/statuses/show/'.$item['id'].'.atom').'"/>'."\r\n"; //$o .= "\t".'<link rel="edit" type="application/atom+xml" href="'.xmlify($a->get_baseurl().'/api/statuses/show/'.$item['id'].'.atom').'"/>'."\r\n";
$o .= item_get_attachment($item); // Deactivated since it was meant only for OStatus
//$o .= item_get_attachment($item);
$o .= item_getfeedattach($item); $o .= item_getfeedattach($item);
@ -4656,7 +4687,7 @@ function item_getfeedtags($item) {
if($cnt) { if($cnt) {
for($x = 0; $x < $cnt; $x ++) { for($x = 0; $x < $cnt; $x ++) {
if($matches[1][$x]) if($matches[1][$x])
$ret[] = array('#',$matches[1][$x], $matches[2][$x]); $ret[$matches[2][$x]] = array('#',$matches[1][$x], $matches[2][$x]);
} }
} }
$matches = false; $matches = false;

View file

@ -27,7 +27,6 @@ function nav(&$a) {
$a->page['nav'] .= replace_macros($tpl, array( $a->page['nav'] .= replace_macros($tpl, array(
'$baseurl' => $a->get_baseurl(), '$baseurl' => $a->get_baseurl(),
'$langselector' => lang_selector(),
'$sitelocation' => $nav_info['sitelocation'], '$sitelocation' => $nav_info['sitelocation'],
'$nav' => $nav_info['nav'], '$nav' => $nav_info['nav'],
'$banner' => $nav_info['banner'], '$banner' => $nav_info['banner'],
@ -138,6 +137,8 @@ function nav_info(&$a) {
elseif(get_config('system','community_page_style') == CP_GLOBAL_COMMUNITY) elseif(get_config('system','community_page_style') == CP_GLOBAL_COMMUNITY)
$nav['community'] = array('community', t('Community'), "", t('Conversations on the network')); $nav['community'] = array('community', t('Community'), "", t('Conversations on the network'));
$nav['events'] = Array('events', t('Events'), "", t('Events and Calendar'));
$nav['directory'] = array($gdirpath, t('Directory'), "", t('People directory')); $nav['directory'] = array($gdirpath, t('Directory'), "", t('People directory'));
$nav['about'] = Array('friendica', t('Information'), "", t('Information about this friendica instance')); $nav['about'] = Array('friendica', t('Information'), "", t('Information about this friendica instance'));
@ -238,6 +239,7 @@ function nav_set_selected($item){
'settings' => null, 'settings' => null,
'contacts' => null, 'contacts' => null,
'manage' => null, 'manage' => null,
'events' => null,
'register' => null, 'register' => null,
); );
$a->nav_sel[$item] = 'selected'; $a->nav_sel[$item] = 'selected';

View file

@ -86,10 +86,9 @@ function z_fetch_url($url,$binary = false, &$redirects = 0, $opts=array()) {
if(x($opts,'nobody')){ if(x($opts,'nobody')){
@curl_setopt($ch, CURLOPT_NOBODY, $opts['nobody']); @curl_setopt($ch, CURLOPT_NOBODY, $opts['nobody']);
} }
if(intval($timeout)) { if(x($opts,'timeout')){
@curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); @curl_setopt($ch, CURLOPT_TIMEOUT, $opts['timeout']);
} } else {
else {
$curl_time = intval(get_config('system','curl_timeout')); $curl_time = intval(get_config('system','curl_timeout'));
@curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60)); @curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60));
} }
@ -309,16 +308,25 @@ function xml_status($st, $message = '') {
if(! function_exists('http_status_exit')) { if(! function_exists('http_status_exit')) {
function http_status_exit($val) { function http_status_exit($val, $description = array()) {
$err = ''; $err = '';
if($val >= 400) if($val >= 400) {
$err = 'Error'; $err = 'Error';
if (!isset($description["title"]))
$description["title"] = $err." ".$val;
}
if($val >= 200 && $val < 300) if($val >= 200 && $val < 300)
$err = 'OK'; $err = 'OK';
logger('http_status_exit ' . $val); logger('http_status_exit ' . $val);
header($_SERVER["SERVER_PROTOCOL"] . ' ' . $val . ' ' . $err); header($_SERVER["SERVER_PROTOCOL"] . ' ' . $val . ' ' . $err);
if (isset($description["title"])) {
$tpl = get_markup_template('http_status.tpl');
echo replace_macros($tpl, array('$title' => $description["title"],
'$description' => $description["description"]));
}
killme(); killme();
}} }}

View file

@ -4,6 +4,7 @@ require_once('include/queue_fn.php');
require_once('include/html2plain.php'); require_once('include/html2plain.php');
require_once("include/Scrape.php"); require_once("include/Scrape.php");
require_once('include/diaspora.php'); require_once('include/diaspora.php');
require_once("include/ostatus.php");
/* /*
* This file was at one time responsible for doing all deliveries, but this caused * This file was at one time responsible for doing all deliveries, but this caused
@ -529,7 +530,8 @@ function notifier_run(&$argv, &$argc){
unset($photos); unset($photos);
} else { } else {
$slap = atom_entry($target_item,'html',null,$owner,false); $slap = ostatus_salmon($target_item,$owner);
//$slap = atom_entry($target_item,'html',null,$owner,false);
if($followup) { if($followup) {
foreach($items as $item) { // there is only one item foreach($items as $item) { // there is only one item
@ -569,7 +571,8 @@ function notifier_run(&$argv, &$argc){
$atom .= atom_entry($item,'text',null,$owner,true); $atom .= atom_entry($item,'text',null,$owner,true);
if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire)) if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
$slaps[] = atom_entry($item,'html',null,$owner,true); $slaps[] = ostatus_salmon($item,$owner);
//$slaps[] = atom_entry($item,'html',null,$owner,true);
} }
} }
} }
@ -615,6 +618,10 @@ function notifier_run(&$argv, &$argc){
$interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval'))); $interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
// If we are using the worker we don't need a delivery interval
if (get_config("system", "worker"))
$interval = false;
// delivery loop // delivery loop
if(count($r)) { if(count($r)) {
@ -642,8 +649,10 @@ function notifier_run(&$argv, &$argc){
// together into a single process. This will reduce the overall number of processes // together into a single process. This will reduce the overall number of processes
// spawned for each delivery, but they will run longer. // spawned for each delivery, but they will run longer.
// When using the workerqueue, we don't need this functionality.
$deliveries_per_process = intval(get_config('system','delivery_batch_count')); $deliveries_per_process = intval(get_config('system','delivery_batch_count'));
if($deliveries_per_process <= 0) if (($deliveries_per_process <= 0) OR get_config("system", "worker"))
$deliveries_per_process = 1; $deliveries_per_process = 1;
$this_batch = array(); $this_batch = array();
@ -728,9 +737,9 @@ function notifier_run(&$argv, &$argc){
$ssl_policy = get_config('system','ssl_policy'); $ssl_policy = get_config('system','ssl_policy');
fix_contact_ssl_policy($x[0],$ssl_policy); fix_contact_ssl_policy($x[0],$ssl_policy);
// If we are setup as a soapbox we aren't accepting input from this person // If we are setup as a soapbox we aren't accepting top level posts from this person
if($x[0]['page-flags'] == PAGE_SOAPBOX) if (($x[0]['page-flags'] == PAGE_SOAPBOX) AND $top_level)
break; break;
require_once('library/simplepie/simplepie.inc'); require_once('library/simplepie/simplepie.inc');
@ -902,11 +911,16 @@ function notifier_run(&$argv, &$argc){
if(! $contact['pubkey']) if(! $contact['pubkey'])
break; break;
if($target_item['verb'] === ACTIVITY_DISLIKE) { $unsupported_activities = array(ACTIVITY_DISLIKE, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE);
// unsupported
break; //don't transmit activities which are not supported by diaspora
foreach($unsupported_activities as $act) {
if(activity_match($target_item['verb'],$act)) {
break 2;
} }
elseif(($target_item['deleted']) && (($target_item['uri'] === $target_item['parent-uri']) || $followup)) { }
if(($target_item['deleted']) && (($target_item['uri'] === $target_item['parent-uri']) || $followup)) {
// send both top-level retractions and relayable retractions for owner to relay // send both top-level retractions and relayable retractions for owner to relay
diaspora_send_retraction($target_item,$owner,$contact); diaspora_send_retraction($target_item,$owner,$contact);
break; break;

View file

@ -157,7 +157,7 @@ function oembed_format_object($j){
case "rich": { case "rich": {
// not so safe.. // not so safe..
if (!get_config("system","no_oembed_rich_content")) if (!get_config("system","no_oembed_rich_content"))
$ret.= $jhtml; $ret.= proxy_parse_html($jhtml);
}; break; }; break;
} }

View file

@ -168,8 +168,18 @@ function onepoll_run(&$argv, &$argc){
); );
// Update the contact entry // Update the contact entry
if(($contact['network'] === NETWORK_OSTATUS) || ($contact['network'] === NETWORK_DIASPORA) || ($contact['network'] === NETWORK_DFRN)) if(($contact['network'] === NETWORK_OSTATUS) || ($contact['network'] === NETWORK_DIASPORA) || ($contact['network'] === NETWORK_DFRN)) {
update_contact($contact["id"]); if (!poco_reachable($contact['url'])) {
logger("Skipping probably dead contact ".$contact['url']);
return;
}
if (!update_contact($contact["id"])) {
mark_for_death($contact);
return;
} else
unmark_for_death($contact);
}
if($contact['network'] === NETWORK_DFRN) { if($contact['network'] === NETWORK_DFRN) {
@ -360,7 +370,7 @@ function onepoll_run(&$argv, &$argc){
); );
logger("Mail: Connected to " . $mailconf[0]['user']); logger("Mail: Connected to " . $mailconf[0]['user']);
} else } else
logger("Mail: Connection error ".$mailconf[0]['user']." ".print_r(imap_errors())); logger("Mail: Connection error ".$mailconf[0]['user']." ".print_r(imap_errors(), true));
} }
if($mbox) { if($mbox) {

View file

@ -2,6 +2,7 @@
require_once("include/Contact.php"); require_once("include/Contact.php");
require_once("include/threads.php"); require_once("include/threads.php");
require_once("include/html2bbcode.php"); require_once("include/html2bbcode.php");
require_once("include/bbcode.php");
require_once("include/items.php"); require_once("include/items.php");
require_once("mod/share.php"); require_once("mod/share.php");
require_once("include/enotify.php"); require_once("include/enotify.php");
@ -9,11 +10,21 @@ require_once("include/socgraph.php");
require_once("include/Photo.php"); require_once("include/Photo.php");
require_once("include/Scrape.php"); require_once("include/Scrape.php");
require_once("include/follow.php"); require_once("include/follow.php");
require_once("mod/proxy.php");
define('OSTATUS_DEFAULT_POLL_INTERVAL', 30); // given in minutes define('OSTATUS_DEFAULT_POLL_INTERVAL', 30); // given in minutes
define('OSTATUS_DEFAULT_POLL_TIMEFRAME', 1440); // given in minutes define('OSTATUS_DEFAULT_POLL_TIMEFRAME', 1440); // given in minutes
define('OSTATUS_DEFAULT_POLL_TIMEFRAME_MENTIONS', 14400); // given in minutes define('OSTATUS_DEFAULT_POLL_TIMEFRAME_MENTIONS', 14400); // given in minutes
define("NS_ATOM", "http://www.w3.org/2005/Atom");
define("NS_THR", "http://purl.org/syndication/thread/1.0");
define("NS_GEORSS", "http://www.georss.org/georss");
define("NS_ACTIVITY", "http://activitystrea.ms/spec/1.0/");
define("NS_MEDIA", "http://purl.org/syndication/atommedia");
define("NS_POCO", "http://portablecontacts.net/spec/1.0");
define("NS_OSTATUS", "http://ostatus.org/schema/1.0");
define("NS_STATUSNET", "http://status.net/schema/api/1/");
function ostatus_check_follow_friends() { function ostatus_check_follow_friends() {
$r = q("SELECT `uid`,`v` FROM `pconfig` WHERE `cat`='system' AND `k`='ostatus_legacy_contact' AND `v` != ''"); $r = q("SELECT `uid`,`v` FROM `pconfig` WHERE `cat`='system' AND `k`='ostatus_legacy_contact' AND `v` != ''");
@ -131,15 +142,15 @@ function ostatus_fetchauthor($xpath, $context, $importer, &$contact, $onlyfetch)
$value = $xpath->evaluate('atom:author/poco:note/text()', $context)->item(0)->nodeValue; $value = $xpath->evaluate('atom:author/poco:note/text()', $context)->item(0)->nodeValue;
if ($value != "") if ($value != "")
$contact["about"] = $value; $contact["about"] = html2bbcode($value);
$value = $xpath->evaluate('atom:author/poco:address/poco:formatted/text()', $context)->item(0)->nodeValue; $value = $xpath->evaluate('atom:author/poco:address/poco:formatted/text()', $context)->item(0)->nodeValue;
if ($value != "") if ($value != "")
$contact["location"] = $value; $contact["location"] = $value;
q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `about` = '%s', `location` = '%s', `name-date` = '%s' WHERE `id` = %d", q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `about` = '%s', `location` = '%s', `name-date` = '%s' WHERE `id` = %d AND `network` = '%s'",
dbesc($contact["name"]), dbesc($contact["nick"]), dbesc($contact["about"]), dbesc($contact["location"]), dbesc($contact["name"]), dbesc($contact["nick"]), dbesc($contact["about"]), dbesc($contact["location"]),
dbesc(datetime_convert()), intval($contact["id"])); dbesc(datetime_convert()), intval($contact["id"]), dbesc(NETWORK_OSTATUS));
poco_check($contact["url"], $contact["name"], $contact["network"], $author["author-avatar"], $contact["about"], $contact["location"], poco_check($contact["url"], $contact["name"], $contact["network"], $author["author-avatar"], $contact["about"], $contact["location"],
"", "", "", datetime_convert(), 2, $contact["id"], $contact["uid"]); "", "", "", datetime_convert(), 2, $contact["id"], $contact["uid"]);
@ -152,9 +163,9 @@ function ostatus_fetchauthor($xpath, $context, $importer, &$contact, $onlyfetch)
$photos = import_profile_photo($author["author-avatar"], $importer["uid"], $contact["id"]); $photos = import_profile_photo($author["author-avatar"], $importer["uid"], $contact["id"]);
q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s', `avatar-date` = '%s' WHERE `id` = %d", q("UPDATE `contact` SET `photo` = '%s', `thumb` = '%s', `micro` = '%s', `avatar-date` = '%s' WHERE `id` = %d AND `network` = '%s'",
dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]),
dbesc(datetime_convert()), intval($contact["id"])); dbesc(datetime_convert()), intval($contact["id"]), dbesc(NETWORK_OSTATUS));
} }
} }
@ -702,9 +713,13 @@ function ostatus_completion($conversation_url, $uid, $item = array()) {
$conv_as = str_replace(',"statusnet:notice_info":', ',"statusnet_notice_info":', $conv_as); $conv_as = str_replace(',"statusnet:notice_info":', ',"statusnet_notice_info":', $conv_as);
$conv_as = json_decode($conv_as); $conv_as = json_decode($conv_as);
$no_of_items = sizeof($items);
if (@is_array($conv_as->items)) if (@is_array($conv_as->items))
$items = array_merge($items, $conv_as->items); foreach ($conv_as->items AS $single_item)
else $items[$single_item->id] = $single_item;
if ($no_of_items == sizeof($items))
break; break;
$pageno++; $pageno++;
@ -1063,4 +1078,461 @@ function ostatus_store_conversation($itemid, $conversation_url) {
logger('Storing conversation url '.$conversation_url.' for id '.$itemid); logger('Storing conversation url '.$conversation_url.' for id '.$itemid);
} }
} }
function xml_add_element($doc, $parent, $element, $value = "", $attributes = array()) {
$element = $doc->createElement($element, xmlify($value));
foreach ($attributes AS $key => $value) {
$attribute = $doc->createAttribute($key);
$attribute->value = xmlify($value);
$element->appendChild($attribute);
}
$parent->appendChild($element);
}
function ostatus_format_picture_post($body) {
$siteinfo = get_attached_data($body);
if (($siteinfo["type"] == "photo")) {
if (isset($siteinfo["preview"]))
$preview = $siteinfo["preview"];
else
$preview = $siteinfo["image"];
// Is it a remote picture? Then make a smaller preview here
$preview = proxy_url($preview, false, PROXY_SIZE_SMALL);
// Is it a local picture? Then make it smaller here
$preview = str_replace(array("-0.jpg", "-0.png"), array("-2.jpg", "-2.png"), $preview);
$preview = str_replace(array("-1.jpg", "-1.png"), array("-2.jpg", "-2.png"), $preview);
if (isset($siteinfo["url"]))
$url = $siteinfo["url"];
else
$url = $siteinfo["image"];
$body = trim($siteinfo["text"])." [url]".$url."[/url]\n[img]".$preview."[/img]";
}
return $body;
}
function ostatus_add_header($doc, $owner) {
$a = get_app();
$r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default`",
intval($owner["uid"]));
if (!$r)
return;
$profile = $r[0];
$root = $doc->createElementNS(NS_ATOM, 'feed');
$doc->appendChild($root);
$root->setAttribute("xmlns:thr", NS_THR);
$root->setAttribute("xmlns:georss", NS_GEORSS);
$root->setAttribute("xmlns:activity", NS_ACTIVITY);
$root->setAttribute("xmlns:media", NS_MEDIA);
$root->setAttribute("xmlns:poco", NS_POCO);
$root->setAttribute("xmlns:ostatus", NS_OSTATUS);
$root->setAttribute("xmlns:statusnet", NS_STATUSNET);
$attributes = array("uri" => "https://friendi.ca", "version" => FRIENDICA_VERSION."-".DB_UPDATE_VERSION);
xml_add_element($doc, $root, "generator", FRIENDICA_PLATFORM, $attributes);
xml_add_element($doc, $root, "id", $a->get_baseurl()."/profile/".$owner["nick"]);
xml_add_element($doc, $root, "title", sprintf("%s timeline", $profile["name"]));
xml_add_element($doc, $root, "subtitle", sprintf("Updates from %s on %s", $profile["name"], $a->config["sitename"]));
xml_add_element($doc, $root, "logo", $profile["photo"]);
xml_add_element($doc, $root, "updated", datetime_convert("UTC", "UTC", "now", ATOM_TIME));
$author = ostatus_add_author($doc, $owner, $profile);
$root->appendChild($author);
$attributes = array("href" => $owner["url"], "rel" => "alternate", "type" => "text/html");
xml_add_element($doc, $root, "link", "", $attributes);
// To-Do: We have to find out what this is
//$attributes = array("href" => $a->get_baseurl()."/sup",
// "rel" => "http://api.friendfeed.com/2008/03#sup",
// "type" => "application/json");
//xml_add_element($doc, $root, "link", "", $attributes);
ostatus_hublinks($doc, $root);
$attributes = array("href" => $a->get_baseurl()."/salmon/".$owner["nick"], "rel" => "salmon");
xml_add_element($doc, $root, "link", "", $attributes);
$attributes = array("href" => $a->get_baseurl()."/salmon/".$owner["nick"], "rel" => "http://salmon-protocol.org/ns/salmon-replies");
xml_add_element($doc, $root, "link", "", $attributes);
$attributes = array("href" => $a->get_baseurl()."/salmon/".$owner["nick"], "rel" => "http://salmon-protocol.org/ns/salmon-mention");
xml_add_element($doc, $root, "link", "", $attributes);
$attributes = array("href" => $a->get_baseurl()."/api/statuses/user_timeline/".$owner["nick"].".atom",
"rel" => "self", "type" => "application/atom+xml");
xml_add_element($doc, $root, "link", "", $attributes);
return $root;
}
function ostatus_hublinks($doc, $root) {
$a = get_app();
$hub = get_config('system','huburl');
$hubxml = '';
if(strlen($hub)) {
$hubs = explode(',', $hub);
if(count($hubs)) {
foreach($hubs as $h) {
$h = trim($h);
if(! strlen($h))
continue;
if ($h === '[internal]')
$h = $a->get_baseurl() . '/pubsubhubbub';
xml_add_element($doc, $root, "link", "", array("href" => $h, "rel" => "hub"));
}
}
}
}
function ostatus_get_attachment($doc, $root, $item) {
$o = "";
$siteinfo = get_attached_data($item["body"]);
switch($siteinfo["type"]) {
case 'link':
$attributes = array("rel" => "enclosure",
"href" => $siteinfo["url"],
"type" => "text/html; charset=UTF-8",
"length" => "",
"title" => $siteinfo["title"]);
xml_add_element($doc, $root, "link", "", $attributes);
break;
case 'photo':
$imgdata = get_photo_info($siteinfo["image"]);
$attributes = array("rel" => "enclosure",
"href" => $siteinfo["image"],
"type" => $imgdata["mime"],
"length" => intval($imgdata["size"]));
xml_add_element($doc, $root, "link", "", $attributes);
break;
case 'video':
$attributes = array("rel" => "enclosure",
"href" => $siteinfo["url"],
"type" => "text/html; charset=UTF-8",
"length" => "",
"title" => $siteinfo["title"]);
xml_add_element($doc, $root, "link", "", $attributes);
break;
default:
break;
}
if (($siteinfo["type"] != "photo") AND isset($siteinfo["image"])) {
$photodata = get_photo_info($siteinfo["image"]);
$attributes = array("rel" => "preview", "href" => $siteinfo["image"], "media:width" => $photodata[0], "media:height" => $photodata[1]);
xml_add_element($doc, $root, "link", "", $attributes);
}
$arr = explode('[/attach],',$item['attach']);
if(count($arr)) {
foreach($arr as $r) {
$matches = false;
$cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r,$matches);
if($cnt) {
$attributes = array("rel" => "enclosure",
"href" => $matches[1],
"type" => $matches[3]);
if(intval($matches[2]))
$attributes["length"] = intval($matches[2]);
if(trim($matches[4]) != "")
$attributes["title"] = trim($matches[4]);
xml_add_element($doc, $root, "link", "", $attributes);
}
}
}
}
function ostatus_add_author($doc, $owner, $profile) {
$a = get_app();
$author = $doc->createElement("author");
xml_add_element($doc, $author, "activity:object-type", ACTIVITY_OBJ_PERSON);
xml_add_element($doc, $author, "uri", $owner["url"]);
xml_add_element($doc, $author, "name", $profile["name"]);
$attributes = array("rel" => "alternate", "type" => "text/html", "href" => $owner["url"]);
xml_add_element($doc, $author, "link", "", $attributes);
$attributes = array(
"rel" => "avatar",
"type" => "image/jpeg", // To-Do?
"media:width" => 175,
"media:height" => 175,
"href" => $profile["photo"]);
xml_add_element($doc, $author, "link", "", $attributes);
$attributes = array(
"rel" => "avatar",
"type" => "image/jpeg", // To-Do?
"media:width" => 80,
"media:height" => 80,
"href" => $profile["thumb"]);
xml_add_element($doc, $author, "link", "", $attributes);
xml_add_element($doc, $author, "poco:preferredUsername", $owner["nick"]);
xml_add_element($doc, $author, "poco:displayName", $profile["name"]);
xml_add_element($doc, $author, "poco:note", bbcode($profile["about"]));
if (trim($owner["location"]) != "") {
$element = $doc->createElement("poco:address");
xml_add_element($doc, $element, "poco:formatted", $owner["location"]);
$author->appendChild($element);
}
if (trim($profile["homepage"]) != "") {
$urls = $doc->createElement("poco:urls");
xml_add_element($doc, $urls, "poco:type", "homepage");
xml_add_element($doc, $urls, "poco:value", $profile["homepage"]);
xml_add_element($doc, $urls, "poco:primary", "true");
$author->appendChild($urls);
}
xml_add_element($doc, $author, "followers", "", array("url" => $a->get_baseurl()."/viewcontacts/".$owner["nick"]));
xml_add_element($doc, $author, "statusnet:profile_info", "", array("local_id" => $owner["uid"]));
return $author;
}
/*
To-Do: Picture attachments should look like this:
<a href="https://status.pirati.ca/attachment/572819" title="https://status.pirati.ca/file/heluecht-20151202T222602-rd3u49p.gif"
class="attachment thumbnail" id="attachment-572819" rel="nofollow external">https://status.pirati.ca/attachment/572819</a>
*/
function ostatus_entry($doc, $item, $owner, $toplevel = false) {
$a = get_app();
if (!$toplevel) {
$entry = $doc->createElement("entry");
$title = sprintf("New note by %s", $owner["nick"]);
} else {
$entry = $doc->createElementNS(NS_ATOM, "entry");
$entry->setAttribute("xmlns:thr", NS_THR);
$entry->setAttribute("xmlns:georss", NS_GEORSS);
$entry->setAttribute("xmlns:activity", NS_ACTIVITY);
$entry->setAttribute("xmlns:media", NS_MEDIA);
$entry->setAttribute("xmlns:poco", NS_POCO);
$entry->setAttribute("xmlns:ostatus", NS_OSTATUS);
$entry->setAttribute("xmlns:statusnet", NS_STATUSNET);
$r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default`",
intval($owner["uid"]));
if (!$r)
return;
$profile = $r[0];
$author = ostatus_add_author($doc, $owner, $profile);
$entry->appendChild($author);
$title = sprintf("New comment by %s", $owner["nick"]);
}
// To use the object-type "bookmark" we have to implement these elements:
//
// <activity:object-type>http://activitystrea.ms/schema/1.0/bookmark</activity:object-type>
// <title>Historic Rocket Landing</title>
// <summary>Nur ein Testbeitrag.</summary>
// <link rel="related" href="https://www.youtube.com/watch?v=9pillaOxGCo"/>
// <link rel="preview" href="https://pirati.cc/file/thumb-4526-450x338-b48c8055f0c2fed0c3f67adc234c4b99484a90c42ed3cac73dc1081a4d0a7bc1.jpg.jpg" media:width="450" media:height="338"/>
//
// But: it seems as if it doesn't federate well between the GS servers
// So we just set it to "note" to be sure that it reaches their target systems
xml_add_element($doc, $entry, "activity:object-type", ACTIVITY_OBJ_NOTE);
xml_add_element($doc, $entry, "id", $item["uri"]);
xml_add_element($doc, $entry, "title", $title);
if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid'])
$body = fix_private_photos($item['body'],$owner['uid'],$item, 0);
else
$body = $item['body'];
$body = ostatus_format_picture_post($body);
if ($item['title'] != "")
$body = "[b]".$item['title']."[/b]\n\n".$body;
//$body = bb_remove_share_information($body);
$body = bbcode($body, false, false, 7);
xml_add_element($doc, $entry, "content", $body, array("type" => "html"));
xml_add_element($doc, $entry, "link", "", array("rel" => "alternate", "type" => "text/html",
"href" => $a->get_baseurl()."/display/".$item["guid"]));
xml_add_element($doc, $entry, "status_net", "", array("notice_id" => $item["id"]));
xml_add_element($doc, $entry, "activity:verb", construct_verb($item));
xml_add_element($doc, $entry, "published", datetime_convert("UTC","UTC",$item["created"]."+00:00",ATOM_TIME));
xml_add_element($doc, $entry, "updated", datetime_convert("UTC","UTC",$item["edited"]."+00:00",ATOM_TIME));
$mentioned = array();
if (($item['parent'] != $item['id']) || ($item['parent-uri'] !== $item['uri']) || (($item['thr-parent'] !== '') && ($item['thr-parent'] !== $item['uri']))) {
$parent = q("SELECT `guid` FROM `item` WHERE `id` = %d", intval($item["parent"]));
$parent_item = (($item['thr-parent']) ? $item['thr-parent'] : $item['parent-uri']);
$attributes = array(
"ref" => $parent_item,
"type" => "text/html",
"href" => $a->get_baseurl()."/display/".$parent[0]["guid"]);
xml_add_element($doc, $entry, "thr:in-reply-to", "", $attributes);
$attributes = array(
"rel" => "related",
"href" => $a->get_baseurl()."/display/".$parent[0]["guid"]);
xml_add_element($doc, $entry, "link", "", $attributes);
$mentioned[$parent[0]["author-link"]] = $parent[0]["author-link"];
$mentioned[$parent[0]["owner-link"]] = $parent[0]["owner-link"];
$thrparent = q("SELECT `guid`, `author-link`, `owner-link` FROM `item` WHERE `uid` = %d AND `uri` = '%s'",
intval($owner["uid"]),
dbesc($parent_item));
if ($thrparent) {
$mentioned[$thrparent[0]["author-link"]] = $thrparent[0]["author-link"];
$mentioned[$thrparent[0]["owner-link"]] = $thrparent[0]["owner-link"];
}
}
xml_add_element($doc, $entry, "link", "", array("rel" => "ostatus:conversation",
"href" => $a->get_baseurl()."/display/".$owner["nick"]."/".$item["parent"]));
xml_add_element($doc, $entry, "ostatus:conversation", $a->get_baseurl()."/display/".$owner["nick"]."/".$item["parent"]);
$tags = item_getfeedtags($item);
if(count($tags))
foreach($tags as $t)
if ($t[0] == "@")
$mentioned[$t[1]] = $t[1];
// Make sure that mentions are accepted (GNU Social has problems with mixing HTTP and HTTPS)
$newmentions = array();
foreach ($mentioned AS $mention) {
$newmentions[str_replace("http://", "https://", $mention)] = str_replace("http://", "https://", $mention);
$newmentions[str_replace("https://", "http://", $mention)] = str_replace("https://", "http://", $mention);
}
$mentioned = $newmentions;
foreach ($mentioned AS $mention) {
$r = q("SELECT `forum`, `prv` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s'",
intval($owner["uid"]),
dbesc(normalise_link($mention)));
if ($r[0]["forum"] OR $r[0]["prv"])
xml_add_element($doc, $entry, "link", "", array("rel" => "mentioned",
"ostatus:object-type" => ACTIVITY_OBJ_GROUP,
"href" => $mention));
else
xml_add_element($doc, $entry, "link", "", array("rel" => "mentioned",
"ostatus:object-type" => ACTIVITY_OBJ_PERSON,
"href" => $mention));
}
if (!$item["private"])
xml_add_element($doc, $entry, "link", "", array("rel" => "mentioned",
"ostatus:object-type" => "http://activitystrea.ms/schema/1.0/collection",
"href" => "http://activityschema.org/collection/public"));
if(count($tags))
foreach($tags as $t)
if ($t[0] != "@")
xml_add_element($doc, $entry, "category", "", array("term" => $t[2]));
ostatus_get_attachment($doc, $entry, $item);
// To-Do:
// The API call has yet to be implemented
//$attributes = array("href" => $a->get_baseurl()."/api/statuses/show/".$item["id"].".atom",
// "rel" => "self", "type" => "application/atom+xml");
//xml_add_element($doc, $entry, "link", "", $attributes);
//$attributes = array("href" => $a->get_baseurl()."/api/statuses/show/".$item["id"].".atom",
// "rel" => "edit", "type" => "application/atom+xml");
//xml_add_element($doc, $entry, "link", "", $attributes);
$app = $item["app"];
if ($app == "")
$app = "web";
xml_add_element($doc, $entry, "statusnet:notice_info", "", array("local_id" => $item["id"], "source" => $app));
return $entry;
}
function ostatus_feed(&$a, $owner_nick, $last_update) {
$r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`self` AND `user`.`nickname` = '%s' LIMIT 1",
dbesc($owner_nick));
if (!$r)
return;
$owner = $r[0];
if(!strlen($last_update))
$last_update = 'now -30 days';
$check_date = datetime_convert('UTC','UTC',$last_update,'Y-m-d H:i:s');
$items = q("SELECT STRAIGHT_JOIN `item`.*, `item`.`id` AS `item_id` FROM `item`
INNER JOIN `thread` ON `thread`.`iid` = `item`.`parent`
LEFT JOIN `item` AS `thritem` ON `thritem`.`uri`=`item`.`thr-parent` AND `thritem`.`uid`=`item`.`uid`
WHERE `item`.`uid` = %d AND `item`.`received` > '%s' AND NOT `item`.`private` AND NOT `item`.`deleted`
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
AND ((`item`.`wall` AND (`item`.`parent` = `item`.`id`))
OR (`item`.`network` = '%s' AND ((`thread`.`network`='%s') OR (`thritem`.`network` = '%s'))) AND `thread`.`mention`)
AND (`item`.`owner-link` IN ('%s', '%s'))
ORDER BY `item`.`received` DESC
LIMIT 0, 300",
intval($owner["uid"]), dbesc($check_date),
dbesc(NETWORK_DFRN), dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS),
dbesc($owner["nurl"]), dbesc(str_replace("http://", "https://", $owner["nurl"]))
);
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
$root = ostatus_add_header($doc, $owner);
foreach ($items AS $item) {
$entry = ostatus_entry($doc, $item, $owner);
$root->appendChild($entry);
}
return(trim($doc->saveXML()));
}
function ostatus_salmon($item,$owner) {
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
$entry = ostatus_entry($doc, $item, $owner, true);
$doc->appendChild($entry);
return(trim($doc->saveXML()));
}
?> ?>

View file

@ -161,3 +161,26 @@ function string_plural_select_default($n) {
return ($n != 1); return ($n != 1);
}} }}
/**
* Return installed languages as associative array
* [
* lang => lang,
* ...
* ]
*/
function get_avaiable_languages() {
$lang_choices = array();
$langs = glob('view/*/strings.php'); /**/
if(is_array($langs) && count($langs)) {
if(! in_array('view/en/strings.php',$langs))
$langs[] = 'view/en/';
asort($langs);
foreach($langs as $l) {
$t = explode("/",$l);
$lang_choices[$t[1]] = $t[1];
}
}
return $lang_choices;
}

27
include/photos.php Normal file
View file

@ -0,0 +1,27 @@
<?php
/**
* @file include/photos.php
* @brief Functions related to photo handling.
*/
function getGps($exifCoord, $hemi) {
$degrees = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
$minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0;
$seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0;
$flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1;
return floatval($flip * ($degrees + ($minutes / 60) + ($seconds / 3600)));
}
function gps2Num($coordPart) {
$parts = explode('/', $coordPart);
if (count($parts) <= 0)
return 0;
if (count($parts) == 1)
return $parts[0];
return floatval($parts[0]) / floatval($parts[1]);
}

View file

@ -7,8 +7,8 @@ class pidfile {
$this->_file = "$dir/$name.pid"; $this->_file = "$dir/$name.pid";
if (file_exists($this->_file)) { if (file_exists($this->_file)) {
$pid = trim(file_get_contents($this->_file)); $pid = trim(@file_get_contents($this->_file));
if (posix_kill($pid, 0)) { if (($pid != "") AND posix_kill($pid, 0)) {
$this->_running = true; $this->_running = true;
} }
} }
@ -21,7 +21,7 @@ class pidfile {
public function __destruct() { public function __destruct() {
if ((! $this->_running) && file_exists($this->_file)) { if ((! $this->_running) && file_exists($this->_file)) {
unlink($this->_file); @unlink($this->_file);
} }
} }
@ -30,7 +30,7 @@ class pidfile {
} }
public function running_time() { public function running_time() {
return(time() - filectime($this->_file)); return(time() - @filectime($this->_file));
} }
public function kill() { public function kill() {

View file

@ -55,9 +55,10 @@ function get_attached_data($body) {
$data = parseurl_getsiteinfo_cached($pictures[0][1], true); $data = parseurl_getsiteinfo_cached($pictures[0][1], true);
if ($data["type"] == "photo") { if ($data["type"] == "photo") {
$post["type"] = "photo"; $post["type"] = "photo";
if (isset($data["images"][0])) if (isset($data["images"][0])) {
$post["image"] = $data["images"][0]["src"]; $post["image"] = $data["images"][0]["src"];
else $post["url"] = $data["url"];
} else
$post["image"] = $data["url"]; $post["image"] = $data["url"];
$post["preview"] = $pictures[0][2]; $post["preview"] = $pictures[0][2];

View file

@ -1,7 +1,17 @@
<?php <?php
/**
* @file include/identity.php
*
* @brief Some functions to handle addons and themes.
*/
// install and uninstall plugin /**
* @brief uninstalls an addon.
*
* @param string $plugin name of the addon
* @return boolean
*/
if (! function_exists('uninstall_plugin')){ if (! function_exists('uninstall_plugin')){
function uninstall_plugin($plugin){ function uninstall_plugin($plugin){
logger("Addons: uninstalling " . $plugin); logger("Addons: uninstalling " . $plugin);
@ -16,6 +26,12 @@ function uninstall_plugin($plugin){
} }
}} }}
/**
* @brief installs an addon.
*
* @param string $plugin name of the addon
* @return bool
*/
if (! function_exists('install_plugin')){ if (! function_exists('install_plugin')){
function install_plugin($plugin) { function install_plugin($plugin) {
// silently fail if plugin was removed // silently fail if plugin was removed
@ -42,7 +58,7 @@ function install_plugin($plugin) {
// This way the system won't fall over dead during the update. // This way the system won't fall over dead during the update.
if(file_exists('addon/' . $plugin . '/.hidden')) { if(file_exists('addon/' . $plugin . '/.hidden')) {
q("update addon set hidden = 1 where name = '%s'", q("UPDATE `addon` SET `hidden` = 1 WHERE `name` = '%s'",
dbesc($plugin) dbesc($plugin)
); );
} }
@ -105,10 +121,27 @@ function reload_plugins() {
}} }}
/**
* @brief check if addon is enabled
*
* @param string $plugin
* @return boolean
*/
function plugin_enabled($plugin) {
$r = q("SELECT * FROM `addon` WHERE `installed` = 1 AND `name` = '%s'", $plugin);
return((bool)(count($r) > 0));
}
/**
* @brief registers a hook.
*
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook will call
* @param int $priority A priority (defaults to 0)
* @return mixed|bool
*/
if(! function_exists('register_hook')) { if(! function_exists('register_hook')) {
function register_hook($hook,$file,$function,$priority=0) { function register_hook($hook,$file,$function,$priority=0) {
@ -129,6 +162,14 @@ function register_hook($hook,$file,$function,$priority=0) {
return $r; return $r;
}} }}
/**
* @brief unregisters a hook.
*
* @param string $hook the name of the hook
* @param string $file the name of the file that hooks into
* @param string $function the name of the function that the hook called
* @return array
*/
if(! function_exists('unregister_hook')) { if(! function_exists('unregister_hook')) {
function unregister_hook($hook,$file,$function) { function unregister_hook($hook,$file,$function) {
@ -155,7 +196,15 @@ function load_hooks() {
} }
}} }}
/**
* @brief Calls a hook.
*
* Use this function when you want to be able to allow a hook to manipulate
* the provided data.
*
* @param string $name of the hook to call
* @param string|array &$data to transmit to the callback handler
*/
if(! function_exists('call_hooks')) { if(! function_exists('call_hooks')) {
function call_hooks($name, &$data = null) { function call_hooks($name, &$data = null) {
$stamp1 = microtime(true); $stamp1 = microtime(true);
@ -178,7 +227,7 @@ function call_hooks($name, &$data = null) {
} }
else { else {
// remove orphan hooks // remove orphan hooks
q("delete from hook where hook = '%s' and file = '%s' and function = '%s'", q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'",
dbesc($name), dbesc($name),
dbesc($hook[0]), dbesc($hook[0]),
dbesc($hook[1]) dbesc($hook[1])
@ -204,16 +253,20 @@ function plugin_is_app($name) {
return false; return false;
}} }}
/* /**
* parse plugin comment in search of plugin infos. * @brief Parse plugin comment in search of plugin infos.
* like
* *
* * Name: Plugin * like
* \code
*...* Name: Plugin
* * Description: A plugin which plugs in * * Description: A plugin which plugs in
* * Version: 1.2.3 * . * Version: 1.2.3
* * Author: John <profile url> * * Author: John <profile url>
* * Author: Jane <email> * * Author: Jane <email>
* * * *
* *\endcode
* @param string $plugin the name of the plugin
* @return array with the plugin information
*/ */
if (! function_exists('get_plugin_info')){ if (! function_exists('get_plugin_info')){
@ -265,16 +318,20 @@ function get_plugin_info($plugin){
}} }}
/* /**
* parse theme comment in search of theme infos. * @brief Parse theme comment in search of theme infos.
* like
* *
* * Name: My Theme * like
* \code
* ..* Name: My Theme
* * Description: My Cool Theme * * Description: My Cool Theme
* * Version: 1.2.3 * . * Version: 1.2.3
* * Author: John <profile url> * * Author: John <profile url>
* * Maintainer: Jane <profile url> * * Maintainer: Jane <profile url>
* * * *
* \endcode
* @param string $theme the name of the theme
* @return array
*/ */
if (! function_exists('get_theme_info')){ if (! function_exists('get_theme_info')){
@ -340,7 +397,14 @@ function get_theme_info($theme){
return $info; return $info;
}} }}
/**
* @brief Returns the theme's screenshot.
*
* The screenshot is expected as view/theme/$theme/screenshot.[png|jpg].
*
* @param sring $theme The name of the theme
* @return string
*/
function get_theme_screenshot($theme) { function get_theme_screenshot($theme) {
$a = get_app(); $a = get_app();
$exts = array('.png','.jpg'); $exts = array('.png','.jpg');
@ -402,7 +466,7 @@ function service_class_allows($uid,$property,$usage = false) {
$service_class = $a->user['service_class']; $service_class = $a->user['service_class'];
} }
else { else {
$r = q("select service_class from user where uid = %d limit 1", $r = q("SELECT `service_class` FROM `user` WHERE `uid` = %d LIMIT 1",
intval($uid) intval($uid)
); );
if($r !== false and count($r)) { if($r !== false and count($r)) {
@ -432,7 +496,7 @@ function service_class_fetch($uid,$property) {
$service_class = $a->user['service_class']; $service_class = $a->user['service_class'];
} }
else { else {
$r = q("select service_class from user where uid = %d limit 1", $r = q("SELECT `service_class` FROM `user` WHERE `uid` = %d LIMIT 1",
intval($uid) intval($uid)
); );
if($r !== false and count($r)) { if($r !== false and count($r)) {

View file

@ -12,7 +12,6 @@ if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
require_once("boot.php"); require_once("boot.php");
function poller_run(&$argv, &$argc){ function poller_run(&$argv, &$argc){
global $a, $db; global $a, $db;
@ -27,297 +26,142 @@ function poller_run(&$argv, &$argc){
unset($db_host, $db_user, $db_pass, $db_data); unset($db_host, $db_user, $db_pass, $db_data);
}; };
$load = current_load();
require_once('include/session.php'); if($load) {
require_once('include/datetime.php');
require_once('library/simplepie/simplepie.inc');
require_once('include/items.php');
require_once('include/Contact.php');
require_once('include/email.php');
require_once('include/socgraph.php');
require_once('include/pidfile.php');
require_once('mod/nodeinfo.php');
load_config('config');
load_config('system');
$maxsysload = intval(get_config('system','maxloadavg')); $maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1) if($maxsysload < 1)
$maxsysload = 50; $maxsysload = 50;
if(function_exists('sys_getloadavg')) {
$load = sys_getloadavg(); if(intval($load) > $maxsysload) {
if(intval($load[0]) > $maxsysload) { logger('system: load ' . $load . ' too high. poller deferred to next scheduled run.');
logger('system: load ' . $load[0] . ' too high. Poller deferred to next scheduled run.');
return; return;
} }
} }
$lockpath = get_lockpath(); // Checking the number of workers
if ($lockpath != '') { if (poller_too_much_workers(1))
$pidfile = new pidfile($lockpath, 'poller'); return;
if($pidfile->is_already_running()) {
logger("poller: Already running"); if(($argc <= 1) OR ($argv[1] != "no_cron")) {
if ($pidfile->running_time() > 9*60) { // Run the cron job that calls all other jobs
$pidfile->kill(); proc_run("php","include/cron.php");
logger("poller: killed stale process");
// Calling a new instance // Run the cronhooks job separately from cron for being able to use a different timing
proc_run('php','include/poller.php'); proc_run("php","include/cronhooks.php");
}
exit; // Cleaning dead processes
} $r = q("SELECT DISTINCT(`pid`) FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
foreach($r AS $pid)
if (!posix_kill($pid["pid"], 0))
q("UPDATE `workerqueue` SET `executed` = '0000-00-00 00:00:00', `pid` = 0 WHERE `pid` = %d",
intval($pid["pid"]));
else {
// To-Do: Kill long running processes
// But: Update processes (like the database update) mustn't be killed
} }
$a->set_baseurl(get_config('system','url'));
load_hooks();
logger('poller: start');
// run queue delivery process in the background
proc_run('php',"include/queue.php");
// run diaspora photo queue process in the background
proc_run('php',"include/dsprphotoq.php");
// run the process to discover global contacts in the background
proc_run('php',"include/discover_poco.php");
// run the process to update locally stored global contacts in the background
proc_run('php',"include/discover_poco.php", "checkcontact");
// expire any expired accounts
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` != '0000-00-00 00:00:00'
AND `account_expires_on` < UTC_TIMESTAMP() ");
// delete user and contact records for recently removed accounts
$r = q("SELECT * FROM `user` WHERE `account_removed` = 1 AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if ($r) {
foreach($r as $user) {
q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
}
}
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
// Check OStatus conversations
// Check only conversations with mentions (for a longer time)
check_conversations(true);
// Check every conversation
check_conversations(false);
// Follow your friends from your legacy OStatus account
ostatus_check_follow_friends();
// update nodeinfo data
nodeinfo_cron();
// To-Do: Regenerate usage statistics
// q("ANALYZE TABLE `item`");
// once daily run birthday_updates and then expire in background
$d1 = get_config('system','last_expire_day');
$d2 = intval(datetime_convert('UTC','UTC','now','d'));
if($d2 != intval($d1)) {
update_contact_birthdays();
update_suggestions();
set_config('system','last_expire_day',$d2);
proc_run('php','include/expire.php');
}
$last = get_config('system','cache_last_cleared');
if($last) {
$next = $last + (3600); // Once per hour
$clear_cache = ($next <= time());
} else } else
$clear_cache = true; // Sleep four seconds before checking for running processes again to avoid having too many workers
sleep(4);
if ($clear_cache) { // Checking number of workers
// clear old cache if (poller_too_much_workers(2))
Cache::clear();
// clear old item cache files
clear_cache();
// clear cache for photos
clear_cache($a->get_basepath(), $a->get_basepath()."/photo");
// clear smarty cache
clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled");
// clear cache for image proxy
if (!get_config("system", "proxy_disabled")) {
clear_cache($a->get_basepath(), $a->get_basepath()."/proxy");
$cachetime = get_config('system','proxy_cache_time');
if (!$cachetime) $cachetime = PROXY_DEFAULT_TIME;
q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime);
}
set_config('system','cache_last_cleared', time());
}
$manual_id = 0;
$generation = 0;
$force = false;
$restart = false;
if(($argc > 1) && ($argv[1] == 'force'))
$force = true;
if(($argc > 1) && ($argv[1] == 'restart')) {
$restart = true;
$generation = intval($argv[2]);
if(! $generation)
killme();
}
if(($argc > 1) && intval($argv[1])) {
$manual_id = intval($argv[1]);
$force = true;
}
$interval = intval(get_config('system','poll_interval'));
if(! $interval)
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
$sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
reload_plugins();
$d = datetime_convert();
if(! $restart)
proc_run('php','include/cronhooks.php');
// Only poll from those with suitable relationships,
// and which have a polling address and ignore Diaspora since
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
$abandon_sql = (($abandon_days)
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
: ''
);
$contacts = q("SELECT `contact`.`id` FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `rel` IN (%d, %d) AND `poll` != '' AND `network` IN ('%s', '%s', '%s', '%s', '%s', '%s')
$sql_extra
AND NOT `self` AND NOT `contact`.`blocked` AND NOT `contact`.`readonly` AND NOT `contact`.`archive`
AND NOT `user`.`account_expired` AND NOT `user`.`account_removed` $abandon_sql ORDER BY RAND()",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_ZOT),
dbesc(NETWORK_OSTATUS),
dbesc(NETWORK_FEED),
dbesc(NETWORK_MAIL),
dbesc(NETWORK_MAIL2)
);
if(! count($contacts)) {
return; return;
}
foreach($contacts as $c) { $starttime = time();
$res = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", while ($r = q("SELECT * FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `created` LIMIT 1")) {
intval($c['id'])
);
if((! $res) || (! count($res))) // Count active workers and compare them with a maximum value that depends on the load
continue; if (poller_too_much_workers(3))
return;
foreach($res as $contact) { q("UPDATE `workerqueue` SET `executed` = '%s', `pid` = %d WHERE `id` = %d AND `executed` = '0000-00-00 00:00:00'",
dbesc(datetime_convert()),
intval(getmypid()),
intval($r[0]["id"]));
$xml = false; // Assure that there are no tasks executed twice
$id = q("SELECT `id` FROM `workerqueue` WHERE `id` = %d AND `pid` = %d",
if($manual_id) intval($r[0]["id"]),
$contact['last-update'] = '0000-00-00 00:00:00'; intval(getmypid()));
if (!$id) {
if(in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) logger("Queue item ".$r[0]["id"]." was executed multiple times - skip this execution", LOGGER_DEBUG);
$contact['priority'] = 2;
if($contact['subhub'] AND in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) {
// We should be getting everything via a hub. But just to be sure, let's check once a day.
// (You can make this more or less frequent if desired by setting 'pushpoll_frequency' appropriately)
// This also lets us update our subscription to the hub, and add or replace hubs in case it
// changed. We will only update hubs once a day, regardless of 'pushpoll_frequency'.
$poll_interval = get_config('system','pushpoll_frequency');
$contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3);
}
if($contact['priority'] AND !$force) {
$update = false;
$t = $contact['last-update'];
/**
* Based on $contact['priority'], should we poll this site now? Or later?
*/
switch ($contact['priority']) {
case 5:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 month"))
$update = true;
break;
case 4:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 week"))
$update = true;
break;
case 3:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
$update = true;
break;
case 2:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 12 hour"))
$update = true;
break;
case 1:
default:
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 hour"))
$update = true;
break;
}
if(!$update)
continue; continue;
} }
logger("Polling ".$contact["network"]." ".$contact["id"]." ".$contact["nick"]." ".$contact["name"]); $argv = json_decode($r[0]["parameter"]);
proc_run('php','include/onepoll.php',$contact['id']); $argc = count($argv);
if($interval) // Check for existance and validity of the include file
@time_sleep_until(microtime(true) + (float) $interval); $include = $argv[0];
}
if (!validate_include($include)) {
logger("Include file ".$argv[0]." is not valid!");
q("DELETE FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
continue;
} }
logger('poller: end'); require_once($include);
$funcname=str_replace(".php", "", basename($argv[0]))."_run";
if (function_exists($funcname)) {
logger("Process ".getmypid()." - ID ".$r[0]["id"].": ".$funcname." ".$r[0]["parameter"]);
$funcname($argv, $argc);
logger("Process ".getmypid()." - ID ".$r[0]["id"].": ".$funcname." - done");
q("DELETE FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
} else
logger("Function ".$funcname." does not exist");
// Quit the poller once every hour
if (time() > ($starttime + 3600))
return; return;
}
}
function poller_too_much_workers($stage) {
$queues = get_config("system", "worker_queues");
if ($queues == 0)
$queues = 4;
$active = poller_active_workers();
// Decrease the number of workers at higher load
$load = current_load();
if($load) {
$maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1)
$maxsysload = 50;
$maxworkers = $queues;
// Some magical mathemathics to reduce the workers
$exponent = 3;
$slope = $maxworkers / pow($maxsysload, $exponent);
$queues = ceil($slope * pow(max(0, $maxsysload - $load), $exponent));
logger("Current load stage ".$stage.": ".$load." - maximum: ".$maxsysload." - current queues: ".$active." - maximum: ".$queues, LOGGER_DEBUG);
}
return($active >= $queues);
}
function poller_active_workers() {
$workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
return($workers[0]["workers"]);
} }
if (array_search(__file__,get_included_files())===0){ if (array_search(__file__,get_included_files())===0){
poller_run($_SERVER["argv"],$_SERVER["argc"]); poller_run($_SERVER["argv"],$_SERVER["argc"]);
killme(); killme();
} }
?>

View file

@ -1,5 +1,6 @@
<?php <?php
require_once("boot.php"); require_once("boot.php");
require_once("include/ostatus.php");
function handle_pubsubhubbub() { function handle_pubsubhubbub() {
global $a, $db; global $a, $db;
@ -12,17 +13,17 @@ function handle_pubsubhubbub() {
$r = q("SELECT * FROM `push_subscriber` WHERE `push` > 0"); $r = q("SELECT * FROM `push_subscriber` WHERE `push` > 0");
foreach($r as $rr) { foreach($r as $rr) {
$params = get_feed_for($a, '', $rr['nickname'], $rr['last_update'], 0, true); //$params = get_feed_for($a, '', $rr['nickname'], $rr['last_update'], 0, true);
$params = ostatus_feed($a, $rr['nickname'], $rr['last_update']);
$hmac_sig = hash_hmac("sha1", $params, $rr['secret']); $hmac_sig = hash_hmac("sha1", $params, $rr['secret']);
$headers = array("Content-type: application/atom+xml", $headers = array("Content-type: application/atom+xml",
sprintf("Link: <%s>;rel=hub," . sprintf("Link: <%s>;rel=hub,<%s>;rel=self",
"<%s>;rel=self", $a->get_baseurl().'/pubsubhubbub',
$a->get_baseurl() . '/pubsubhubbub',
$rr['topic']), $rr['topic']),
"X-Hub-Signature: sha1=" . $hmac_sig); "X-Hub-Signature: sha1=".$hmac_sig);
logger('POST '. print_r($headers, true)."\n".$params, LOGGER_DEBUG); logger('POST '.print_r($headers, true)."\n".$params, LOGGER_DEBUG);
post_url($rr['callback_url'], $params, $headers); post_url($rr['callback_url'], $params, $headers);
$ret = $a->get_curl_code(); $ret = $a->get_curl_code();

View file

@ -22,6 +22,7 @@ function queue_run(&$argv, &$argc){
require_once('include/items.php'); require_once('include/items.php');
require_once('include/bbcode.php'); require_once('include/bbcode.php');
require_once('include/pidfile.php'); require_once('include/pidfile.php');
require_once('include/socgraph.php');
load_config('config'); load_config('config');
load_config('system'); load_config('system');
@ -59,6 +60,10 @@ function queue_run(&$argv, &$argc){
$interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval'))); $interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
// If we are using the worker we don't need a delivery interval
if (get_config("system", "worker"))
$interval = false;
$r = q("select * from deliverq where 1"); $r = q("select * from deliverq where 1");
if($r) { if($r) {
foreach($r as $rr) { foreach($r as $rr) {
@ -137,6 +142,12 @@ function queue_run(&$argv, &$argc){
continue; continue;
} }
if (!poco_reachable($c[0]['url'])) {
logger('queue: skipping probably dead url: ' . $c[0]['url']);
update_queue_time($q_item['id']);
continue;
}
$u = q("SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey` $u = q("SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`
FROM `user` WHERE `uid` = %d LIMIT 1", FROM `user` WHERE `uid` = %d LIMIT 1",
intval($c[0]['uid']) intval($c[0]['uid'])

View file

@ -66,8 +66,6 @@ function get_salmon_key($uri,$keyhash) {
function slapper($owner,$url,$slap) { function slapper($owner,$url,$slap) {
logger('slapper called for '.$url.'. Data: ' . $slap);
// does contact have a salmon endpoint? // does contact have a salmon endpoint?
if(! strlen($url)) if(! strlen($url))
@ -97,6 +95,8 @@ EOT;
$slap = str_replace('<entry>',$namespaces,$slap); $slap = str_replace('<entry>',$namespaces,$slap);
logger('slapper called for '.$url.'. Data: ' . $slap);
// create a magic envelope // create a magic envelope
$data = base64url_encode($slap); $data = base64url_encode($slap);

View file

@ -225,15 +225,17 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
$created = $x[0]["created"]; $created = $x[0]["created"];
$server_url = $x[0]["server_url"]; $server_url = $x[0]["server_url"];
$nick = $x[0]["nick"]; $nick = $x[0]["nick"];
$addr = $x[0]["addr"];
} else { } else {
$created = "0000-00-00 00:00:00"; $created = "0000-00-00 00:00:00";
$server_url = ""; $server_url = "";
$urlparts = parse_url($profile_url); $urlparts = parse_url($profile_url);
$nick = end(explode("/", $urlparts["path"])); $nick = end(explode("/", $urlparts["path"]));
$addr = "";
} }
if ((($network == "") OR ($name == "") OR ($profile_photo == "") OR ($server_url == "") OR $alternate) if ((($network == "") OR ($name == "") OR ($addr == "") OR ($profile_photo == "") OR ($server_url == "") OR $alternate)
AND poco_reachable($profile_url, $server_url, $network, false)) { AND poco_reachable($profile_url, $server_url, $network, false)) {
$data = probe_url($profile_url); $data = probe_url($profile_url);
@ -242,6 +244,7 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
$network = $data["network"]; $network = $data["network"];
$name = $data["name"]; $name = $data["name"];
$nick = $data["nick"]; $nick = $data["nick"];
$addr = $data["addr"];
$profile_url = $data["url"]; $profile_url = $data["url"];
$profile_photo = $data["photo"]; $profile_photo = $data["photo"];
$server_url = $data["baseurl"]; $server_url = $data["baseurl"];
@ -294,14 +297,18 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
if (($keywords == "") AND ($x[0]['keywords'] != "")) if (($keywords == "") AND ($x[0]['keywords'] != ""))
$keywords = $x[0]['keywords']; $keywords = $x[0]['keywords'];
if (($addr == "") AND ($x[0]['addr'] != ""))
$addr = $x[0]['addr'];
if (($generation == 0) AND ($x[0]['generation'] > 0)) if (($generation == 0) AND ($x[0]['generation'] > 0))
$generation = $x[0]['generation']; $generation = $x[0]['generation'];
if($x[0]['name'] != $name || $x[0]['photo'] != $profile_photo || $x[0]['updated'] < $updated) { if($x[0]['name'] != $name || $x[0]['photo'] != $profile_photo || $x[0]['updated'] < $updated) {
q("UPDATE `gcontact` SET `name` = '%s', `network` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s', `server_url` = '%s', q("UPDATE `gcontact` SET `name` = '%s', `addr` = '%s', `network` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s', `server_url` = '%s',
`updated` = '%s', `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s', `generation` = %d `updated` = '%s', `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s', `generation` = %d
WHERE (`generation` >= %d OR `generation` = 0) AND `nurl` = '%s'", WHERE (`generation` >= %d OR `generation` = 0) AND `nurl` = '%s'",
dbesc($name), dbesc($name),
dbesc($addr),
dbesc($network), dbesc($network),
dbesc($profile_photo), dbesc($profile_photo),
dbesc($connect_url), dbesc($connect_url),
@ -318,10 +325,11 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
); );
} }
} else { } else {
q("INSERT INTO `gcontact` (`name`, `nick`, `network`, `url`, `nurl`, `photo`, `connect`, `server_url`, `created`, `updated`, `location`, `about`, `keywords`, `gender`, `generation`) q("INSERT INTO `gcontact` (`name`, `nick`, `addr`, `network`, `url`, `nurl`, `photo`, `connect`, `server_url`, `created`, `updated`, `location`, `about`, `keywords`, `gender`, `generation`)
VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)",
dbesc($name), dbesc($name),
dbesc($nick), dbesc($nick),
dbesc($addr),
dbesc($network), dbesc($network),
dbesc($profile_url), dbesc($profile_url),
dbesc(normalise_link($profile_url)), dbesc(normalise_link($profile_url)),
@ -570,7 +578,7 @@ function poco_last_updated($profile, $force = false) {
return false; return false;
} }
if (($data["poll"] == "") OR ($data["network"] == NETWORK_FEED)) { if (($data["poll"] == "") OR (in_array($data["network"], array(NETWORK_FEED, NETWORK_PHANTOM)))) {
q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'", q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'",
dbesc(datetime_convert()), dbesc(normalise_link($profile))); dbesc(datetime_convert()), dbesc(normalise_link($profile)));
return false; return false;
@ -748,8 +756,11 @@ function poco_check_server($server_url, $network = "", $force = false) {
} }
if (!$serverret["success"] OR ($serverret["body"] == "") OR (sizeof($xmlobj) == 0) OR !is_object($xmlobj)) { if (!$serverret["success"] OR ($serverret["body"] == "") OR (sizeof($xmlobj) == 0) OR !is_object($xmlobj)) {
// Workaround for bad configured servers (known nginx problem)
if ($serverret["debug"]["http_code"] != "403") {
$last_failure = datetime_convert(); $last_failure = datetime_convert();
$failure = true; $failure = true;
}
} elseif ($network == NETWORK_DIASPORA) } elseif ($network == NETWORK_DIASPORA)
$last_contact = datetime_convert(); $last_contact = datetime_convert();
@ -1036,8 +1047,9 @@ function count_common_friends($uid,$cid) {
$r = q("SELECT count(*) as `total` $r = q("SELECT count(*) as `total`
FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`cid` = %d and `glink`.`uid` = %d WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ", ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
AND `gcontact`.`nurl` IN (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ",
intval($cid), intval($cid),
intval($uid), intval($uid),
intval($uid), intval($uid),
@ -1059,11 +1071,15 @@ function common_friends($uid,$cid,$start = 0,$limit=9999,$shuffle = false) {
else else
$sql_extra = " order by `gcontact`.`name` asc "; $sql_extra = " order by `gcontact`.`name` asc ";
$r = q("SELECT `gcontact`.* $r = q("SELECT `gcontact`.*, `contact`.`id` AS `cid`
FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` FROM `glink`
where `glink`.`cid` = %d and `glink`.`uid` = %d INNER JOIN `gcontact` ON `glink`.`gcid` = `gcontact`.`id`
and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) INNER JOIN `contact` ON `gcontact`.`nurl` = `contact`.`nurl`
$sql_extra limit %d, %d", WHERE `glink`.`cid` = %d and `glink`.`uid` = %d
AND `contact`.`uid` = %d AND `contact`.`self` = 0 AND `contact`.`blocked` = 0
AND `contact`.`hidden` = 0 AND `contact`.`id` != %d
AND ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
$sql_extra LIMIT %d, %d",
intval($cid), intval($cid),
intval($uid), intval($uid),
intval($uid), intval($uid),
@ -1120,7 +1136,8 @@ function count_all_friends($uid,$cid) {
$r = q("SELECT count(*) as `total` $r = q("SELECT count(*) as `total`
FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`cid` = %d and `glink`.`uid` = %d ", where `glink`.`cid` = %d and `glink`.`uid` = %d AND
((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))",
intval($cid), intval($cid),
intval($uid) intval($uid)
); );
@ -1134,10 +1151,14 @@ function count_all_friends($uid,$cid) {
function all_friends($uid,$cid,$start = 0, $limit = 80) { function all_friends($uid,$cid,$start = 0, $limit = 80) {
$r = q("SELECT `gcontact`.* $r = q("SELECT `gcontact`.*, `contact`.`id` AS `cid`
FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id` FROM `glink`
where `glink`.`cid` = %d and `glink`.`uid` = %d INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
order by `gcontact`.`name` asc LIMIT %d, %d ", LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` AND `contact`.`uid` = %d
WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
ORDER BY `gcontact`.`name` ASC LIMIT %d, %d ",
intval($uid),
intval($cid), intval($cid),
intval($uid), intval($uid),
intval($start), intval($start),
@ -1167,14 +1188,14 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
$sql_network = "'".$sql_network."'"; $sql_network = "'".$sql_network."'";
$r = q("SELECT count(glink.gcid) as `total`, gcontact.* from gcontact $r = q("SELECT count(glink.gcid) as `total`, gcontact.* from gcontact
INNER JOIN glink on glink.gcid = gcontact.id INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
where uid = %d and not gcontact.nurl in ( select nurl from contact where uid = %d ) where uid = %d and not gcontact.nurl in ( select nurl from contact where uid = %d )
and not gcontact.name in ( select name from contact where uid = %d ) AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d)
and not gcontact.id in ( select gcid from gcign where uid = %d ) AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d)
AND `gcontact`.`updated` != '0000-00-00 00:00:00' AND `gcontact`.`updated` != '0000-00-00 00:00:00'
AND `gcontact`.`last_contact` >= `gcontact`.`last_failure` AND `gcontact`.`last_contact` >= `gcontact`.`last_failure`
AND `gcontact`.`network` IN (%s) AND `gcontact`.`network` IN (%s)
group by glink.gcid order by gcontact.updated desc,total desc limit %d, %d ", GROUP BY `glink`.`gcid` ORDER BY `gcontact`.`updated` DESC,`total` DESC LIMIT %d, %d",
intval($uid), intval($uid),
intval($uid), intval($uid),
intval($uid), intval($uid),
@ -1187,14 +1208,15 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
if(count($r) && count($r) >= ($limit -1)) if(count($r) && count($r) >= ($limit -1))
return $r; return $r;
$r2 = q("SELECT gcontact.* from gcontact $r2 = q("SELECT gcontact.* FROM gcontact
INNER JOIN glink on glink.gcid = gcontact.id INNER JOIN `glink` ON `glink`.`gcid` = `gcontact`.`id`
where glink.uid = 0 and glink.cid = 0 and glink.zcid = 0 and not gcontact.nurl in ( select nurl from contact where uid = %d ) WHERE `glink`.`uid` = 0 AND `glink`.`cid` = 0 AND `glink`.`zcid` = 0 AND NOT `gcontact`.`nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` = %d)
and not gcontact.name in ( select name from contact where uid = %d ) AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d)
and not gcontact.id in ( select gcid from gcign where uid = %d ) AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d)
AND `gcontact`.`updated` != '0000-00-00 00:00:00' AND `gcontact`.`updated` != '0000-00-00 00:00:00'
AND `gcontact`.`last_contact` >= `gcontact`.`last_failure`
AND `gcontact`.`network` IN (%s) AND `gcontact`.`network` IN (%s)
order by rand() limit %d, %d ", ORDER BY rand() LIMIT %d, %d",
intval($uid), intval($uid),
intval($uid), intval($uid),
intval($uid), intval($uid),
@ -1210,6 +1232,9 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
foreach ($r AS $suggestion) foreach ($r AS $suggestion)
$list[$suggestion["nurl"]] = $suggestion; $list[$suggestion["nurl"]] = $suggestion;
while (sizeof($list) > ($limit))
array_pop($list);
return $list; return $list;
} }

View file

@ -21,6 +21,10 @@ function replace_macros($s,$r) {
$a = get_app(); $a = get_app();
// pass $baseurl to all templates
$r['$baseurl'] = z_root();
$t = $a->template_engine(); $t = $a->template_engine();
try { try {
$output = $t->replace_macros($s,$r); $output = $t->replace_macros($s,$r);
@ -281,7 +285,7 @@ function paginate_data(&$a, $count=null) {
if (($a->page_offset != "") AND !preg_match('/[?&].offset=/', $stripped)) if (($a->page_offset != "") AND !preg_match('/[?&].offset=/', $stripped))
$stripped .= "&offset=".urlencode($a->page_offset); $stripped .= "&offset=".urlencode($a->page_offset);
$url = $a->get_baseurl() . '/' . $stripped; $url = z_root() . '/' . $stripped;
$data = array(); $data = array();
function _l(&$d, $name, $url, $text, $class="") { function _l(&$d, $name, $url, $text, $class="") {
@ -939,13 +943,16 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) {
if($class) if($class)
$class = ' ' . $class; $class = ' ' . $class;
if ($contact["addr"] == "")
$contact["addr"] = $contact["url"];
$url = $contact['url']; $url = $contact['url'];
$sparkle = ''; $sparkle = '';
$redir = false; $redir = false;
if($redirect) { if($redirect) {
$a = get_app(); $a = get_app();
$redirect_url = $a->get_baseurl() . '/redir/' . $contact['id']; $redirect_url = z_root() . '/redir/' . $contact['id'];
if(local_user() && ($contact['uid'] == local_user()) && ($contact['network'] === NETWORK_DFRN)) { if(local_user() && ($contact['uid'] == local_user()) && ($contact['network'] === NETWORK_DFRN)) {
$redir = true; $redir = true;
$url = $redirect_url; $url = $redirect_url;
@ -962,7 +969,7 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) {
. (($click) ? ' fakelink' : '') . '" ' . (($click) ? ' fakelink' : '') . '" '
. (($redir) ? ' target="redir" ' : '') . (($redir) ? ' target="redir" ' : '')
. (($url) ? ' href="' . $url . '"' : '') . $click . (($url) ? ' href="' . $url . '"' : '') . $click
. '" title="' . $contact['name'] . ' [' . $contact['url'] . ']" alt="' . $contact['name'] . '" title="' . $contact['name'] . ' [' . $contact['addr'] . ']" alt="' . $contact['name']
. '" >'. $contact['name'] . '</a></div>' . "\r\n"; . '" >'. $contact['name'] . '</a></div>' . "\r\n";
} }
else { else {
@ -970,7 +977,7 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) {
. (($click) ? ' fakelink' : '') . '" ' . (($click) ? ' fakelink' : '') . '" '
. (($redir) ? ' target="redir" ' : '') . (($redir) ? ' target="redir" ' : '')
. (($url) ? ' href="' . $url . '"' : '') . $click . ' ><img class="contact-block-img' . $class . $sparkle . '" src="' . (($url) ? ' href="' . $url . '"' : '') . $click . ' ><img class="contact-block-img' . $class . $sparkle . '" src="'
. proxy_url($contact['micro']) . '" title="' . $contact['name'] . ' [' . $contact['url'] . ']" alt="' . $contact['name'] . proxy_url($contact['micro'], false, PROXY_SIZE_THUMB) . '" title="' . $contact['name'] . ' [' . $contact['addr'] . ']" alt="' . $contact['name']
. '" /></a></div>' . "\r\n"; . '" /></a></div>' . "\r\n";
} }
}} }}
@ -1020,8 +1027,9 @@ if(! function_exists('valid_email')) {
*/ */
function valid_email($x){ function valid_email($x){
if(get_config('system','disable_email_validation')) // Removed because Fabio told me so.
return true; //if(get_config('system','disable_email_validation'))
// return true;
if(preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/',$x)) if(preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/',$x))
return true; return true;
@ -1169,41 +1177,41 @@ function smilies($s, $sample = false) {
); );
$icons = array( $icons = array(
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-heart.gif" alt="&lt;3" />', '<img class="smiley" src="' . z_root() . '/images/smiley-heart.gif" alt="&lt;3" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-brokenheart.gif" alt="&lt;/3" />', '<img class="smiley" src="' . z_root() . '/images/smiley-brokenheart.gif" alt="&lt;/3" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-brokenheart.gif" alt="&lt;\\3" />', '<img class="smiley" src="' . z_root() . '/images/smiley-brokenheart.gif" alt="&lt;\\3" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-smile.gif" alt=":-)" />', '<img class="smiley" src="' . z_root() . '/images/smiley-smile.gif" alt=":-)" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-wink.gif" alt=";-)" />', '<img class="smiley" src="' . z_root() . '/images/smiley-wink.gif" alt=";-)" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-frown.gif" alt=":-(" />', '<img class="smiley" src="' . z_root() . '/images/smiley-frown.gif" alt=":-(" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-tongue-out.gif" alt=":-P" />', '<img class="smiley" src="' . z_root() . '/images/smiley-tongue-out.gif" alt=":-P" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-tongue-out.gif" alt=":-p" />', '<img class="smiley" src="' . z_root() . '/images/smiley-tongue-out.gif" alt=":-p" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-kiss.gif" alt=":-\"" />', '<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-\"" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-kiss.gif" alt=":-\"" />', '<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-\"" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-kiss.gif" alt=":-x" />', '<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-x" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-kiss.gif" alt=":-X" />', '<img class="smiley" src="' . z_root() . '/images/smiley-kiss.gif" alt=":-X" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-laughing.gif" alt=":-D" />', '<img class="smiley" src="' . z_root() . '/images/smiley-laughing.gif" alt=":-D" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt="8-|" />', '<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt="8-|" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt="8-O" />', '<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt="8-O" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-surprised.gif" alt=":-O" />', '<img class="smiley" src="' . z_root() . '/images/smiley-surprised.gif" alt=":-O" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-thumbsup.gif" alt="\\o/" />', '<img class="smiley" src="' . z_root() . '/images/smiley-thumbsup.gif" alt="\\o/" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-Oo.gif" alt="o.O" />', '<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="o.O" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-Oo.gif" alt="O.o" />', '<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="O.o" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-Oo.gif" alt="o_O" />', '<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="o_O" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-Oo.gif" alt="O_o" />', '<img class="smiley" src="' . z_root() . '/images/smiley-Oo.gif" alt="O_o" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-cry.gif" alt=":\'(" />', '<img class="smiley" src="' . z_root() . '/images/smiley-cry.gif" alt=":\'(" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-foot-in-mouth.gif" alt=":-!" />', '<img class="smiley" src="' . z_root() . '/images/smiley-foot-in-mouth.gif" alt=":-!" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-undecided.gif" alt=":-/" />', '<img class="smiley" src="' . z_root() . '/images/smiley-undecided.gif" alt=":-/" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-embarassed.gif" alt=":-[" />', '<img class="smiley" src="' . z_root() . '/images/smiley-embarassed.gif" alt=":-[" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-cool.gif" alt="8-)" />', '<img class="smiley" src="' . z_root() . '/images/smiley-cool.gif" alt="8-)" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/beer_mug.gif" alt=":beer" />', '<img class="smiley" src="' . z_root() . '/images/beer_mug.gif" alt=":beer" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/beer_mug.gif" alt=":homebrew" />', '<img class="smiley" src="' . z_root() . '/images/beer_mug.gif" alt=":homebrew" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/coffee.gif" alt=":coffee" />', '<img class="smiley" src="' . z_root() . '/images/coffee.gif" alt=":coffee" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-facepalm.gif" alt=":facepalm" />', '<img class="smiley" src="' . z_root() . '/images/smiley-facepalm.gif" alt=":facepalm" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/like.gif" alt=":like" />', '<img class="smiley" src="' . z_root() . '/images/like.gif" alt=":like" />',
'<img class="smiley" src="' . $a->get_baseurl() . '/images/dislike.gif" alt=":dislike" />', '<img class="smiley" src="' . z_root() . '/images/dislike.gif" alt=":dislike" />',
'<a href="http://friendica.com">~friendica <img class="smiley" src="' . $a->get_baseurl() . '/images/friendica-16.png" alt="~friendica" /></a>', '<a href="http://friendica.com">~friendica <img class="smiley" src="' . z_root() . '/images/friendica-16.png" alt="~friendica" /></a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . $a->get_baseurl() . '/images/rm-16.png" alt="red" />matrix</a>', '<a href="http://redmatrix.me/">red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="red" />matrix</a>',
'<a href="http://redmatrix.me/">red<img class="smiley" src="' . $a->get_baseurl() . '/images/rm-16.png" alt="red" />matrix</a>' '<a href="http://redmatrix.me/">red<img class="smiley" src="' . z_root() . '/images/rm-16.png" alt="red" />matrix</a>'
); );
$params = array('texts' => $texts, 'icons' => $icons, 'string' => $s); $params = array('texts' => $texts, 'icons' => $icons, 'string' => $s);
@ -1248,7 +1256,7 @@ function preg_heart($x) {
return $x[0]; return $x[0];
$t = ''; $t = '';
for($cnt = 0; $cnt < strlen($x[1]); $cnt ++) for($cnt = 0; $cnt < strlen($x[1]); $cnt ++)
$t .= '<img class="smiley" src="' . $a->get_baseurl() . '/images/smiley-heart.gif" alt="&lt;3" />'; $t .= '<img class="smiley" src="' . z_root() . '/images/smiley-heart.gif" alt="&lt;3" />';
$r = str_replace($x[0],$t,$x[0]); $r = str_replace($x[0],$t,$x[0]);
return $r; return $r;
} }
@ -1326,7 +1334,7 @@ function redir_private_images($a, &$item) {
if((local_user() == $item['uid']) && ($item['private'] != 0) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == NETWORK_DFRN)) { if((local_user() == $item['uid']) && ($item['private'] != 0) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == NETWORK_DFRN)) {
//logger("redir_private_images: redir"); //logger("redir_private_images: redir");
$img_url = $a->get_baseurl() . '/redir?f=1&quiet=1&url=' . $mtch[1] . '&conurl=' . $item['author-link']; $img_url = z_root() . '/redir?f=1&quiet=1&url=' . $mtch[1] . '&conurl=' . $item['author-link'];
$item['body'] = str_replace($mtch[0], "[img]".$img_url."[/img]", $item['body']); $item['body'] = str_replace($mtch[0], "[img]".$img_url."[/img]", $item['body']);
} }
} }
@ -1377,7 +1385,7 @@ function prepare_body(&$item,$attach = false, $preview = false) {
$a = get_app(); $a = get_app();
call_hooks('prepare_body_init', $item); call_hooks('prepare_body_init', $item);
$searchpath = $a->get_baseurl()."/search?tag="; $searchpath = z_root()."/search?tag=";
$tags=array(); $tags=array();
$hashtags = array(); $hashtags = array();
@ -1410,9 +1418,6 @@ function prepare_body(&$item,$attach = false, $preview = false) {
put_item_in_cache($item, true); put_item_in_cache($item, true);
$s = $item["rendered-html"]; $s = $item["rendered-html"];
require_once("mod/proxy.php");
$s = proxy_parse_html($s);
$prep_arr = array('item' => $item, 'html' => $s, 'preview' => $preview); $prep_arr = array('item' => $item, 'html' => $s, 'preview' => $preview);
call_hooks('prepare_body', $prep_arr); call_hooks('prepare_body', $prep_arr);
$s = $prep_arr['html']; $s = $prep_arr['html'];
@ -1438,7 +1443,7 @@ function prepare_body(&$item,$attach = false, $preview = false) {
$mime = $mtch[3]; $mime = $mtch[3];
if((local_user() == $item['uid']) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == NETWORK_DFRN)) if((local_user() == $item['uid']) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == NETWORK_DFRN))
$the_url = $a->get_baseurl() . '/redir/' . $item['contact-id'] . '?f=1&url=' . $mtch[1]; $the_url = z_root() . '/redir/' . $item['contact-id'] . '?f=1&url=' . $mtch[1];
else else
$the_url = $mtch[1]; $the_url = $mtch[1];
@ -1446,10 +1451,10 @@ function prepare_body(&$item,$attach = false, $preview = false) {
if(!$vhead) { if(!$vhead) {
$vhead = true; $vhead = true;
$a->page['htmlhead'] .= replace_macros(get_markup_template('videos_head.tpl'), array( $a->page['htmlhead'] .= replace_macros(get_markup_template('videos_head.tpl'), array(
'$baseurl' => $a->get_baseurl(), '$baseurl' => z_root(),
)); ));
$a->page['end'] .= replace_macros(get_markup_template('videos_end.tpl'), array( $a->page['end'] .= replace_macros(get_markup_template('videos_end.tpl'), array(
'$baseurl' => $a->get_baseurl(), '$baseurl' => z_root(),
)); ));
} }
@ -1613,7 +1618,7 @@ function get_cats_and_terms($item) {
$categories[] = array( $categories[] = array(
'name' => xmlify(file_tag_decode($mtch[1])), 'name' => xmlify(file_tag_decode($mtch[1])),
'url' => "#", 'url' => "#",
'removeurl' => ((local_user() == $item['uid'])?$a->get_baseurl() . '/filerm/' . $item['id'] . '?f=&cat=' . xmlify(file_tag_decode($mtch[1])):""), 'removeurl' => ((local_user() == $item['uid'])?z_root() . '/filerm/' . $item['id'] . '?f=&cat=' . xmlify(file_tag_decode($mtch[1])):""),
'first' => $first, 'first' => $first,
'last' => false 'last' => false
); );
@ -1631,7 +1636,7 @@ function get_cats_and_terms($item) {
$folders[] = array( $folders[] = array(
'name' => xmlify(file_tag_decode($mtch[1])), 'name' => xmlify(file_tag_decode($mtch[1])),
'url' => "#", 'url' => "#",
'removeurl' => ((local_user() == $item['uid'])?$a->get_baseurl() . '/filerm/' . $item['id'] . '?f=&term=' . xmlify(file_tag_decode($mtch[1])):""), 'removeurl' => ((local_user() == $item['uid'])?z_root() . '/filerm/' . $item['id'] . '?f=&term=' . xmlify(file_tag_decode($mtch[1])):""),
'first' => $first, 'first' => $first,
'last' => false 'last' => false
); );
@ -1665,7 +1670,7 @@ function feed_hublinks() {
if(! strlen($h)) if(! strlen($h))
continue; continue;
if ($h === '[internal]') if ($h === '[internal]')
$h = $a->get_baseurl() . '/pubsubhubbub'; $h = z_root() . '/pubsubhubbub';
$hubxml .= '<link rel="hub" href="' . xmlify($h) . '" />' . "\n" ; $hubxml .= '<link rel="hub" href="' . xmlify($h) . '" />' . "\n" ;
} }
} }
@ -1684,12 +1689,12 @@ function feed_salmonlinks($nick) {
$a = get_app(); $a = get_app();
$salmon = '<link rel="salmon" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; $salmon = '<link rel="salmon" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
// old style links that status.net still needed as of 12/2010 // old style links that status.net still needed as of 12/2010
$salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
$salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify(z_root() . '/salmon/' . $nick) . '" />' . "\n" ;
return $salmon; return $salmon;
}} }}
@ -1704,9 +1709,9 @@ function get_plink($item) {
if ($a->user['nickname'] != "") { if ($a->user['nickname'] != "") {
$ret = array( $ret = array(
//'href' => $a->get_baseurl()."/display/".$a->user['nickname']."/".$item['id'], //'href' => z_root()."/display/".$a->user['nickname']."/".$item['id'],
'href' => $a->get_baseurl()."/display/".$item['guid'], 'href' => z_root()."/display/".$item['guid'],
'orig' => $a->get_baseurl()."/display/".$item['guid'], 'orig' => z_root()."/display/".$item['guid'],
'title' => t('View on separate page'), 'title' => t('View on separate page'),
'orig_title' => t('view on separate page'), 'orig_title' => t('view on separate page'),
); );
@ -1741,50 +1746,6 @@ function unamp($s) {
}} }}
if(! function_exists('lang_selector')) {
/**
* get html for language selector
* @global string $lang
* @return string
* @template lang_selector.tpl
*/
function lang_selector() {
global $lang;
$langs = glob('view/*/strings.php');
$lang_options = array();
$selected = "";
if(is_array($langs) && count($langs)) {
$langs[] = '';
if(! in_array('view/en/strings.php',$langs))
$langs[] = 'view/en/';
asort($langs);
foreach($langs as $l) {
if($l == '') {
$lang_options[""] = t('default');
continue;
}
$ll = substr($l,5);
$ll = substr($ll,0,strrpos($ll,'/'));
$selected = (($ll === $lang && (x($_SESSION, 'language'))) ? $ll : $selected);
$lang_options[$ll]=$ll;
}
}
$tpl = get_markup_template("lang_selector.tpl");
$o = replace_macros($tpl, array(
'$title' => t('Select an alternate language'),
'$langs' => array($lang_options, $selected),
));
return $o;
}}
if(! function_exists('return_bytes')) { if(! function_exists('return_bytes')) {
/** /**
* return number of bytes in size (K, M, G) * return number of bytes in size (K, M, G)
@ -1792,8 +1753,7 @@ if(! function_exists('return_bytes')) {
* @return number * @return number
*/ */
function return_bytes ($size_str) { function return_bytes ($size_str) {
switch (substr ($size_str, -1)) switch (substr ($size_str, -1)) {
{
case 'M': case 'm': return (int)$size_str * 1048576; case 'M': case 'm': return (int)$size_str * 1048576;
case 'K': case 'k': return (int)$size_str * 1024; case 'K': case 'k': return (int)$size_str * 1024;
case 'G': case 'g': return (int)$size_str * 1073741824; case 'G': case 'g': return (int)$size_str * 1073741824;
@ -1875,7 +1835,7 @@ if (!function_exists('str_getcsv')) {
* @param string $eol * @param string $eol
* @return boolean|array False on error, otherwise array[row][column] * @return boolean|array False on error, otherwise array[row][column]
*/ */
function str_getcsv($input, $delimiter = ',', $enclosure = '"', $escape = '\\', $eol = '\n') { function str_getcsv($input, $delimiter = ',', $enclosure = '"', $escape = '\\', $eol = '\n') {
if (is_string($input) && !empty($input)) { if (is_string($input) && !empty($input)) {
$output = array(); $output = array();
$tmp = preg_split("/".$eol."/",$input); $tmp = preg_split("/".$eol."/",$input);
@ -1928,7 +1888,7 @@ if (!function_exists('str_getcsv')) {
} else { } else {
return false; return false;
} }
} }
} }
/** /**
@ -1989,8 +1949,7 @@ function array_xmlify($val){
* @param string $base base url * @param string $base base url
* @return string * @return string
*/ */
function reltoabs($text, $base) function reltoabs($text, $base) {
{
if (empty($base)) if (empty($base))
return $text; return $text;
@ -2187,13 +2146,13 @@ function file_tag_save_file($uid,$item,$file) {
$result = false; $result = false;
if(! intval($uid)) if(! intval($uid))
return false; return false;
$r = q("select file from item where id = %d and uid = %d limit 1", $r = q("SELECT `file` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($item), intval($item),
intval($uid) intval($uid)
); );
if(count($r)) { if(count($r)) {
if(! stristr($r[0]['file'],'[' . file_tag_encode($file) . ']')) if(! stristr($r[0]['file'],'[' . file_tag_encode($file) . ']'))
q("update item set file = '%s' where id = %d and uid = %d", q("UPDATE `item` SET `file` = '%s' WHERE `id` = %d AND `uid` = %d",
dbesc($r[0]['file'] . '[' . file_tag_encode($file) . ']'), dbesc($r[0]['file'] . '[' . file_tag_encode($file) . ']'),
intval($item), intval($item),
intval($uid) intval($uid)
@ -2225,14 +2184,14 @@ function file_tag_unsave_file($uid,$item,$file,$cat = false) {
} }
$r = q("select file from item where id = %d and uid = %d limit 1", $r = q("SELECT `file` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($item), intval($item),
intval($uid) intval($uid)
); );
if(! count($r)) if(! count($r))
return false; return false;
q("update item set file = '%s' where id = %d and uid = %d", q("UPDATE `item` SET `file` = '%s' WHERE `id` = %d AND `uid` = %d",
dbesc(str_replace($pattern,'',$r[0]['file'])), dbesc(str_replace($pattern,'',$r[0]['file'])),
intval($item), intval($item),
intval($uid) intval($uid)
@ -2328,3 +2287,25 @@ function formatBytes($bytes, $precision = 2) {
return round($bytes, $precision) . ' ' . $units[$pow]; return round($bytes, $precision) . ' ' . $units[$pow];
} }
/**
* @brief translate and format the networkname of a contact
*
* @param string $network
* Networkname of the contact (e.g. dfrn, rss and so on)
* @param sting $url
* The contact url
* @return string
*/
function format_network_name($network, $url = 0) {
if ($network != "") {
require_once('include/contact_selectors.php');
if ($url != "")
$network_name = '<a href="'.$url.'">'.network_to_name($network, $url)."</a>";
else
$network_name = network_to_name($network);
return $network_name;
}
}

View file

@ -87,7 +87,6 @@ function add_shadow_entry($item) {
// Is there already a shadow entry? // Is there already a shadow entry?
$r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item['uri'])); $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item['uri']));
if (count($r)) if (count($r))
return; return;

113
include/update_gcontact.php Normal file
View file

@ -0,0 +1,113 @@
<?php
require_once("boot.php");
function update_gcontact_run(&$argv, &$argc){
global $a, $db;
if(is_null($a)) {
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("include/dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once('include/pidfile.php');
require_once('include/Scrape.php');
require_once("include/socgraph.php");
load_config('config');
load_config('system');
$a->set_baseurl(get_config('system','url'));
load_hooks();
logger('update_gcontact: start');
if(($argc > 1) && (intval($argv[1])))
$contact_id = intval($argv[1]);
if(!$contact_id) {
logger('update_gcontact: no contact');
return;
}
$lockpath = get_lockpath();
if ($lockpath != '') {
$pidfile = new pidfile($lockpath, 'update_gcontact'.$contact_id);
if ($pidfile->is_already_running()) {
logger("update_gcontact: Already running for contact ".$contact_id);
if ($pidfile->running_time() > 9*60) {
$pidfile->kill();
logger("killed stale process");
}
exit;
}
}
$r = q("SELECT * FROM `gcontact` WHERE `id` = %d", intval($contact_id));
if (!$r)
return;
if (!in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
return;
$data = probe_url($r[0]["url"]);
if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
if ($r[0]["server_url"] != "")
poco_check_server($r[0]["server_url"], $r[0]["network"]);
q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `id` = %d",
dbesc(datetime_convert()), intval($contact_id));
return;
}
if (($data["name"] == "") AND ($r[0]['name'] != ""))
$data["name"] = $r[0]['name'];
if (($data["nick"] == "") AND ($r[0]['nick'] != ""))
$data["nick"] = $r[0]['nick'];
if (($data["addr"] == "") AND ($r[0]['addr'] != ""))
$data["addr"] = $r[0]['addr'];
if (($data["photo"] == "") AND ($r[0]['photo'] != ""))
$data["photo"] = $r[0]['photo'];
q("UPDATE `gcontact` SET `name` = '%s', `nick` = '%s', `addr` = '%s', `photo` = '%s'
WHERE `id` = %d",
dbesc($data["name"]),
dbesc($data["nick"]),
dbesc($data["addr"]),
dbesc($data["photo"]),
intval($contact_id)
);
q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `addr` = '%s', `photo` = '%s'
WHERE `uid` = 0 AND `addr` = '' AND `nurl` = '%s'",
dbesc($data["name"]),
dbesc($data["nick"]),
dbesc($data["addr"]),
dbesc($data["photo"]),
dbesc(normalise_link($data["url"]))
);
q("UPDATE `contact` SET `addr` = '%s'
WHERE `uid` != 0 AND `addr` = '' AND `nurl` = '%s'",
dbesc($data["addr"]),
dbesc(normalise_link($data["url"]))
);
}
if (array_search(__file__,get_included_files())===0){
update_gcontact_run($_SERVER["argv"],$_SERVER["argc"]);
killme();
}

View file

@ -48,7 +48,7 @@ function create_user($arr) {
$result['message'] .= t('An invitation is required.') . EOL; $result['message'] .= t('An invitation is required.') . EOL;
return $result; return $result;
} }
$r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id)); $r = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1", dbesc($invite_id));
if(! results($r)) { if(! results($r)) {
$result['message'] .= t('Invitation could not be verified.') . EOL; $result['message'] .= t('Invitation could not be verified.') . EOL;
return $result; return $result;
@ -66,7 +66,7 @@ function create_user($arr) {
require_once('library/openid.php'); require_once('library/openid.php');
$openid = new LightOpenID; $openid = new LightOpenID;
$openid->identity = $openid_url; $openid->identity = $openid_url;
$openid->returnUrl = $a->get_baseurl() . '/openid'; $openid->returnUrl = z_root() . '/openid';
$openid->required = array('namePerson/friendly', 'contact/email', 'namePerson'); $openid->required = array('namePerson/friendly', 'contact/email', 'namePerson');
$openid->optional = array('namePerson/first','media/image/aspect11','media/image/default'); $openid->optional = array('namePerson/first','media/image/aspect11','media/image/default');
try { try {
@ -138,6 +138,7 @@ function create_user($arr) {
if(! preg_match("/^[a-z0-9][a-z0-9\_]*$/",$nickname)) if(! preg_match("/^[a-z0-9][a-z0-9\_]*$/",$nickname))
$result['message'] .= t('Your "nickname" can only contain "a-z", "0-9" and "_".') . EOL; $result['message'] .= t('Your "nickname" can only contain "a-z", "0-9" and "_".') . EOL;
$r = q("SELECT `uid` FROM `user` $r = q("SELECT `uid` FROM `user`
WHERE `nickname` = '%s' LIMIT 1", WHERE `nickname` = '%s' LIMIT 1",
dbesc($nickname) dbesc($nickname)
@ -255,8 +256,8 @@ function create_user($arr) {
t('default'), t('default'),
1, 1,
dbesc($username), dbesc($username),
dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc(z_root() . "/photo/profile/{$newuid}.jpg"),
dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), dbesc(z_root() . "/photo/avatar/{$newuid}.jpg"),
intval($publish), intval($publish),
intval($netpublish) intval($netpublish)
@ -269,22 +270,23 @@ function create_user($arr) {
return $result; return $result;
} }
$r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`, $r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,
`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date`, `closeness` ) `addr`, `request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date`, `closeness` )
VALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0 ) ", VALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0 ) ",
intval($newuid), intval($newuid),
datetime_convert(), datetime_convert(),
dbesc($username), dbesc($username),
dbesc($nickname), dbesc($nickname),
dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"), dbesc(z_root() . "/photo/profile/{$newuid}.jpg"),
dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"), dbesc(z_root() . "/photo/avatar/{$newuid}.jpg"),
dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"), dbesc(z_root() . "/photo/micro/{$newuid}.jpg"),
dbesc($a->get_baseurl() . "/profile/$nickname"), dbesc(z_root() . "/profile/$nickname"),
dbesc(normalise_link($a->get_baseurl() . "/profile/$nickname")), dbesc(normalise_link(z_root() . "/profile/$nickname")),
dbesc($a->get_baseurl() . "/dfrn_request/$nickname"), dbesc($nickname . '@' . substr(z_root(), strpos(z_root(),'://') + 3 )),
dbesc($a->get_baseurl() . "/dfrn_notify/$nickname"), dbesc(z_root() . "/dfrn_request/$nickname"),
dbesc($a->get_baseurl() . "/dfrn_poll/$nickname"), dbesc(z_root() . "/dfrn_notify/$nickname"),
dbesc($a->get_baseurl() . "/dfrn_confirm/$nickname"), dbesc(z_root() . "/dfrn_poll/$nickname"),
dbesc($a->get_baseurl() . "/poco/$nickname"), dbesc(z_root() . "/dfrn_confirm/$nickname"),
dbesc(z_root() . "/poco/$nickname"),
dbesc(datetime_convert()), dbesc(datetime_convert()),
dbesc(datetime_convert()), dbesc(datetime_convert()),
dbesc(datetime_convert()) dbesc(datetime_convert())
@ -296,21 +298,21 @@ function create_user($arr) {
require_once('include/group.php'); require_once('include/group.php');
group_add($newuid, t('Friends')); group_add($newuid, t('Friends'));
$r = q("SELECT id FROM `group` WHERE uid = %d AND name = '%s'", $r = q("SELECT `id` FROM `group` WHERE `uid` = %d AND `name` = '%s'",
intval($newuid), intval($newuid),
dbesc(t('Friends')) dbesc(t('Friends'))
); );
if($r && count($r)) { if($r && count($r)) {
$def_gid = $r[0]['id']; $def_gid = $r[0]['id'];
q("UPDATE user SET def_gid = %d WHERE uid = %d", q("UPDATE `user` SET `def_gid` = %d WHERE `uid` = %d",
intval($r[0]['id']), intval($r[0]['id']),
intval($newuid) intval($newuid)
); );
} }
if(get_config('system', 'newuser_private') && $def_gid) { if(get_config('system', 'newuser_private') && $def_gid) {
q("UPDATE user SET allow_gid = '%s' WHERE uid = %d", q("UPDATE `user` SET `allow_gid` = '%s' WHERE `uid` = %d",
dbesc("<" . $def_gid . ">"), dbesc("<" . $def_gid . ">"),
intval($newuid) intval($newuid)
); );

View file

@ -56,10 +56,11 @@ if(!$install) {
$maxsysload_frontend = intval(get_config('system','maxloadavg_frontend')); $maxsysload_frontend = intval(get_config('system','maxloadavg_frontend'));
if($maxsysload_frontend < 1) if($maxsysload_frontend < 1)
$maxsysload_frontend = 50; $maxsysload_frontend = 50;
if(function_exists('sys_getloadavg')) {
$load = sys_getloadavg(); $load = current_load();
if(intval($load[0]) > $maxsysload_frontend) { if($load) {
logger('system: load ' . $load[0] . ' too high. Service Temporarily Unavailable.'); if($load > $maxsysload_frontend) {
logger('system: load ' . $load . ' too high. Service Temporarily Unavailable.');
header($_SERVER["SERVER_PROTOCOL"].' 503 Service Temporarily Unavailable'); header($_SERVER["SERVER_PROTOCOL"].' 503 Service Temporarily Unavailable');
header('Retry-After: 300'); header('Retry-After: 300');
die("System is currently unavailable. Please try again later"); die("System is currently unavailable. Please try again later");
@ -102,13 +103,13 @@ session_start();
* Language was set earlier, but we can over-ride it in the session. * Language was set earlier, but we can over-ride it in the session.
* We have to do it here because the session was just now opened. * We have to do it here because the session was just now opened.
*/ */
if (x($_SESSION,'authenticated') && !x($_SESSION,'language')) {
if(array_key_exists('system_language',$_POST)) { // we didn't loaded user data yet, but we need user language
if(strlen($_POST['system_language'])) $r = q("SELECT language FROM user WHERE uid=%d", intval($_SESSION['uid']));
$_SESSION['language'] = $_POST['system_language']; $_SESSION['language'] = $lang;
else if (count($r)>0) $_SESSION['language'] = $r[0]['language'];
unset($_SESSION['language']);
} }
if((x($_SESSION,'language')) && ($_SESSION['language'] !== $lang)) { if((x($_SESSION,'language')) && ($_SESSION['language'] !== $lang)) {
$lang = $_SESSION['language']; $lang = $_SESSION['language'];
load_translation_table($lang); load_translation_table($lang);

View file

@ -1,7 +1,7 @@
/** /**
* Filebrowser - Friendica Communications Server * Filebrowser - Friendica Communications Server
* *
* Copyright (c) 2010-2013 the Friendica Project * Copyright (c) 2010-2015 the Friendica Project
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by * it under the terms of the GNU Affero General Public License as published by
@ -13,14 +13,14 @@
* *
* To load filebrowser in colorbox, call * To load filebrowser in colorbox, call
* *
* $.colorbox({href: ulr, iframe:true,innerWidth:'500px',innerHeight:'400px'}) * Dialog.doImageBrowser(eventname, id);
* *
* where url is: * or
* *
* <baseurl>/fbrowser/<type>/?mode=minimal[#<eventname>-<id>] * Dialog.doFileBrowser(eventname, id);
*
* where:
* *
* baseurl: baseurl from friendica
* type: one of "image", "file"
* eventname: event name to catch return value * eventname: event name to catch return value
* id: id returned to event handler * id: id returned to event handler
* *
@ -29,17 +29,18 @@
* *
* fbrowser.<type>.[<eventname>] * fbrowser.<type>.[<eventname>]
* *
* with params: * <type> will be one of "image" or "file", and the event handler will
* get the following params:
* *
* filemane: filename of item choosed by user * filemane: filename of item choosed by user
* embed: bbcode to embed element into posts * embed: bbcode to embed element into posts
* id: id from url * id: id from caller code
* *
* example: * example:
* *
* // open dialog for select an image for a textarea with id "myeditor" * // open dialog for select an image for a textarea with id "myeditor"
* var id="myeditor"; * var id="myeditor";
* $.colorbox({href: baseurl + "/fbrowser/image/?mode=minimal#example-"+id, iframe:true,innerWidth:'500px',innerHeight:'400px'}) * Dialog.doImageBrowser("example", id);
* *
* // setup event handler to get user selection * // setup event handler to get user selection
* $("body").on("fbrowser.image.example", function(event, filename, bbcode, id) { * $("body").on("fbrowser.image.example", function(event, filename, bbcode, id) {

View file

@ -23,19 +23,20 @@ function ACPopup(elm,backend_url){
var h = 130; var h = 130;
if(typeof elm.editorId == "undefined") { if(tinyMCE.activeEditor == null) {
style = $(elm).offset(); style = $(elm).offset();
w = $(elm).width(); w = $(elm).width();
h = $(elm).height(); h = $(elm).height();
} }
else { else {
var container = elm.getContainer(); // I can't find an "official" way to get the element who get all
if(typeof container != "undefined") { // this fraking thing that is tinyMCE.
// This code will broke again at some point...
var container = $(tinyMCE.activeEditor.getContainer()).find("table");
style = $(container).offset(); style = $(container).offset();
w = $(container).width(); w = $(container).width();
h = $(container).height(); h = $(container).height();
} }
}
style.top=style.top+h; style.top=style.top+h;
style.width = w; style.width = w;

View file

@ -1,6 +1,21 @@
function resizeIframe(obj) { function resizeIframe(obj) {
obj.style.height = 0; obj.style.height = 0;
obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px'; _resizeIframe(obj, 0);
}
function _resizeIframe(obj, desth) {
var h = obj.style.height;
var ch = obj.contentWindow.document.body.scrollHeight + 'px';
if (h==ch) {
return;
}
console.log("_resizeIframe", obj, desth, ch);
if (desth!=ch) {
setTimeout(_resizeIframe, 500, obj, ch);
} else {
obj.style.height = ch;
setTimeout(_resizeIframe, 1000, obj, ch);
}
} }
function openClose(theID) { function openClose(theID) {
@ -65,10 +80,9 @@
var bbcode = o.data('bbcode'); var bbcode = o.data('bbcode');
var id = o.data('id'); var id = o.data('id');
if (bbcode=="img") { if (bbcode=="img") {
$.colorbox({href: baseurl + "/fbrowser/image/?mode=minimal#comment-"+id, iframe:true,innerWidth:'500px',innerHeight:'400px'}) Dialog.doImageBrowser("comment", id);
return; return;
} }
insertFormatting(comment, bbcode, id); insertFormatting(comment, bbcode, id);
}); });
@ -154,7 +168,7 @@
var notifications_empty = unescape($("#nav-notifications-menu").html()); var notifications_empty = unescape($("#nav-notifications-menu").html());
/* nav update event */ /* nav update event */
$('nav').bind('nav-update', function(e,data){; $('nav').bind('nav-update', function(e,data){
var invalid = $(data).find('invalid').text(); var invalid = $(data).find('invalid').text();
if(invalid == 1) { window.location.href=window.location.href } if(invalid == 1) { window.location.href=window.location.href }
@ -204,6 +218,20 @@
var birthdaystoday = $(data).find('birthdays-today').text(); var birthdaystoday = $(data).find('birthdays-today').text();
if(birthdaystoday == 0) { $('#birthdays-update').removeClass('notif-birthdays-today') } else { $('#birthdays-update').addClass('notif-birthdays-today') } if(birthdaystoday == 0) { $('#birthdays-update').removeClass('notif-birthdays-today') } else { $('#birthdays-update').addClass('notif-birthdays-today') }
$(".sidebar-group-li .notify").removeClass("show");
$(data).find("group").each(function() {
var gid = this.id;
var gcount = this.innerHTML;
$(".group-"+gid+" .notify").addClass("show").text(gcount);
});
$(".forum-widget-entry .notify").removeClass("show");
$(data).find("forum").each(function() {
var fid = this.id;
var fcount = this.innerHTML;
$(".forum-"+fid+" .notify").addClass("show").text(fcount);
});
var eNotif = $(data).find('notif') var eNotif = $(data).find('notif')
@ -614,7 +642,6 @@
$("#comment-edit-form-" + id).serialize(), $("#comment-edit-form-" + id).serialize(),
function(data) { function(data) {
if(data.preview) { if(data.preview) {
$("#comment-edit-preview-" + id).html(data.preview); $("#comment-edit-preview-" + id).html(data.preview);
$("#comment-edit-preview-" + id + " a").click(function() { return false; }); $("#comment-edit-preview-" + id + " a").click(function() { return false; });
} }
@ -826,3 +853,68 @@ function getNotificationPermission() {
return Notification.permission; return Notification.permission;
} }
} }
/**
* Show a dialog loaded from an url
* By defaults this load the url in an iframe in colorbox
* Themes can overwrite `show()` function to personalize it
*/
var Dialog = {
/**
* Show the dialog
*
* @param string url
* @return object colorbox
*/
show : function (url) {
var size = Dialog._get_size();
return $.colorbox({href: url, iframe:true,innerWidth: size.width+'px',innerHeight: size.height+'px'})
},
/**
* Show the Image browser dialog
*
* @param string name
* @param string id (optional)
* @return object
*
* The name will be used to build the event name
* fired by image browser dialog when the user select
* an image. The optional id will be passed as argument
* to the event handler
*/
doImageBrowser : function (name, id) {
var url = Dialog._get_url("image",name,id);
return Dialog.show(url);
},
/**
* Show the File browser dialog
*
* @param string name
* @param string id (optional)
* @return object
*
* The name will be used to build the event name
* fired by file browser dialog when the user select
* a file. The optional id will be passed as argument
* to the event handler
*/
doFileBrowser : function (name, id) {
var url = Dialog._get_url("file",name,id);
return Dialog.show(url);
},
_get_url : function(type, name, id) {
var hash = name;
if (id !== undefined) hash = hash + "-" + id;
return baseurl + "/fbrowser/"+type+"/?mode=minimal#"+hash;
},
_get_size: function() {
return {
width: window.innerWidth-50,
height: window.innerHeight-100
};
}
}

View file

@ -47,12 +47,35 @@ function admin_post(&$a){
return; // NOTREACHED return; // NOTREACHED
break; break;
case 'themes': case 'themes':
if ($a->argc < 2) {
if(is_ajax()) return;
goaway($a->get_baseurl(true) . '/admin/' );
return;
}
$theme = $a->argv[2]; $theme = $a->argv[2];
if (is_file("view/theme/$theme/config.php")){ if (is_file("view/theme/$theme/config.php")){
function __call_theme_admin_post(&$a, $theme) {
$orig_theme = $a->theme;
$orig_page = $a->page;
$orig_session_theme = $_SESSION['theme'];
require_once("view/theme/$theme/theme.php");
require_once("view/theme/$theme/config.php"); require_once("view/theme/$theme/config.php");
if (function_exists("theme_admin_post")){ $_SESSION['theme'] = $theme;
theme_admin_post($a);
$init = $theme."_init";
if(function_exists($init)) $init($a);
if(function_exists("theme_admin_post")){
$admin_form = theme_admin_post($a);
} }
$_SESSION['theme'] = $orig_session_theme;
$a->theme = $orig_theme;
$a->page = $orig_page;
return $admin_form;
}
__call_theme_admin_post($a, $theme);
} }
info(t('Theme settings updated.')); info(t('Theme settings updated.'));
if(is_ajax()) return; if(is_ajax()) return;
@ -112,7 +135,7 @@ function admin_content(&$a) {
/* get plugins admin page */ /* get plugins admin page */
$r = q("SELECT name FROM `addon` WHERE `plugin_admin`=1"); $r = q("SELECT `name` FROM `addon` WHERE `plugin_admin`=1 ORDER BY `name`");
$aside['plugins_admin']=Array(); $aside['plugins_admin']=Array();
foreach ($r as $h){ foreach ($r as $h){
$plugin =$h['name']; $plugin =$h['name'];
@ -386,6 +409,8 @@ function admin_page_site_post(&$a){
$poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0); $poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0);
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50); $maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
$maxloadavg_frontend = ((x($_POST,'maxloadavg_frontend')) ? intval(trim($_POST['maxloadavg_frontend'])) : 50); $maxloadavg_frontend = ((x($_POST,'maxloadavg_frontend')) ? intval(trim($_POST['maxloadavg_frontend'])) : 50);
$optimize_max_tablesize = ((x($_POST,'optimize_max_tablesize')) ? intval(trim($_POST['optimize_max_tablesize'])): 100);
$optimize_fragmentation = ((x($_POST,'optimize_fragmentation')) ? intval(trim($_POST['optimize_fragmentation'])): 30);
$poco_completion = ((x($_POST,'poco_completion')) ? intval(trim($_POST['poco_completion'])) : false); $poco_completion = ((x($_POST,'poco_completion')) ? intval(trim($_POST['poco_completion'])) : false);
$poco_requery_days = ((x($_POST,'poco_requery_days')) ? intval(trim($_POST['poco_requery_days'])) : 7); $poco_requery_days = ((x($_POST,'poco_requery_days')) ? intval(trim($_POST['poco_requery_days'])) : 7);
$poco_discovery = ((x($_POST,'poco_discovery')) ? intval(trim($_POST['poco_discovery'])) : 0); $poco_discovery = ((x($_POST,'poco_discovery')) ? intval(trim($_POST['poco_discovery'])) : 0);
@ -416,6 +441,11 @@ function admin_page_site_post(&$a){
$rino = ((x($_POST,'rino')) ? intval($_POST['rino']) : 0); $rino = ((x($_POST,'rino')) ? intval($_POST['rino']) : 0);
$embedly = ((x($_POST,'embedly')) ? notags(trim($_POST['embedly'])) : ''); $embedly = ((x($_POST,'embedly')) ? notags(trim($_POST['embedly'])) : '');
if ($a->get_path() != "")
$diaspora_enabled = false;
if (!$thread_allow)
$ostatus_disabled = true;
if($ssl_policy != intval(get_config('system','ssl_policy'))) { if($ssl_policy != intval(get_config('system','ssl_policy'))) {
if($ssl_policy == SSL_POLICY_FULL) { if($ssl_policy == SSL_POLICY_FULL) {
@ -462,6 +492,8 @@ function admin_page_site_post(&$a){
set_config('system','poll_interval',$poll_interval); set_config('system','poll_interval',$poll_interval);
set_config('system','maxloadavg',$maxloadavg); set_config('system','maxloadavg',$maxloadavg);
set_config('system','maxloadavg_frontend',$maxloadavg_frontend); set_config('system','maxloadavg_frontend',$maxloadavg_frontend);
set_config('system','optimize_max_tablesize',$optimize_max_tablesize);
set_config('system','optimize_fragmentation',$optimize_fragmentation);
set_config('system','poco_completion',$poco_completion); set_config('system','poco_completion',$poco_completion);
set_config('system','poco_requery_days',$poco_requery_days); set_config('system','poco_requery_days',$poco_requery_days);
set_config('system','poco_discovery',$poco_discovery); set_config('system','poco_discovery',$poco_discovery);
@ -535,6 +567,7 @@ function admin_page_site_post(&$a){
set_config('system','ostatus_disabled', $ostatus_disabled); set_config('system','ostatus_disabled', $ostatus_disabled);
set_config('system','ostatus_poll_interval', $ostatus_poll_interval); set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
set_config('system','diaspora_enabled', $diaspora_enabled); set_config('system','diaspora_enabled', $diaspora_enabled);
set_config('config','private_addons', $private_addons); set_config('config','private_addons', $private_addons);
set_config('system','force_ssl', $force_ssl); set_config('system','force_ssl', $force_ssl);
@ -574,18 +607,7 @@ function admin_page_site_post(&$a){
function admin_page_site(&$a) { function admin_page_site(&$a) {
/* Installed langs */ /* Installed langs */
$lang_choices = array(); $lang_choices = get_avaiable_languages();
$langs = glob('view/*/strings.php'); /**/
if(is_array($langs) && count($langs)) {
if(! in_array('view/en/strings.php',$langs))
$langs[] = 'view/en/';
asort($langs);
foreach($langs as $l) {
$t = explode("/",$l);
$lang_choices[$t[1]] = $t[1];
}
}
if (strlen(get_config('system','directory_submit_url')) AND if (strlen(get_config('system','directory_submit_url')) AND
!strlen(get_config('system','directory'))) { !strlen(get_config('system','directory'))) {
@ -597,15 +619,17 @@ function admin_page_site(&$a) {
$theme_choices = array(); $theme_choices = array();
$theme_choices_mobile = array(); $theme_choices_mobile = array();
$theme_choices_mobile["---"] = t("No special theme for mobile devices"); $theme_choices_mobile["---"] = t("No special theme for mobile devices");
$files = glob('view/theme/*'); $files = glob('view/theme/*'); /**/
if($files) { if($files) {
foreach($files as $file) { foreach($files as $file) {
if (intval(file_exists($file . '/unsupported')))
continue;
$f = basename($file); $f = basename($file);
$theme_name = ((file_exists($file . '/experimental')) ? sprintf("%s - \x28Experimental\x29", $f) : $f); $theme_name = ((file_exists($file . '/experimental')) ? sprintf("%s - \x28Experimental\x29", $f) : $f);
if (file_exists($file . '/mobile')) { if (file_exists($file . '/mobile')) {
$theme_choices_mobile[$f] = $theme_name; $theme_choices_mobile[$f] = $theme_name;
} } else {
else {
$theme_choices[$f] = $theme_name; $theme_choices[$f] = $theme_name;
} }
} }
@ -681,6 +705,8 @@ function admin_page_site(&$a) {
if ($a->config['hostname'] == "") if ($a->config['hostname'] == "")
$a->config['hostname'] = $a->get_hostname(); $a->config['hostname'] = $a->get_hostname();
$diaspora_able = ($a->get_path() == "");
$t = get_markup_template("admin_site.tpl"); $t = get_markup_template("admin_site.tpl");
return replace_macros($t, array( return replace_macros($t, array(
'$title' => t('Administration'), '$title' => t('Administration'),
@ -737,6 +763,9 @@ function admin_page_site(&$a) {
'$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")), '$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")),
'$ostatus_disabled' => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")), '$ostatus_disabled' => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),
'$ostatus_poll_interval' => array('ostatus_poll_interval', t("OStatus conversation completion interval"), (string) intval(get_config('system','ostatus_poll_interval')), t("How often shall the poller check for new entries in OStatus conversations? This can be a very ressource task."), $ostatus_poll_choices), '$ostatus_poll_interval' => array('ostatus_poll_interval', t("OStatus conversation completion interval"), (string) intval(get_config('system','ostatus_poll_interval')), t("How often shall the poller check for new entries in OStatus conversations? This can be a very ressource task."), $ostatus_poll_choices),
'$ostatus_not_able' => t("OStatus support can only be enabled if threading is enabled."),
'$diaspora_able' => $diaspora_able,
'$diaspora_not_able' => t("Diaspora support can't be enabled because Friendica was installed into a sub directory."),
'$diaspora_enabled' => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")), '$diaspora_enabled' => array('diaspora_enabled', t("Enable Diaspora support"), get_config('system','diaspora_enabled'), t("Provide built-in Diaspora network compatibility.")),
'$dfrn_only' => array('dfrn_only', t('Only allow Friendica contacts'), get_config('system','dfrn_only'), t("All contacts must use Friendica protocols. All other built-in communication protocols disabled.")), '$dfrn_only' => array('dfrn_only', t('Only allow Friendica contacts'), get_config('system','dfrn_only'), t("All contacts must use Friendica protocols. All other built-in communication protocols disabled.")),
'$verifyssl' => array('verifyssl', t("Verify SSL"), get_config('system','verifyssl'), t("If you wish, you can turn on strict certificate checking. This will mean you cannot connect (at all) to self-signed SSL sites.")), '$verifyssl' => array('verifyssl', t("Verify SSL"), get_config('system','verifyssl'), t("If you wish, you can turn on strict certificate checking. This will mean you cannot connect (at all) to self-signed SSL sites.")),
@ -747,6 +776,8 @@ function admin_page_site(&$a) {
'$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")), '$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")),
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")), '$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
'$maxloadavg_frontend' => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(get_config('system','maxloadavg_frontend')) > 0)?get_config('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")), '$maxloadavg_frontend' => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(get_config('system','maxloadavg_frontend')) > 0)?get_config('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")),
'$optimize_max_tablesize'=> array('optimize_max_tablesize', t("Maximum table size for optimization"), ((intval(get_config('system','optimize_max_tablesize')) > 0)?get_config('system','optimize_max_tablesize'):100), t("Maximum table size (in MB) for the automatic optimization - default 100 MB. Enter -1 to disable it.")),
'$optimize_fragmentation'=> array('optimize_fragmentation', t("Minimum level of fragmentation"), ((intval(get_config('system','optimize_fragmentation')) > 0)?get_config('system','optimize_fragmentation'):30), t("Minimum fragmenation level to start the automatic optimization - default value is 30%.")),
'$poco_completion' => array('poco_completion', t("Periodical check of global contacts"), get_config('system','poco_completion'), t("If enabled, the global contacts are checked periodically for missing or outdated data and the vitality of the contacts and servers.")), '$poco_completion' => array('poco_completion', t("Periodical check of global contacts"), get_config('system','poco_completion'), t("If enabled, the global contacts are checked periodically for missing or outdated data and the vitality of the contacts and servers.")),
'$poco_requery_days' => array('poco_requery_days', t("Days between requery"), get_config('system','poco_requery_days'), t("Number of days after which a server is requeried for his contacts.")), '$poco_requery_days' => array('poco_requery_days', t("Days between requery"), get_config('system','poco_requery_days'), t("Number of days after which a server is requeried for his contacts.")),
@ -1241,6 +1272,7 @@ function admin_page_plugins(&$a){
'$title' => t('Administration'), '$title' => t('Administration'),
'$page' => t('Plugins'), '$page' => t('Plugins'),
'$submit' => t('Save Settings'), '$submit' => t('Save Settings'),
'$reload' => t('Reload active plugins'),
'$baseurl' => $a->get_baseurl(true), '$baseurl' => $a->get_baseurl(true),
'$function' => 'plugins', '$function' => 'plugins',
'$plugins' => $plugins, '$plugins' => $plugins,
@ -1393,11 +1425,27 @@ function admin_page_themes(&$a){
$admin_form=""; $admin_form="";
if (is_file("view/theme/$theme/config.php")){ if (is_file("view/theme/$theme/config.php")){
function __get_theme_admin_form(&$a, $theme) {
$orig_theme = $a->theme;
$orig_page = $a->page;
$orig_session_theme = $_SESSION['theme'];
require_once("view/theme/$theme/theme.php");
require_once("view/theme/$theme/config.php"); require_once("view/theme/$theme/config.php");
$_SESSION['theme'] = $theme;
$init = $theme."_init";
if(function_exists($init)) $init($a);
if(function_exists("theme_admin")){ if(function_exists("theme_admin")){
$admin_form = theme_admin($a); $admin_form = theme_admin($a);
} }
$_SESSION['theme'] = $orig_session_theme;
$a->theme = $orig_theme;
$a->page = $orig_page;
return $admin_form;
}
$admin_form = __get_theme_admin_form($a, $theme);
} }
$screenshot = array( get_theme_screenshot($theme), t('Screenshot')); $screenshot = array( get_theme_screenshot($theme), t('Screenshot'));
@ -1427,6 +1475,22 @@ function admin_page_themes(&$a){
)); ));
} }
// reload active themes
if (x($_GET,"a") && $_GET['a']=="r"){
check_form_security_token_redirectOnErr($a->get_baseurl().'/admin/themes', 'admin_themes', 't');
if ($themes) {
foreach($themes as $th) {
if ($th['allowed']) {
uninstall_theme($th['name']);
install_theme($th['name']);
}
}
}
info("Themes reloaded");
goaway($a->get_baseurl().'/admin/themes');
}
/** /**
* List themes * List themes
*/ */
@ -1438,11 +1502,13 @@ function admin_page_themes(&$a){
} }
} }
$t = get_markup_template("admin_plugins.tpl"); $t = get_markup_template("admin_plugins.tpl");
return replace_macros($t, array( return replace_macros($t, array(
'$title' => t('Administration'), '$title' => t('Administration'),
'$page' => t('Themes'), '$page' => t('Themes'),
'$submit' => t('Save Settings'), '$submit' => t('Save Settings'),
'$reload' => t('Reload active themes'),
'$baseurl' => $a->get_baseurl(true), '$baseurl' => $a->get_baseurl(true),
'$function' => 'themes', '$function' => 'themes',
'$plugins' => $xthemes, '$plugins' => $xthemes,

View file

@ -1,6 +1,9 @@
<?php <?php
require_once('include/socgraph.php'); require_once('include/socgraph.php');
require_once('include/Contact.php');
require_once('include/contact_selectors.php');
require_once('mod/contacts.php');
function allfriends_content(&$a) { function allfriends_content(&$a) {
@ -12,52 +15,85 @@ function allfriends_content(&$a) {
if($a->argc > 1) if($a->argc > 1)
$cid = intval($a->argv[1]); $cid = intval($a->argv[1]);
if(! $cid) if(! $cid)
return; return;
$c = q("select name, url, photo from contact where id = %d and uid = %d limit 1", $uid = $a->user[uid];
$c = q("SELECT `name`, `url`, `photo` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($cid), intval($cid),
intval(local_user()) intval(local_user())
); );
$vcard_widget .= replace_macros(get_markup_template("vcard-widget.tpl"),array(
'$name' => $c[0]['name'],
'$photo' => $c[0]['photo'],
'url' => z_root() . '/contacts/' . $cid
));
if(! x($a->page,'aside'))
$a->page['aside'] = '';
$a->page['aside'] .= $vcard_widget;
if(! count($c)) if(! count($c))
return; return;
$o .= replace_macros(get_markup_template("section_title.tpl"),array( $a->page['aside'] = "";
'$title' => sprintf( t('Friends of %s'), $c[0]['name']) profile_load($a, "", 0, get_contact_details_by_url($c[0]["url"]));
));
$total = count_all_friends(local_user(), $cid);
$r = all_friends(local_user(),$cid); if(count($total))
$a->set_pager_total($total);
$r = all_friends(local_user(), $cid, $a->pager['start'], $a->pager['itemspage']);
if(! count($r)) { if(! count($r)) {
$o .= t('No friends to display.'); $o .= t('No friends to display.');
return $o; return $o;
} }
$tpl = get_markup_template('common_friends.tpl'); $id = 0;
foreach($r as $rr) { foreach($r as $rr) {
$o .= replace_macros($tpl,array( //get further details of the contact
'$url' => $rr['url'], $contact_details = get_contact_details_by_url($rr['url'], $uid);
'$name' => $rr['name'],
'$photo' => $rr['photo'], $photo_menu = '';
'$tags' => ''
)); // $rr[cid] is only available for common contacts. So if the contact is a common one, use contact_photo_menu to generate the photo_menu
// If the contact is not common to the user, Connect/Follow' will be added to the photo menu
if ($rr[cid]) {
$rr[id] = $rr[cid];
$photo_menu = contact_photo_menu ($rr);
}
else {
$connlnk = $a->get_baseurl() . '/follow/?url=' . $rr['url'];
$photo_menu = array(array(t("View Profile"), zrl($rr['url'])));
$photo_menu[] = array(t("Connect/Follow"), $connlnk);
} }
$o .= cleardiv(); $entry = array(
// $o .= paginate($a); 'url' => $rr['url'],
'itemurl' => (($contact_details['addr'] != "") ? $contact_details['addr'] : $rr['url']),
'name' => htmlentities($rr['name']),
'thumb' => proxy_url($rr['photo'], false, PROXY_SIZE_THUMB),
'img_hover' => htmlentities($rr['name']),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
'account_type' => (($contact_details['community']) ? t('Forum') : ''),
'network' => network_to_name($contact_details['network'], $contact_details['url']),
'photo_menu' => $photo_menu,
'conntxt' => t('Connect'),
'connlnk' => $connlnk,
'id' => ++$id,
);
$entries[] = $entry;
}
$tab_str = contacts_tab($a, $cid, 3);
$tpl = get_markup_template('viewcontact_template.tpl');
$o .= replace_macros($tpl,array(
//'$title' => sprintf( t('Friends of %s'), htmlentities($c[0]['name'])),
'$tab_str' => $tab_str,
'$contacts' => $entries,
'$paginate' => paginate($a),
));
return $o; return $o;
} }

View file

@ -1,6 +1,9 @@
<?php <?php
require_once('include/socgraph.php'); require_once('include/socgraph.php');
require_once('include/Contact.php');
require_once('include/contact_selectors.php');
require_once('mod/contacts.php');
function common_content(&$a) { function common_content(&$a) {
@ -11,25 +14,31 @@ function common_content(&$a) {
$cid = intval($a->argv[3]); $cid = intval($a->argv[3]);
$zcid = 0; $zcid = 0;
if (! local_user()) {
notice( t('Permission denied.') . EOL);
return;
}
if($cmd !== 'loc' && $cmd != 'rem') if($cmd !== 'loc' && $cmd != 'rem')
return; return;
if(! $uid) if(! $uid)
return; return;
if($cmd === 'loc' && $cid) { if($cmd === 'loc' && $cid) {
$c = q("select name, url, photo from contact where id = %d and uid = %d limit 1", $c = q("SELECT `name`, `url`, `photo` FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($cid), intval($cid),
intval($uid) intval($uid)
); );
} $a->page['aside'] = "";
else { profile_load($a, "", 0, get_contact_details_by_url($c[0]["url"]));
$c = q("select name, url, photo from contact where self = 1 and uid = %d limit 1", } else {
$c = q("SELECT `name`, `url`, `photo` FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
intval($uid) intval($uid)
); );
}
$vcard_widget .= replace_macros(get_markup_template("vcard-widget.tpl"),array( $vcard_widget .= replace_macros(get_markup_template("vcard-widget.tpl"),array(
'$name' => $c[0]['name'], '$name' => htmlentities($c[0]['name']),
'$photo' => $c[0]['photo'], '$photo' => $c[0]['photo'],
'url' => z_root() . '/contacts/' . $cid 'url' => z_root() . '/contacts/' . $cid
)); ));
@ -37,25 +46,21 @@ function common_content(&$a) {
if(! x($a->page,'aside')) if(! x($a->page,'aside'))
$a->page['aside'] = ''; $a->page['aside'] = '';
$a->page['aside'] .= $vcard_widget; $a->page['aside'] .= $vcard_widget;
}
if(! count($c)) if(! count($c))
return; return;
$o .= replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => t('Common Friends')
));
if(! $cid) { if(! $cid) {
if(get_my_url()) { if(get_my_url()) {
$r = q("select id from contact where nurl = '%s' and uid = %d limit 1", $r = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1",
dbesc(normalise_link(get_my_url())), dbesc(normalise_link(get_my_url())),
intval($profile_uid) intval($profile_uid)
); );
if(count($r)) if(count($r))
$cid = $r[0]['id']; $cid = $r[0]['id'];
else { else {
$r = q("select id from gcontact where nurl = '%s' limit 1", $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
dbesc(normalise_link(get_my_url())) dbesc(normalise_link(get_my_url()))
); );
if(count($r)) if(count($r))
@ -71,42 +76,71 @@ function common_content(&$a) {
if($cid) if($cid)
$t = count_common_friends($uid,$cid); $t = count_common_friends($uid, $cid);
else else
$t = count_common_friends_zcid($uid,$zcid); $t = count_common_friends_zcid($uid, $zcid);
if(count($t))
$a->set_pager_total($t); $a->set_pager_total($t);
else {
if(! $t) {
notice( t('No contacts in common.') . EOL); notice( t('No contacts in common.') . EOL);
return $o; return $o;
} }
if($cid) if($cid)
$r = common_friends($uid,$cid); $r = common_friends($uid, $cid, $a->pager['start'], $a->pager['itemspage']);
else else
$r = common_friends_zcid($uid,$zcid); $r = common_friends_zcid($uid, $zcid, $a->pager['start'], $a->pager['itemspage']);
if(! count($r)) { if(! count($r)) {
return $o; return $o;
} }
$tpl = get_markup_template('common_friends.tpl'); $id = 0;
foreach($r as $rr) { foreach($r as $rr) {
$o .= replace_macros($tpl,array( //get further details of the contact
'$url' => $rr['url'], $contact_details = get_contact_details_by_url($rr['url'], $uid);
'$name' => $rr['name'],
'$photo' => $rr['photo'], // $rr[id] is needed to use contact_photo_menu()
'$tags' => '' $rr[id] = $rr[cid];
));
$photo_menu = '';
$photo_menu = contact_photo_menu ($rr);
$entry = array(
'url' => $rr['url'],
'itemurl' => (($contact_details['addr'] != "") ? $contact_details['addr'] : $rr['url']),
'name' => $rr['name'],
'thumb' => proxy_url($rr['photo'], false, PROXY_SIZE_THUMB),
'img_hover' => htmlentities($rr['name']),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
'account_type' => (($contact_details['community']) ? t('Forum') : ''),
'network' => network_to_name($contact_details['network'], $contact_details['url']),
'photo_menu' => $photo_menu,
'id' => ++$id,
);
$entries[] = $entry;
} }
$o .= cleardiv(); if($cmd === 'loc' && $cid && $uid == local_user()) {
// $o .= paginate($a); $tab_str = contacts_tab($a, $cid, 4);
} else
$title = t('Common Friends');
$tpl = get_markup_template('viewcontact_template.tpl');
$o .= replace_macros($tpl,array(
'$title' => $title,
'$tab_str' => $tab_str,
'$contacts' => $entries,
'$paginate' => paginate($a),
));
return $o; return $o;
} }

View file

@ -13,7 +13,7 @@ function contacts_init(&$a) {
$contact_id = 0; $contact_id = 0;
if(($a->argc == 2) && intval($a->argv[1])) { if((($a->argc == 2) && intval($a->argv[1])) OR (($a->argc == 3) && intval($a->argv[1]) && ($a->argv[2] == "posts"))) {
$contact_id = intval($a->argv[1]); $contact_id = intval($a->argv[1]);
$r = q("SELECT * FROM `contact` WHERE `uid` = %d and `id` = %d LIMIT 1", $r = q("SELECT * FROM `contact` WHERE `uid` = %d and `id` = %d LIMIT 1",
intval(local_user()), intval(local_user()),
@ -27,41 +27,55 @@ function contacts_init(&$a) {
require_once('include/group.php'); require_once('include/group.php');
require_once('include/contact_widgets.php'); require_once('include/contact_widgets.php');
if ($_GET['nets'] == "all")
$_GET['nets'] = "";
if(! x($a->page,'aside')) if(! x($a->page,'aside'))
$a->page['aside'] = ''; $a->page['aside'] = '';
if($contact_id) { if($contact_id) {
$a->data['contact'] = $r[0]; $a->data['contact'] = $r[0];
if (($a->data['contact']['network'] != "") AND ($a->data['contact']['network'] != NETWORK_DFRN)) {
$networkname = format_network_name($a->data['contact']['network'],$a->data['contact']['url']);
} else
$networkname = '';
$vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"),array( $vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"),array(
'$name' => $a->data['contact']['name'], '$name' => htmlentities($a->data['contact']['name']),
'$photo' => $a->data['contact']['photo'], '$photo' => $a->data['contact']['photo'],
'$url' => ($a->data['contact']['network'] == NETWORK_DFRN) ? $a->get_baseurl()."/redir/".$a->data['contact']['id'] : $a->data['contact']['url'] '$url' => ($a->data['contact']['network'] == NETWORK_DFRN) ? z_root()."/redir/".$a->data['contact']['id'] : $a->data['contact']['url'],
'$addr' => (($a->data['contact']['addr'] != "") ? ($a->data['contact']['addr']) : ""),
'$network_name' => $networkname,
'$network' => t('Network:'),
'account_type' => (($a->data['contact']['forum'] || $a->data['contact']['prv']) ? t('Forum') : '')
)); ));
$finpeople_widget = '';
$follow_widget = ''; $follow_widget = '';
$networks_widget = '';
} }
else { else {
$vcard_widget = ''; $vcard_widget = '';
$networks_widget .= networks_widget('contacts',$_GET['nets']);
if (isset($_GET['add'])) if (isset($_GET['add']))
$follow_widget = follow_widget($_GET['add']); $follow_widget = follow_widget($_GET['add']);
else else
$follow_widget = follow_widget(); $follow_widget = follow_widget();
$findpeople_widget .= findpeople_widget();
} }
if ($_GET['nets'] == "all") $groups_widget .= group_side('contacts','group','full',0,$contact_id);
$_GET['nets'] = "";
$groups_widget .= group_side('contacts','group',false,0,$contact_id);
$findpeople_widget .= findpeople_widget();
$networks_widget .= networks_widget('contacts',$_GET['nets']);
$a->page['aside'] .= replace_macros(get_markup_template("contacts-widget-sidebar.tpl"),array( $a->page['aside'] .= replace_macros(get_markup_template("contacts-widget-sidebar.tpl"),array(
'$vcard_widget' => $vcard_widget, '$vcard_widget' => $vcard_widget,
'$findpeople_widget' => $findpeople_widget,
'$follow_widget' => $follow_widget, '$follow_widget' => $follow_widget,
'$groups_widget' => $groups_widget, '$groups_widget' => $groups_widget,
'$findpeople_widget' => $findpeople_widget,
'$networks_widget' => $networks_widget '$networks_widget' => $networks_widget
)); ));
$base = $a->get_baseurl(); $base = z_root();
$tpl = get_markup_template("contacts-head.tpl"); $tpl = get_markup_template("contacts-head.tpl");
$a->page['htmlhead'] .= replace_macros($tpl,array( $a->page['htmlhead'] .= replace_macros($tpl,array(
'$baseurl' => $a->get_baseurl(true), '$baseurl' => $a->get_baseurl(true),
@ -238,12 +252,12 @@ function _contact_update_profile($contact_id) {
$data = probe_url($r[0]["url"]); $data = probe_url($r[0]["url"]);
// "Feed" is mostly a sign of communication problems // "Feed" or "Unknown" is mostly a sign of communication problems
if (($data["network"] == NETWORK_FEED) AND ($data["network"] != $r[0]["network"])) if ((in_array($data["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) AND ($data["network"] != $r[0]["network"]))
return; return;
$updatefields = array("name", "nick", "url", "addr", "batch", "notify", "poll", "request", "confirm", $updatefields = array("name", "nick", "url", "addr", "batch", "notify", "poll", "request", "confirm",
"poco", "network", "alias", "pubkey"); "poco", "network", "alias");
$update = array(); $update = array();
if ($data["network"] == NETWORK_OSTATUS) { if ($data["network"] == NETWORK_OSTATUS) {
@ -460,6 +474,9 @@ function contacts_content(&$a) {
goaway($a->get_baseurl(true) . '/contacts'); goaway($a->get_baseurl(true) . '/contacts');
return; // NOTREACHED return; // NOTREACHED
} }
if($cmd === 'posts') {
return contact_posts($a, $contact_id);
}
} }
@ -509,7 +526,7 @@ function contacts_content(&$a) {
if(!in_array($contact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) if(!in_array($contact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
$relation_text = ""; $relation_text = "";
$relation_text = sprintf($relation_text,$contact['name']); $relation_text = sprintf($relation_text,htmlentities($contact['name']));
if(($contact['network'] === NETWORK_DFRN) && ($contact['rel'])) { if(($contact['network'] === NETWORK_DFRN) && ($contact['rel'])) {
$url = "redir/{$contact['id']}"; $url = "redir/{$contact['id']}";
@ -535,48 +552,16 @@ function contacts_content(&$a) {
$nettype = sprintf( t('Network type: %s'),network_to_name($contact['network'], $contact["url"])); $nettype = sprintf( t('Network type: %s'),network_to_name($contact['network'], $contact["url"]));
$common = count_common_friends(local_user(),$contact['id']); //$common = count_common_friends(local_user(),$contact['id']);
$common_text = (($common) ? sprintf( tt('%d contact in common','%d contacts in common', $common),$common) : ''); //$common_text = (($common) ? sprintf( tt('%d contact in common','%d contacts in common', $common),$common) : '');
$polling = (($contact['network'] === NETWORK_MAIL | $contact['network'] === NETWORK_FEED) ? 'polling' : ''); $polling = (($contact['network'] === NETWORK_MAIL | $contact['network'] === NETWORK_FEED) ? 'polling' : '');
$x = count_all_friends(local_user(), $contact['id']); //$x = count_all_friends(local_user(), $contact['id']);
$all_friends = (($x) ? t('View all contacts') : ''); //$all_friends = (($x) ? t('View all contacts') : '');
// tabs // tabs
$tabs = array( $tab_str = contacts_tab($a, $contact_id, 2);
array(
'label' => (($contact['blocked']) ? t('Unblock') : t('Block') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/block',
'sel' => '',
'title' => t('Toggle Blocked status'),
'accesskey' => 'b',
),
array(
'label' => (($contact['readonly']) ? t('Unignore') : t('Ignore') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/ignore',
'sel' => '',
'title' => t('Toggle Ignored status'),
'accesskey' => 'i',
),
array(
'label' => (($contact['archive']) ? t('Unarchive') : t('Archive') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/archive',
'sel' => '',
'title' => t('Toggle Archive status'),
'accesskey' => 'v',
),
array(
'label' => t('Repair'),
'url' => $a->get_baseurl(true) . '/crepair/' . $contact_id,
'sel' => '',
'title' => t('Advanced Contact Settings'),
'accesskey' => 'r',
)
);
$tab_tpl = get_markup_template('common_tabs.tpl');
$tab_str = replace_macros($tab_tpl, array('$tabs' => $tabs));
$lost_contact = (($contact['archive'] && $contact['term-date'] != '0000-00-00 00:00:00' && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : ''); $lost_contact = (($contact['archive'] && $contact['term-date'] != '0000-00-00 00:00:00' && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : '');
@ -590,8 +575,13 @@ function contacts_content(&$a) {
if ($contact['network'] == NETWORK_DFRN) if ($contact['network'] == NETWORK_DFRN)
$profile_select = contact_profile_assign($contact['profile-id'],(($contact['network'] !== NETWORK_DFRN) ? true : false)); $profile_select = contact_profile_assign($contact['profile-id'],(($contact['network'] !== NETWORK_DFRN) ? true : false));
if (in_array($contact['network'], array(NETWORK_DIASPORA, NETWORK_OSTATUS)) AND
($contact['rel'] == CONTACT_IS_FOLLOWER))
$follow = $a->get_baseurl(true)."/follow?url=".urlencode($contact["url"]);
$o .= replace_macros($tpl, array( $o .= replace_macros($tpl, array(
'$header' => t('Contact Editor'), //'$header' => t('Contact Editor'),
'$tab_str' => $tab_str, '$tab_str' => $tab_str,
'$submit' => t('Submit'), '$submit' => t('Submit'),
'$lbl_vis1' => t('Profile Visibility'), '$lbl_vis1' => t('Profile Visibility'),
@ -617,6 +607,8 @@ function contacts_content(&$a) {
'$updpub' => t('Update public posts'), '$updpub' => t('Update public posts'),
'$last_update' => $last_update, '$last_update' => $last_update,
'$udnow' => t('Update now'), '$udnow' => t('Update now'),
'$follow' => $follow,
'$follow_text' => t("Connect/Follow"),
'$profile_select' => $profile_select, '$profile_select' => $profile_select,
'$contact_id' => $contact['id'], '$contact_id' => $contact['id'],
'$block_text' => (($contact['blocked']) ? t('Unblock') : t('Block') ), '$block_text' => (($contact['blocked']) ? t('Unblock') : t('Block') ),
@ -632,13 +624,19 @@ function contacts_content(&$a) {
'$ffi_keyword_blacklist' => $contact['ffi_keyword_blacklist'], '$ffi_keyword_blacklist' => $contact['ffi_keyword_blacklist'],
'$ffi_keyword_blacklist' => array('ffi_keyword_blacklist', t('Blacklisted keywords'), $contact['ffi_keyword_blacklist'], t('Comma separated list of keywords that should not be converted to hashtags, when "Fetch information and keywords" is selected')), '$ffi_keyword_blacklist' => array('ffi_keyword_blacklist', t('Blacklisted keywords'), $contact['ffi_keyword_blacklist'], t('Comma separated list of keywords that should not be converted to hashtags, when "Fetch information and keywords" is selected')),
'$photo' => $contact['photo'], '$photo' => $contact['photo'],
'$name' => $contact['name'], '$name' => htmlentities($contact['name']),
'$dir_icon' => $dir_icon, '$dir_icon' => $dir_icon,
'$alt_text' => $alt_text, '$alt_text' => $alt_text,
'$sparkle' => $sparkle, '$sparkle' => $sparkle,
'$url' => $url, '$url' => $url,
'$profileurllabel' => t('Profile URL'), '$profileurllabel' => t('Profile URL'),
'$profileurl' => $contact['url'], '$profileurl' => $contact['url'],
'$location' => bbcode($contact["location"]),
'$location_label' => t("Location:"),
'$about' => bbcode($contact["about"], false, false),
'$about_label' => t("About:"),
'$keywords' => $contact["keywords"],
'$keywords_label' => t("Tags:")
)); ));
@ -687,6 +685,7 @@ function contacts_content(&$a) {
'url' => $a->get_baseurl(true) . '/suggest', 'url' => $a->get_baseurl(true) . '/suggest',
'sel' => '', 'sel' => '',
'title' => t('Suggest potential friends'), 'title' => t('Suggest potential friends'),
'id' => 'suggestions-tab',
'accesskey' => 'g', 'accesskey' => 'g',
), ),
array( array(
@ -694,6 +693,7 @@ function contacts_content(&$a) {
'url' => $a->get_baseurl(true) . '/contacts/all', 'url' => $a->get_baseurl(true) . '/contacts/all',
'sel' => ($all) ? 'active' : '', 'sel' => ($all) ? 'active' : '',
'title' => t('Show all contacts'), 'title' => t('Show all contacts'),
'id' => 'showall-tab',
'accesskey' => 'l', 'accesskey' => 'l',
), ),
array( array(
@ -701,6 +701,7 @@ function contacts_content(&$a) {
'url' => $a->get_baseurl(true) . '/contacts', 'url' => $a->get_baseurl(true) . '/contacts',
'sel' => ((! $all) && (! $blocked) && (! $hidden) && (! $search) && (! $nets) && (! $ignored) && (! $archived)) ? 'active' : '', 'sel' => ((! $all) && (! $blocked) && (! $hidden) && (! $search) && (! $nets) && (! $ignored) && (! $archived)) ? 'active' : '',
'title' => t('Only show unblocked contacts'), 'title' => t('Only show unblocked contacts'),
'id' => 'showunblocked-tab',
'accesskey' => 'o', 'accesskey' => 'o',
), ),
@ -709,6 +710,7 @@ function contacts_content(&$a) {
'url' => $a->get_baseurl(true) . '/contacts/blocked', 'url' => $a->get_baseurl(true) . '/contacts/blocked',
'sel' => ($blocked) ? 'active' : '', 'sel' => ($blocked) ? 'active' : '',
'title' => t('Only show blocked contacts'), 'title' => t('Only show blocked contacts'),
'id' => 'showblocked-tab',
'accesskey' => 'b', 'accesskey' => 'b',
), ),
@ -717,6 +719,7 @@ function contacts_content(&$a) {
'url' => $a->get_baseurl(true) . '/contacts/ignored', 'url' => $a->get_baseurl(true) . '/contacts/ignored',
'sel' => ($ignored) ? 'active' : '', 'sel' => ($ignored) ? 'active' : '',
'title' => t('Only show ignored contacts'), 'title' => t('Only show ignored contacts'),
'id' => 'showignored-tab',
'accesskey' => 'i', 'accesskey' => 'i',
), ),
@ -725,6 +728,7 @@ function contacts_content(&$a) {
'url' => $a->get_baseurl(true) . '/contacts/archived', 'url' => $a->get_baseurl(true) . '/contacts/archived',
'sel' => ($archived) ? 'active' : '', 'sel' => ($archived) ? 'active' : '',
'title' => t('Only show archived contacts'), 'title' => t('Only show archived contacts'),
'id' => 'showarchived-tab',
'accesskey' => 'y', 'accesskey' => 'y',
), ),
@ -733,6 +737,7 @@ function contacts_content(&$a) {
'url' => $a->get_baseurl(true) . '/contacts/hidden', 'url' => $a->get_baseurl(true) . '/contacts/hidden',
'sel' => ($hidden) ? 'active' : '', 'sel' => ($hidden) ? 'active' : '',
'title' => t('Only show hidden contacts'), 'title' => t('Only show hidden contacts'),
'id' => 'showhidden-tab',
'accesskey' => 'h', 'accesskey' => 'h',
), ),
@ -765,8 +770,9 @@ function contacts_content(&$a) {
$total = $r[0]['total']; $total = $r[0]['total'];
} }
$sql_extra3 = unavailable_networks();
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 ORDER BY `name` ASC LIMIT %d , %d ", $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `pending` = 0 $sql_extra $sql_extra2 $sql_extra3 ORDER BY `name` ASC LIMIT %d , %d ",
intval($_SESSION['uid']), intval($_SESSION['uid']),
intval($a->pager['start']), intval($a->pager['start']),
intval($a->pager['itemspage']) intval($a->pager['itemspage'])
@ -782,7 +788,7 @@ function contacts_content(&$a) {
$tpl = get_markup_template("contacts-template.tpl"); $tpl = get_markup_template("contacts-template.tpl");
$o .= replace_macros($tpl, array( $o .= replace_macros($tpl, array(
'$baseurl' => $a->get_baseurl(), '$baseurl' => z_root(),
'$header' => t('Contacts') . (($nets) ? ' - ' . network_to_name($nets) : ''), '$header' => t('Contacts') . (($nets) ? ' - ' . network_to_name($nets) : ''),
'$tabs' => $t, '$tabs' => $t,
'$total' => $total, '$total' => $total,
@ -793,6 +799,7 @@ function contacts_content(&$a) {
'$cmd' => $a->cmd, '$cmd' => $a->cmd,
'$contacts' => $contacts, '$contacts' => $contacts,
'$contact_drop_confirm' => t('Do you really want to delete this contact?'), '$contact_drop_confirm' => t('Do you really want to delete this contact?'),
'multiselect' => 1,
'$batch_actions' => array( '$batch_actions' => array(
'contacts_batch_update' => t('Update'), 'contacts_batch_update' => t('Update'),
'contacts_batch_block' => t('Block')."/".t("Unblock"), 'contacts_batch_block' => t('Block')."/".t("Unblock"),
@ -807,7 +814,135 @@ function contacts_content(&$a) {
return $o; return $o;
} }
function contacts_tab($a, $contact_id, $active_tab) {
// tabs
$tabs = array(
array(
'label'=>t('Status'),
'url' => "contacts/".$contact_id."/posts",
'sel' => (($active_tab == 1)?'active':''),
'title' => t('Status Messages and Posts'),
'id' => 'status-tab',
'accesskey' => 'm',
),
array(
'label'=>t('Profile'),
'url' => "contacts/".$contact_id,
'sel' => (($active_tab == 2)?'active':''),
'title' => t('Profile Details'),
'id' => 'status-tab',
'accesskey' => 'o',
)
);
$x = count_all_friends(local_user(), $contact_id);
if ($x)
$tabs[] = array('label'=>t('Contacts'),
'url' => "allfriends/".$contact_id,
'sel' => (($active_tab == 3)?'active':''),
'title' => t('View all contacts'),
'id' => 'allfriends-tab',
'accesskey' => 't');
$common = count_common_friends(local_user(),$contact_id);
if ($common)
$tabs[] = array('label'=>t('Common Friends'),
'url' => "common/loc/".local_user()."/".$contact_id,
'sel' => (($active_tab == 4)?'active':''),
'title' => t('View all common friends'),
'id' => 'common-loc-tab',
'accesskey' => 'd');
$tabs[] = array('label' => t('Repair'),
'url' => $a->get_baseurl(true) . '/crepair/' . $contact_id,
'sel' => (($active_tab == 5)?'active':''),
'title' => t('Advanced Contact Settings'),
'id' => 'repair-tab',
'accesskey' => 'r');
$tabs[] = array('label' => (($contact['blocked']) ? t('Unblock') : t('Block') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/block',
'sel' => '',
'title' => t('Toggle Blocked status'),
'id' => 'toggle-block-tab',
'accesskey' => 'b');
$tabs[] = array('label' => (($contact['readonly']) ? t('Unignore') : t('Ignore') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/ignore',
'sel' => '',
'title' => t('Toggle Ignored status'),
'id' => 'toggle-ignore-tab',
'accesskey' => 'i');
$tabs[] = array('label' => (($contact['archive']) ? t('Unarchive') : t('Archive') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/archive',
'sel' => '',
'title' => t('Toggle Archive status'),
'id' => 'toggle-archive-tab',
'accesskey' => 'v');
$tab_tpl = get_markup_template('common_tabs.tpl');
$tab_str = replace_macros($tab_tpl, array('$tabs' => $tabs));
return $tab_str;
}
function contact_posts($a, $contact_id) {
require_once('include/conversation.php');
$r = q("SELECT * FROM `contact` WHERE `id` = %d", intval($contact_id));
if ($r) {
$contact = $r[0];
$a->page['aside'] = "";
profile_load($a, "", 0, get_contact_details_by_url($contact["url"]));
}
if(get_config('system', 'old_pager')) {
$r = q("SELECT COUNT(*) AS `total` FROM `item`
WHERE `item`.`uid` = %d AND `author-link` IN ('%s', '%s')",
intval(local_user()),
dbesc(str_replace("https://", "http://", $contact["url"])),
dbesc(str_replace("http://", "https://", $contact["url"])));
$a->set_pager_total($r[0]['total']);
}
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`author-name` AS `name`, `owner-avatar` AS `photo`,
`owner-link` AS `url`, `owner-avatar` AS `thumb`
FROM `item` FORCE INDEX (uid_contactid_created)
WHERE `item`.`uid` = %d AND `contact-id` = %d
AND `author-link` IN ('%s', '%s')
ORDER BY `item`.`created` DESC LIMIT %d, %d",
intval(local_user()),
intval($contact_id),
dbesc(str_replace("https://", "http://", $contact["url"])),
dbesc(str_replace("http://", "https://", $contact["url"])),
intval($a->pager['start']),
intval($a->pager['itemspage'])
);
$tab_str = contacts_tab($a, $contact_id, 1);
$o .= $tab_str;
$o .= conversation($a,$r,'community',false);
if(!get_config('system', 'old_pager')) {
$o .= alt_pager($a,count($r));
} else {
$o .= paginate($a);
}
return $o;
}
function _contact_detail_for_template($rr){ function _contact_detail_for_template($rr){
$community = '';
switch($rr['rel']) { switch($rr['rel']) {
case CONTACT_IS_FRIEND: case CONTACT_IS_FRIEND:
$dir_icon = 'images/lrarrow.gif'; $dir_icon = 'images/lrarrow.gif';
@ -833,6 +968,10 @@ function _contact_detail_for_template($rr){
$sparkle = ''; $sparkle = '';
} }
//test if contact is a forum page
if (isset($rr['forum']) OR isset($rr['prv']))
$community = ($rr['forum'] OR $rr['prv']);
return array( return array(
'img_hover' => sprintf( t('Visit %s\'s profile [%s]'),$rr['name'],$rr['url']), 'img_hover' => sprintf( t('Visit %s\'s profile [%s]'),$rr['name'],$rr['url']),
@ -841,11 +980,12 @@ function _contact_detail_for_template($rr){
'id' => $rr['id'], 'id' => $rr['id'],
'alt_text' => $alt_text, 'alt_text' => $alt_text,
'dir_icon' => $dir_icon, 'dir_icon' => $dir_icon,
'thumb' => proxy_url($rr['thumb']), 'thumb' => proxy_url($rr['thumb'], false, PROXY_SIZE_THUMB),
'name' => $rr['name'], 'name' => htmlentities($rr['name']),
'username' => $rr['name'], 'username' => htmlentities($rr['name']),
'account_type' => ($community ? t('Forum') : ''),
'sparkle' => $sparkle, 'sparkle' => $sparkle,
'itemurl' => $rr['url'], 'itemurl' => (($rr['addr'] != "") ? $rr['addr'] : $rr['url']),
'url' => $url, 'url' => $url,
'network' => network_to_name($rr['network'], $rr['url']), 'network' => network_to_name($rr['network'], $rr['url']),
); );

View file

@ -476,7 +476,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
'name' => $name_e, 'name' => $name_e,
'sparkle' => $sparkle, 'sparkle' => $sparkle,
'lock' => $lock, 'lock' => $lock,
'thumb' => proxy_url($profile_avatar), 'thumb' => proxy_url($profile_avatar, false, PROXY_SIZE_THUMB),
'title' => $title_e, 'title' => $title_e,
'body' => $body_e, 'body' => $body_e,
'text' => $text_e, 'text' => $text_e,
@ -485,7 +485,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
'indent' => '', 'indent' => '',
'owner_name' => $owner_name_e, 'owner_name' => $owner_name_e,
'owner_url' => $owner_url, 'owner_url' => $owner_url,
'owner_photo' => proxy_url($owner_photo), 'owner_photo' => proxy_url($owner_photo, false, PROXY_SIZE_THUMB),
'plink' => get_plink($item), 'plink' => get_plink($item),
'edpost' => false, 'edpost' => false,
'isstarred' => $isstarred, 'isstarred' => $isstarred,
@ -859,7 +859,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
'profile_url' => $profile_link, 'profile_url' => $profile_link,
'item_photo_menu' => item_photo_menu($item), 'item_photo_menu' => item_photo_menu($item),
'name' => $name_e, 'name' => $name_e,
'thumb' => proxy_url($profile_avatar), 'thumb' => proxy_url($profile_avatar, false, PROXY_SIZE_THUMB),
'osparkle' => $osparkle, 'osparkle' => $osparkle,
'sparkle' => $sparkle, 'sparkle' => $sparkle,
'title' => $title_e, 'title' => $title_e,
@ -869,7 +869,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
'indent' => $indent, 'indent' => $indent,
'shiny' => $shiny, 'shiny' => $shiny,
'owner_url' => $owner_url, 'owner_url' => $owner_url,
'owner_photo' => proxy_url($owner_photo), 'owner_photo' => proxy_url($owner_photo, false, PROXY_SIZE_THUMB),
'owner_name' => $owner_name_e, 'owner_name' => $owner_name_e,
'plink' => get_plink($item), 'plink' => get_plink($item),
'edpost' => $edpost, 'edpost' => $edpost,

20
mod/credits.php Normal file
View file

@ -0,0 +1,20 @@
<?php
/**
* Show a credits page for all the developers who helped with the project
* (only contributors to the git repositories for friendica core and the
* addons repository will be listed though ATM)
*/
function credits_content (&$a) {
/* fill the page with credits */
$f = fopen('util/credits.txt','r');
$names = fread($f, filesize('util/credits.txt'));
$arr = explode("\n", htmlspecialchars($names));
fclose($f);
$tpl = get_markup_template('credits.tpl');
return replace_macros( $tpl, array(
'$title' => t('Credits'),
'$thanks' => t('Friendica is a community project, that would not be possible without the help of many people. Here is a list of those who have contributed to the code or the translation of Friendica. Thank you all!'),
'$names' => $arr,
));
}

View file

@ -1,4 +1,6 @@
<?php <?php
require_once("include/contact_selectors.php");
require_once("mod/contacts.php");
function crepair_init(&$a) { function crepair_init(&$a) {
if(! local_user()) if(! local_user())
@ -22,13 +24,8 @@ function crepair_init(&$a) {
if($contact_id) { if($contact_id) {
$a->data['contact'] = $r[0]; $a->data['contact'] = $r[0];
$tpl = get_markup_template("vcard-widget.tpl"); $contact = $r[0];
$vcard_widget .= replace_macros($tpl, array( profile_load($a, "", 0, get_contact_details_by_url($contact["url"]));
'$name' => $a->data['contact']['name'],
'$photo' => $a->data['contact']['photo']
));
$a->page['aside'] .= $vcard_widget;
} }
} }
@ -137,16 +134,10 @@ function crepair_content(&$a) {
$contact = $r[0]; $contact = $r[0];
$msg1 = t('Repair Contact Settings'); $warning = t('<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working.');
$info = t('Please use your browser \'Back\' button <strong>now</strong> if you are uncertain what to do on this page.');
$msg2 = t('<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working.'); $returnaddr = "contacts/$cid";
$msg3 = t('Please use your browser \'Back\' button <strong>now</strong> if you are uncertain what to do on this page.');
$o .= '<h2>' . $msg1 . '</h2>';
$o .= '<div class="error-message">' . $msg2 . EOL . EOL. $msg3 . '</div>';
$o .= EOL . '<a href="contacts/' . $cid . '">' . t('Return to contact editor') . '</a>' . EOL;
$allow_remote_self = get_config('system','allow_users_remote_self'); $allow_remote_self = get_config('system','allow_users_remote_self');
@ -163,8 +154,17 @@ function crepair_content(&$a) {
$update_profile = in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DSPR, NETWORK_OSTATUS)); $update_profile = in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DSPR, NETWORK_OSTATUS));
$tab_str = contacts_tab($a, $contact['id'], 5);
$tpl = get_markup_template('crepair.tpl'); $tpl = get_markup_template('crepair.tpl');
$o .= replace_macros($tpl, array( $o .= replace_macros($tpl, array(
//'$title' => t('Repair Contact Settings'),
'$tab_str' => $tab_str,
'$warning' => $warning,
'$info' => $info,
'$returnaddr' => $returnaddr,
'$return' => t('Return to contact editor'),
'$update_profile' => update_profile, '$update_profile' => update_profile,
'$udprofilenow' => t('Refetch contact data'), '$udprofilenow' => t('Refetch contact data'),
'$label_name' => t('Name'), '$label_name' => t('Name'),
@ -178,9 +178,14 @@ function crepair_content(&$a) {
'$label_photo' => t('New photo from this URL'), '$label_photo' => t('New photo from this URL'),
'$label_remote_self' => t('Remote Self'), '$label_remote_self' => t('Remote Self'),
'$allow_remote_self' => $allow_remote_self, '$allow_remote_self' => $allow_remote_self,
'$remote_self' => array('remote_self', t('Mirror postings from this contact'), $contact['remote_self'], t('Mark this contact as remote_self, this will cause friendica to repost new entries from this contact.'), $remote_self_options), '$remote_self' => array('remote_self',
'$contact_name' => $contact['name'], t('Mirror postings from this contact'),
'$contact_nick' => $contact['nick'], $contact['remote_self'],
t('Mark this contact as remote_self, this will cause friendica to repost new entries from this contact.'),
$remote_self_options
),
'$contact_name' => htmlentities($contact['name']),
'$contact_nick' => htmlentities($contact['nick']),
'$contact_id' => $contact['id'], '$contact_id' => $contact['id'],
'$contact_url' => $contact['url'], '$contact_url' => $contact['url'],
'$request' => $contact['request'], '$request' => $contact['request'],

View file

@ -382,7 +382,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
if($duplex) if($duplex)
$new_relation = CONTACT_IS_FRIEND; $new_relation = CONTACT_IS_FRIEND;
else else
$new_relation = CONTACT_IS_SHARING; $new_relation = CONTACT_IS_FOLLOWER;
if($new_relation != CONTACT_IS_FOLLOWER) if($new_relation != CONTACT_IS_FOLLOWER)
$writable = 1; $writable = 1;

View file

@ -564,5 +564,3 @@ function dfrn_poll_content(&$a) {
} }
} }
} }

View file

@ -146,13 +146,14 @@ function dfrn_request_post(&$a) {
* Create a contact record on our site for the other person * Create a contact record on our site for the other person
*/ */
$r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `name`, `nick`, `photo`, `site-pubkey`, $r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `addr`, `name`, `nick`, `photo`, `site-pubkey`,
`request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`, `hidden`) `request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`, `hidden`)
VALUES ( %d, '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)", VALUES ( %d, '%s', '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
intval(local_user()), intval(local_user()),
datetime_convert(), datetime_convert(),
dbesc($dfrn_url), dbesc($dfrn_url),
dbesc(normalise_link($dfrn_url)), dbesc(normalise_link($dfrn_url)),
$parms['addr'],
$parms['fn'], $parms['fn'],
$parms['nick'], $parms['nick'],
$parms['photo'], $parms['photo'],
@ -539,13 +540,14 @@ function dfrn_request_post(&$a) {
dbesc_array($parms); dbesc_array($parms);
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`,`name`, `nick`, `issued-id`, `photo`, `site-pubkey`, $r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `name`, `nick`, `issued-id`, `photo`, `site-pubkey`,
`request`, `confirm`, `notify`, `poll`, `poco`, `network` ) `request`, `confirm`, `notify`, `poll`, `poco`, `network` )
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )", VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
intval($uid), intval($uid),
dbesc(datetime_convert()), dbesc(datetime_convert()),
$parms['url'], $parms['url'],
dbesc(normalise_link($parms['url'])), dbesc(normalise_link($parms['url'])),
$parms['addr'],
$parms['fn'], $parms['fn'],
$parms['nick'], $parms['nick'],
$parms['issued-id'], $parms['issued-id'],

View file

@ -8,6 +8,8 @@ function directory_init(&$a) {
$a->page['aside'] .= findpeople_widget(); $a->page['aside'] .= findpeople_widget();
$a->page['aside'] .= follow_widget();
} }
else { else {
unset($_SESSION['theme']); unset($_SESSION['theme']);
@ -44,51 +46,38 @@ function directory_content(&$a) {
else else
$search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : ''); $search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
$tpl = get_markup_template('directory_header.tpl'); $gdirpath = '';
$dirurl = get_config('system','directory');
$globaldir = ''; if(strlen($dirurl)) {
$gdirpath = get_config('system','directory'); $gdirpath = zrl($dirurl,true);
if(strlen($gdirpath)) {
$globaldir = '<ul><li><div id="global-directory-link"><a href="'
. zrl($gdirpath,true) . '">' . t('Global Directory') . '</a></div></li></ul>';
} }
$admin = '';
$o .= replace_macros($tpl, array(
'$search' => $search,
'$globaldir' => $globaldir,
'$desc' => t('Find on this site'),
'$admin' => $admin,
'$finding' => (strlen($search) ? '<h4>' . t('Finding: ') . "'" . $search . "'" . '</h4>' : ""),
'$sitedir' => t('Site Directory'),
'$submit' => t('Find')
));
if($search) { if($search) {
$search = dbesc($search); $search = dbesc($search);
$sql_extra = " AND ((`profile`.`name` LIKE '%$search%') OR $sql_extra = " AND ((`profile`.`name` LIKE '%$search%') OR
(`user`.`nickname` LIKE '%$search%') OR (`user`.`nickname` LIKE '%$search%') OR
(`pdesc` LIKE '%$search%') OR (`profile`.`pdesc` LIKE '%$search%') OR
(`locality` LIKE '%$search%') OR (`profile`.`locality` LIKE '%$search%') OR
(`region` LIKE '%$search%') OR (`profile`.`region` LIKE '%$search%') OR
(`country-name` LIKE '%$search%') OR (`profile`.`country-name` LIKE '%$search%') OR
(`gender` LIKE '%$search%') OR (`profile`.`gender` LIKE '%$search%') OR
(`marital` LIKE '%$search%') OR (`profile`.`marital` LIKE '%$search%') OR
(`sexual` LIKE '%$search%') OR (`profile`.`sexual` LIKE '%$search%') OR
(`about` LIKE '%$search%') OR (`profile`.`about` LIKE '%$search%') OR
(`romance` LIKE '%$search%') OR (`profile`.`romance` LIKE '%$search%') OR
(`work` LIKE '%$search%') OR (`profile`.`work` LIKE '%$search%') OR
(`education` LIKE '%$search%') OR (`profile`.`education` LIKE '%$search%') OR
(`pub_keywords` LIKE '%$search%') OR (`profile`.`pub_keywords` LIKE '%$search%') OR
(`prv_keywords` LIKE '%$search%'))"; (`profile`.`prv_keywords` LIKE '%$search%'))";
} }
$publish = ((get_config('system','publish_all')) ? '' : " AND `publish` = 1 " ); $publish = ((get_config('system','publish_all')) ? '' : " AND `publish` = 1 " );
$r = $db->q("SELECT COUNT(*) AS `total` FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra "); $r = $db->q("SELECT COUNT(*) AS `total` FROM `profile`
LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra ");
if(count($r)) if(count($r))
$a->set_pager_total($r[0]['total']); $a->set_pager_total($r[0]['total']);
@ -96,7 +85,11 @@ function directory_content(&$a) {
$limit = intval($a->pager['start']).",".intval($a->pager['itemspage']); $limit = intval($a->pager['start']).",".intval($a->pager['itemspage']);
$r = $db->q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags` FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid` WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra $order LIMIT ".$limit); $r = $db->q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
`contact`.`addr`, `contact`.`url` AS profile_url FROM `profile`
LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 AND `contact`.`self` $sql_extra $order LIMIT ".$limit);
if(count($r)) { if(count($r)) {
if(in_array('small', $a->argv)) if(in_array('small', $a->argv))
@ -106,8 +99,12 @@ function directory_content(&$a) {
foreach($r as $rr) { foreach($r as $rr) {
$community = '';
$itemurl= '';
$profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']); $itemurl = (($rr['addr'] != "") ? $rr['addr'] : $rr['profile_url']);
$profile_link = z_root() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']);
$pdesc = (($rr['pdesc']) ? $rr['pdesc'] . '<br />' : ''); $pdesc = (($rr['pdesc']) ? $rr['pdesc'] . '<br />' : '');
@ -124,23 +121,19 @@ function directory_content(&$a) {
$details .= ', '; $details .= ', ';
$details .= $rr['country-name']; $details .= $rr['country-name'];
} }
if(strlen($rr['dob'])) { // if(strlen($rr['dob'])) {
if(($years = age($rr['dob'],$rr['timezone'],'')) != 0) // if(($years = age($rr['dob'],$rr['timezone'],'')) != 0)
$details .= '<br />' . t('Age: ') . $years ; // $details .= '<br />' . t('Age: ') . $years ;
} // }
if(strlen($rr['gender'])) // if(strlen($rr['gender']))
$details .= '<br />' . t('Gender: ') . $rr['gender']; // $details .= '<br />' . t('Gender: ') . $rr['gender'];
if($rr['page-flags'] == PAGE_NORMAL)
$page_type = "Personal Profile"; // show if account is a community account
if($rr['page-flags'] == PAGE_SOAPBOX) // ToDo the other should be also respected, but first we need a good translatiion
$page_type = "Fan Page"; // and systemwide consistency for displaying the page type
if($rr['page-flags'] == PAGE_COMMUNITY) if((intval($rr['page-flags']) == PAGE_COMMUNITY) OR (intval($rr['page-flags']) == PAGE_PRVGROUP))
$page_type = "Community Forum"; $community = true;
if($rr['page-flags'] == PAGE_FREELOVE)
$page_type = "Open Forum";
if($rr['page-flags'] == PAGE_PRVGROUP)
$page_type = "Private Group";
$profile = $rr; $profile = $rr;
@ -159,8 +152,6 @@ function directory_content(&$a) {
$about = ((x($profile,'about') == 1) ? t('About:') : False); $about = ((x($profile,'about') == 1) ? t('About:') : False);
$tpl = get_markup_template('directory_item.tpl');
if($a->theme['template_engine'] === 'internal') { if($a->theme['template_engine'] === 'internal') {
$location_e = template_escape($location); $location_e = template_escape($location);
} }
@ -168,23 +159,28 @@ function directory_content(&$a) {
$location_e = $location; $location_e = $location;
} }
$entry = replace_macros($tpl,array( $photo_menu = array(array(t("View Profile"), zrl($profile_link)));
'$id' => $rr['id'],
'$profile_link' => $profile_link,
'$photo' => proxy_url($a->get_cached_avatar_image($rr[$photo])),
'$alt_text' => $rr['name'],
'$name' => $rr['name'],
'$details' => $pdesc . $details,
'$page_type' => $page_type,
'$profile' => $profile,
'$location' => $location_e,
'$gender' => $gender,
'$pdesc' => $pdesc,
'$marital' => $marital,
'$homepage' => $homepage,
'$about' => $about,
)); $entry = array(
'id' => $rr['id'],
'url' => $profile_link,
'itemurl' => $itemurl,
'thumb' => proxy_url($a->get_cached_avatar_image($rr[$photo]), false, PROXY_SIZE_THUMB),
'img_hover' => $rr['name'],
'name' => $rr['name'],
'details' => $details,
'account_type' => ($community ? t('Forum') : ''),
'profile' => $profile,
'location' => $location_e,
'tags' => $rr['pub_keywords'],
'gender' => $gender,
'pdesc' => $pdesc,
'marital' => $marital,
'homepage' => $homepage,
'about' => $about,
'photo_menu' => $photo_menu,
);
$arr = array('contact' => $rr, 'entry' => $entry); $arr = array('contact' => $rr, 'entry' => $entry);
@ -193,12 +189,27 @@ function directory_content(&$a) {
unset($profile); unset($profile);
unset($location); unset($location);
$o .= $entry; if(! $arr['entry'])
continue;
$entries[] = $arr['entry'];
} }
$o .= "<div class=\"directory-end\" ></div>\r\n"; $tpl = get_markup_template('directory_header.tpl');
$o .= paginate($a);
$o .= replace_macros($tpl, array(
'$search' => $search,
'$globaldir' => t('Global Directory'),
'$gdirpath' => $gdirpath,
'$desc' => t('Find on this site'),
'$contacts' => $entries,
'$finding' => t('Finding:'),
'$findterm' => (strlen($search) ? $search : ""),
'$title' => t('Site Directory'),
'$submit' => t('Find'),
'$paginate' => paginate($a),
));
} }
else else

View file

@ -1,15 +1,23 @@
<?php <?php
require_once('include/contact_widgets.php'); require_once('include/contact_widgets.php');
require_once('include/socgraph.php'); require_once('include/socgraph.php');
require_once('include/Contact.php');
require_once('include/contact_selectors.php');
require_once('mod/contacts.php');
function dirfind_init(&$a) { function dirfind_init(&$a) {
if(! local_user()) {
notice( t('Permission denied.') . EOL );
return;
}
if(! x($a->page,'aside')) if(! x($a->page,'aside'))
$a->page['aside'] = ''; $a->page['aside'] = '';
$a->page['aside'] .= follow_widget();
$a->page['aside'] .= findpeople_widget(); $a->page['aside'] .= findpeople_widget();
$a->page['aside'] .= follow_widget();
} }
@ -17,13 +25,20 @@ function dirfind_init(&$a) {
function dirfind_content(&$a, $prefix = "") { function dirfind_content(&$a, $prefix = "") {
$community = false; $community = false;
$discover_user = false;
$local = get_config('system','poco_local_search'); $local = get_config('system','poco_local_search');
$search = $prefix.notags(trim($_REQUEST['search'])); $search = $prefix.notags(trim($_REQUEST['search']));
if(strpos($search,'@') === 0) if(strpos($search,'@') === 0) {
$search = substr($search,1); $search = substr($search,1);
if ((valid_email($search) AND validate_email($search)) OR
(substr(normalise_link($search), 0, 7) == "http://")) {
$user_data = probe_url($search);
$discover_user = (in_array($user_data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)));
}
}
if(strpos($search,'!') === 0) { if(strpos($search,'!') === 0) {
$search = substr($search,1); $search = substr($search,1);
@ -32,13 +47,34 @@ function dirfind_content(&$a, $prefix = "") {
$o = ''; $o = '';
$o .= replace_macros(get_markup_template("section_title.tpl"),array(
'$title' => sprintf( t('People Search - %s'), $search)
));
if($search) { if($search) {
if ($local) { if ($discover_user) {
$j = new stdClass();
$j->total = 1;
$j->items_page = 1;
$j->page = $a->pager['page'];
$objresult = new stdClass();
$objresult->cid = 0;
$objresult->name = $user_data["name"];
$objresult->addr = $user_data["addr"];
$objresult->url = $user_data["url"];
$objresult->photo = $user_data["photo"];
$objresult->tags = "";
$objresult->network = $user_data["network"];
$contact = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1",
dbesc(normalise_link($user_data["url"])), intval(local_user()));
if ($contact)
$objresult->cid = $contact[0]["id"];
$j->results[] = $objresult;
poco_check($user_data["url"], $user_data["name"], $user_data["network"], $user_data["photo"],
"", "", "", "", "", datetime_convert(), 0);
} elseif ($local) {
if ($community) if ($community)
$extra_sql = " AND `community`"; $extra_sql = " AND `community`";
@ -48,14 +84,24 @@ function dirfind_content(&$a, $prefix = "") {
$perpage = 80; $perpage = 80;
$startrec = (($a->pager['page']) * $perpage) - $perpage; $startrec = (($a->pager['page']) * $perpage) - $perpage;
if (get_config('system','diaspora_enabled'))
$diaspora = NETWORK_DIASPORA;
else
$diaspora = NETWORK_DFRN;
if (!get_config('system','ostatus_disabled'))
$ostatus = NETWORK_OSTATUS;
else
$ostatus = NETWORK_DFRN;
$count = q("SELECT count(*) AS `total` FROM `gcontact` WHERE `network` IN ('%s', '%s', '%s') AND $count = q("SELECT count(*) AS `total` FROM `gcontact` WHERE `network` IN ('%s', '%s', '%s') AND
(`url` REGEXP '%s' OR `name` REGEXP '%s' OR `location` REGEXP '%s' OR (`url` REGEXP '%s' OR `name` REGEXP '%s' OR `location` REGEXP '%s' OR
`about` REGEXP '%s' OR `keywords` REGEXP '%s')".$extra_sql, `about` REGEXP '%s' OR `keywords` REGEXP '%s')".$extra_sql,
dbesc(NETWORK_DFRN), dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora),
dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)),
dbesc(escape_tags($search)), dbesc(escape_tags($search))); dbesc(escape_tags($search)), dbesc(escape_tags($search)));
$results = q("SELECT `contact`.`id` AS `cid`, `gcontact`.`url`, `gcontact`.`name`, `gcontact`.`photo`, `gcontact`.`keywords` $results = q("SELECT `contact`.`id` AS `cid`, `gcontact`.`url`, `gcontact`.`name`, `gcontact`.`photo`, `gcontact`.`network`, `gcontact`.`keywords`, `gcontact`.`addr`
FROM `gcontact` FROM `gcontact`
LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl`
AND `contact`.`uid` = %d AND NOT `contact`.`blocked` AND `contact`.`uid` = %d AND NOT `contact`.`blocked`
@ -67,7 +113,7 @@ function dirfind_content(&$a, $prefix = "") {
GROUP BY `gcontact`.`nurl` GROUP BY `gcontact`.`nurl`
ORDER BY `gcontact`.`updated` DESC LIMIT %d, %d", ORDER BY `gcontact`.`updated` DESC LIMIT %d, %d",
intval(local_user()), dbesc(CONTACT_IS_SHARING), dbesc(CONTACT_IS_FRIEND), intval(local_user()), dbesc(CONTACT_IS_SHARING), dbesc(CONTACT_IS_FRIEND),
dbesc(NETWORK_DFRN), dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora),
dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)),
dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)),
intval($startrec), intval($perpage)); intval($startrec), intval($perpage));
@ -87,9 +133,11 @@ function dirfind_content(&$a, $prefix = "") {
$objresult = new stdClass(); $objresult = new stdClass();
$objresult->cid = $result["cid"]; $objresult->cid = $result["cid"];
$objresult->name = $result["name"]; $objresult->name = $result["name"];
$objresult->addr = $result["addr"];
$objresult->url = $result["url"]; $objresult->url = $result["url"];
$objresult->photo = $result["photo"]; $objresult->photo = $result["photo"];
$objresult->tags = $result["keywords"]; $objresult->tags = $result["keywords"];
$objresult->network = $result["network"];
$j->results[] = $objresult; $j->results[] = $objresult;
} }
@ -113,29 +161,65 @@ function dirfind_content(&$a, $prefix = "") {
if(count($j->results)) { if(count($j->results)) {
$tpl = get_markup_template('match.tpl'); $id = 0;
foreach($j->results as $jj) { foreach($j->results as $jj) {
$alt_text = "";
$contact_details = get_contact_details_by_url($jj->url, local_user());
$itemurl = (($contact_details["addr"] != "") ? $contact_details["addr"] : $jj->url);
// If We already know this contact then don't show the "connect" button // If We already know this contact then don't show the "connect" button
if ($jj->cid > 0) { if ($jj->cid > 0) {
$connlnk = ""; $connlnk = "";
$conntxt = ""; $conntxt = "";
$contact = q("SELECT * FROM `contact` WHERE `id` = %d",
intval($jj->cid));
if ($contact) {
$photo_menu = contact_photo_menu($contact[0]);
$details = _contact_detail_for_template($contact[0]);
$alt_text = $details['alt_text'];
} else
$photo_menu = array();
} else { } else {
$connlnk = $a->get_baseurl().'/follow/?url='.(($jj->connect) ? $jj->connect : $jj->url); $connlnk = $a->get_baseurl().'/follow/?url='.(($jj->connect) ? $jj->connect : $jj->url);
$conntxt = t('Connect'); $conntxt = t('Connect');
$photo_menu = array(array(t("View Profile"), zrl($jj->url)));
$photo_menu[] = array(t("Connect/Follow"), $connlnk);
} }
$jj->photo = str_replace("http:///photo/", get_server()."/photo/", $jj->photo); $jj->photo = str_replace("http:///photo/", get_server()."/photo/", $jj->photo);
$o .= replace_macros($tpl,array( $entry = array(
'$url' => zrl($jj->url), 'alt_text' => $alt_text,
'$name' => $jj->name, 'url' => zrl($jj->url),
'$photo' => proxy_url($jj->photo), 'itemurl' => $itemurl,
'$tags' => $jj->tags, 'name' => htmlentities($jj->name),
'$conntxt' => $conntxt, 'thumb' => proxy_url($jj->photo, false, PROXY_SIZE_THUMB),
'$connlnk' => $connlnk, 'img_hover' => $jj->tags,
)); 'conntxt' => $conntxt,
'connlnk' => $connlnk,
'photo_menu' => $photo_menu,
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
'account_type' => (($contact_details['community']) ? t('Forum') : ''),
'network' => network_to_name($jj->network, $jj->url),
'id' => ++$id,
);
$entries[] = $entry;
} }
$tpl = get_markup_template('viewcontact_template.tpl');
$o .= replace_macros($tpl,array(
'title' => sprintf( t('People Search - %s'), $search),
'$contacts' => $entries,
'$paginate' => paginate($a),
));
} }
else { else {
info( t('No matches') . EOL); info( t('No matches') . EOL);
@ -143,7 +227,5 @@ function dirfind_content(&$a, $prefix = "") {
} }
$o .= '<div class="clear"></div>';
$o .= paginate($a);
return $o; return $o;
} }

View file

@ -89,51 +89,16 @@ function display_init(&$a) {
} }
function display_fetchauthor($a, $item) { function display_fetchauthor($a, $item) {
require_once("mod/proxy.php");
require_once("include/bbcode.php");
$profiledata = array(); $profiledata = array();
$profiledata["uid"] = -1; $profiledata["uid"] = -1;
$profiledata["nickname"] = $item["author-name"]; $profiledata["nickname"] = $item["author-name"];
$profiledata["name"] = $item["author-name"]; $profiledata["name"] = $item["author-name"];
$profiledata["picdate"] = ""; $profiledata["picdate"] = "";
$profiledata["photo"] = proxy_url($item["author-avatar"]); $profiledata["photo"] = $item["author-avatar"];
$profiledata["url"] = $item["author-link"]; $profiledata["url"] = $item["author-link"];
$profiledata["network"] = $item["network"]; $profiledata["network"] = $item["network"];
// Fetching further contact data from the contact table
$r = q("SELECT `photo`, `nick`, `location`, `about` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` = '%s'",
dbesc(normalise_link($profiledata["url"])), intval($item["uid"]), dbesc($item["network"]));
if (!count($r))
$r = q("SELECT `photo`, `nick`, `location`, `about` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
dbesc(normalise_link($profiledata["url"])), intval($item["uid"]));
if (!count($r))
$r = q("SELECT `photo`, `nick`, `location`, `about` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
dbesc(normalise_link($profiledata["url"])));
if (count($r)) {
$profiledata["photo"] = proxy_url($r[0]["photo"]);
$profiledata["address"] = proxy_parse_html(bbcode($r[0]["location"]));
$profiledata["about"] = proxy_parse_html(bbcode($r[0]["about"]));
if ($r[0]["nick"] != "")
$profiledata["nickname"] = $r[0]["nick"];
}
// Fetching profile data from unique contacts
$r = q("SELECT `avatar`, `nick`, `location`, `about` FROM `unique_contacts` WHERE `url` = '%s'", dbesc(normalise_link($profiledata["url"])));
if (count($r)) {
if ($profiledata["photo"] == "")
$profiledata["photo"] = proxy_url($r[0]["avatar"]);
if ($profiledata["address"] == "")
$profiledata["address"] = proxy_parse_html(bbcode($r[0]["location"]));
if ($profiledata["about"] == "")
$profiledata["about"] = proxy_parse_html(bbcode($r[0]["about"]));
if (($profiledata["nickname"] == "") AND ($r[0]["nick"] != ""))
$profiledata["nickname"] = $r[0]["nick"];
}
// Check for a repeated message // Check for a repeated message
$skip = false; $skip = false;
$body = trim($item["body"]); $body = trim($item["body"]);
@ -187,28 +152,49 @@ function display_fetchauthor($a, $item) {
$profiledata["address"] = ""; $profiledata["address"] = "";
$profiledata["about"] = ""; $profiledata["about"] = "";
}
// Fetching further contact data from the contact table
$r = q("SELECT `uid`, `network`, `photo`, `nick`, `location`, `about` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d AND `network` = '%s'",
dbesc(normalise_link($profiledata["url"])), intval($item["uid"]), dbesc($item["network"]));
if (!count($r))
$r = q("SELECT `uid`, `network`, `photo`, `nick`, `location`, `about` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d",
dbesc(normalise_link($profiledata["url"])), intval($item["uid"]));
if (!count($r))
$r = q("SELECT `uid`, `network`, `photo`, `nick`, `location`, `about` FROM `contact` WHERE `nurl` = '%s' AND `uid` = 0",
dbesc(normalise_link($profiledata["url"])));
// Fetching profile data from unique contacts
if ($profiledata["url"] != "") {
$r = q("SELECT `avatar`, `nick`, `location`, `about` FROM `unique_contacts` WHERE `url` = '%s'", dbesc(normalise_link($profiledata["url"])));
if (count($r)) { if (count($r)) {
$profiledata["photo"] = proxy_url($r[0]["avatar"]); if ((($r[0]["uid"] != local_user()) OR !local_user()) AND ($profiledata["network"] == NETWORK_DIASPORA)) {
$profiledata["address"] = proxy_parse_html(bbcode($r[0]["location"])); $r[0]["location"] = "";
$profiledata["about"] = proxy_parse_html(bbcode($r[0]["about"])); $r[0]["about"] = "";
}
$profiledata["photo"] = $r[0]["photo"];
$profiledata["address"] = $r[0]["location"];
$profiledata["about"] = $r[0]["about"];
if ($r[0]["nick"] != "") if ($r[0]["nick"] != "")
$profiledata["nickname"] = $r[0]["nick"]; $profiledata["nickname"] = $r[0]["nick"];
} }
}
// Fetching profile data from unique contacts
$r = q("SELECT `avatar`, `nick`, `location`, `about` FROM `unique_contacts` WHERE `url` = '%s'", dbesc(normalise_link($profiledata["url"])));
if (count($r)) {
if ($profiledata["photo"] == "")
$profiledata["photo"] = $r[0]["avatar"];
if (($profiledata["address"] == "") AND ($profiledata["network"] != NETWORK_DIASPORA))
$profiledata["address"] = $r[0]["location"];
if (($profiledata["about"] == "") AND ($profiledata["network"] != NETWORK_DIASPORA))
$profiledata["about"] = $r[0]["about"];
if (($profiledata["nickname"] == "") AND ($r[0]["nick"] != ""))
$profiledata["nickname"] = $r[0]["nick"];
} }
if (local_user()) { if (local_user()) {
if (in_array($profiledata["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) if (in_array($profiledata["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
$profiledata["remoteconnect"] = $a->get_baseurl()."/follow?url=".urlencode($profiledata["url"]); $profiledata["remoteconnect"] = $a->get_baseurl()."/follow?url=".urlencode($profiledata["url"]);
//if ($profiledata["network"] == NETWORK_DFRN) {
// $connect = str_replace("/profile/", "/dfrn_request/", $profiledata["url"])."&addr=".bin2hex($a->get_baseurl()."/profile/".$a->user["nickname"]);
// $profiledata["remoteconnect"] = $connect;
//} elseif ($profiledata["network"] == NETWORK_DIASPORA)
// $profiledata["remoteconnect"] = $a->get_baseurl()."/contacts?add=".GetProfileUsername($profiledata["url"], "", true);
} elseif ($profiledata["network"] == NETWORK_DFRN) { } elseif ($profiledata["network"] == NETWORK_DFRN) {
$connect = str_replace("/profile/", "/dfrn_request/", $profiledata["url"]); $connect = str_replace("/profile/", "/dfrn_request/", $profiledata["url"]);
$profiledata["remoteconnect"] = $connect; $profiledata["remoteconnect"] = $connect;
@ -224,7 +210,6 @@ function display_content(&$a, $update = 0) {
return; return;
} }
require_once("include/bbcode.php");
require_once('include/security.php'); require_once('include/security.php');
require_once('include/conversation.php'); require_once('include/conversation.php');
require_once('include/acl_selectors.php'); require_once('include/acl_selectors.php');

View file

@ -102,8 +102,8 @@ function editpost_content(&$a) {
//$tpl = replace_macros($tpl,array('$jotplugins' => $jotplugins)); //$tpl = replace_macros($tpl,array('$jotplugins' => $jotplugins));
$o .= replace_macros($tpl,array( $o .= replace_macros($tpl,array(
'$is_edit' => true,
'$return_path' => $_SESSION['return_url'], '$return_path' => $_SESSION['return_url'],
'$action' => 'item', '$action' => 'item',
'$share' => t('Save'), '$share' => t('Save'),

View file

@ -154,6 +154,7 @@ function events_post(&$a) {
if(! $cid) if(! $cid)
proc_run('php',"include/notifier.php","event","$item_id"); proc_run('php',"include/notifier.php","event","$item_id");
goaway($_SESSION['return_url']);
} }
@ -165,6 +166,9 @@ function events_content(&$a) {
return; return;
} }
if($a->argc == 1)
$_SESSION['return_url'] = $a->get_baseurl() . '/' . $a->cmd;
if(($a->argc > 2) && ($a->argv[1] === 'ignore') && intval($a->argv[2])) { if(($a->argc > 2) && ($a->argv[1] === 'ignore') && intval($a->argv[2])) {
$r = q("update event set ignore = 1 where id = %d and uid = %d", $r = q("update event set ignore = 1 where id = %d and uid = %d",
intval($a->argv[2]), intval($a->argv[2]),
@ -179,14 +183,69 @@ function events_content(&$a) {
); );
} }
if ($a->theme_events_in_profile)
nav_set_selected('home');
else
nav_set_selected('events');
$editselect = 'none'; $editselect = 'none';
if( feature_enabled(local_user(), 'richtext') ) if( feature_enabled(local_user(), 'richtext') )
$editselect = 'textareas'; $editselect = 'textareas';
// First day of the week (0 = Sunday)
$firstDay = get_pconfig(local_user(),'system','first_day_of_week');
if ($firstDay === false) $firstDay=0;
$i18n = array(
"firstDay" => $firstDay,
"Sun" => t("Sun"),
"Mon" => t("Mon"),
"Tue" => t("Tue"),
"Wed" => t("Wed"),
"Thu" => t("Thu"),
"Fri" => t("Fri"),
"Sat" => t("Sat"),
"Sunday" => t("Sunday"),
"Monday" => t("Monday"),
"Tuesday" => t("Tuesday"),
"Wednesday" => t("Wednesday"),
"Thursday" => t("Thursday"),
"Friday" => t("Friday"),
"Saturday" => t("Saturday"),
"Jan" => t("Jan"),
"Feb" => t("Feb"),
"Mar" => t("Mar"),
"Apr" => t("Apr"),
"May" => t("May"),
"Jun" => t("Jun"),
"Jul" => t("Jul"),
"Aug" => t("Aug"),
"Sep" => t("Sept"),
"Oct" => t("Oct"),
"Nov" => t("Nov"),
"Dec" => t("Dec"),
"January" => t("January"),
"February" => t("February"),
"March" => t("March"),
"April" => t("April"),
"May" => t("May"),
"June" => t("June"),
"July" => t("July"),
"August" => t("August"),
"September" => t("September"),
"October" => t("October"),
"November" => t("November"),
"December" => t("December"),
"today" => t("today"),
"month" => t("month"),
"week" => t("week"),
"day" => t("day"),
);
$htpl = get_markup_template('event_head.tpl'); $htpl = get_markup_template('event_head.tpl');
$a->page['htmlhead'] .= replace_macros($htpl,array( $a->page['htmlhead'] .= replace_macros($htpl,array(
'$baseurl' => $a->get_baseurl(), '$baseurl' => $a->get_baseurl(),
'$i18n' => $i18n,
'$editselect' => $editselect '$editselect' => $editselect
)); ));
@ -198,6 +257,7 @@ function events_content(&$a) {
$o =""; $o ="";
// tabs // tabs
if ($a->theme_events_in_profile)
$tabs = profile_tabs($a, True); $tabs = profile_tabs($a, True);
@ -449,7 +509,7 @@ function events_content(&$a) {
else else
$sh_checked = (($orig_event['allow_cid'] === '<' . local_user() . '>' && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" ' ); $sh_checked = (($orig_event['allow_cid'] === '<' . local_user() . '>' && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" ' );
if($cid) if($cid OR ($mode !== 'new'))
$sh_checked .= ' disabled="disabled" '; $sh_checked .= ' disabled="disabled" ';
@ -480,6 +540,9 @@ function events_content(&$a) {
require_once('include/acl_selectors.php'); require_once('include/acl_selectors.php');
if ($mode === 'new')
$acl = (($cid) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $a->user)));
$tpl = get_markup_template('event_form.tpl'); $tpl = get_markup_template('event_form.tpl');
$o .= replace_macros($tpl,array( $o .= replace_macros($tpl,array(
@ -507,7 +570,7 @@ function events_content(&$a) {
'$sh_text' => t('Share this event'), '$sh_text' => t('Share this event'),
'$sh_checked' => $sh_checked, '$sh_checked' => $sh_checked,
'$preview' => t('Preview'), '$preview' => t('Preview'),
'$acl' => (($cid) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $a->user))), '$acl' => $acl,
'$submit' => t('Submit') '$submit' => t('Submit')
)); ));

View file

@ -35,12 +35,14 @@ function fbrowser_content($a){
$sql_extra2 = " ORDER BY created DESC LIMIT 0, 10"; $sql_extra2 = " ORDER BY created DESC LIMIT 0, 10";
if ($a->argc==2){ if ($a->argc==2){
$albums = q("SELECT distinct(`album`) AS `album` FROM `photo` WHERE `uid` = %d ", $albums = q("SELECT distinct(`album`) AS `album` FROM `photo` WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' ",
intval(local_user()) intval(local_user()),
dbesc('Contact Photos'),
dbesc( t('Contact Photos'))
); );
// anon functions only from 5.3.0... meglio tardi che mai..
$folder1 = function($el) use ($mode) {return array(bin2hex($el['album']),$el['album']);}; function _map_folder1($el){return array(bin2hex($el['album']),$el['album']);};
$albums = array_map( $folder1 , $albums); $albums = array_map( "_map_folder1" , $albums);
} }
@ -53,12 +55,14 @@ function fbrowser_content($a){
} }
$r = q("SELECT `resource-id`, `id`, `filename`, type, min(`scale`) AS `hiq`,max(`scale`) AS `loq`, `desc` $r = q("SELECT `resource-id`, `id`, `filename`, type, min(`scale`) AS `hiq`,max(`scale`) AS `loq`, `desc`
FROM `photo` WHERE `uid` = %d $sql_extra FROM `photo` WHERE `uid` = %d $sql_extra AND `album` != '%s' AND `album` != '%s'
GROUP BY `resource-id` $sql_extra2", GROUP BY `resource-id` $sql_extra2",
intval(local_user()) intval(local_user()),
dbesc('Contact Photos'),
dbesc( t('Contact Photos'))
); );
function files1($rr){ function _map_files1($rr){
global $a; global $a;
$types = Photo::supportedTypes(); $types = Photo::supportedTypes();
$ext = $types[$rr['type']]; $ext = $types[$rr['type']];
@ -71,12 +75,12 @@ function fbrowser_content($a){
} }
return array( return array(
$a->get_baseurl() . '/photo/' . $rr['resource-id'] . '.' .$ext, $a->get_baseurl() . '/photos/' . $a->user['nickname'] . '/image/' . $rr['resource-id'],
$filename_e, $filename_e,
$a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['loq'] . '.'. $ext $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['loq'] . '.'. $ext
); );
} }
$files = array_map("files1", $r); $files = array_map("_map_files1", $r);
$tpl = get_markup_template($template_file); $tpl = get_markup_template($template_file);
@ -94,11 +98,11 @@ function fbrowser_content($a){
break; break;
case "file": case "file":
if ($a->argc==2){ if ($a->argc==2){
$files = q("SELECT id, filename, filetype FROM `attach` WHERE `uid` = %d ", $files = q("SELECT `id`, `filename`, `filetype` FROM `attach` WHERE `uid` = %d ",
intval(local_user()) intval(local_user())
); );
function files2($rr){ global $a; function _map_files2($rr){ global $a;
list($m1,$m2) = explode("/",$rr['filetype']); list($m1,$m2) = explode("/",$rr['filetype']);
$filetype = ( (file_exists("images/icons/$m1.png"))?$m1:"zip"); $filetype = ( (file_exists("images/icons/$m1.png"))?$m1:"zip");
@ -111,8 +115,7 @@ function fbrowser_content($a){
return array( $a->get_baseurl() . '/attach/' . $rr['id'], $filename_e, $a->get_baseurl() . '/images/icons/16/' . $filetype . '.png'); return array( $a->get_baseurl() . '/attach/' . $rr['id'], $filename_e, $a->get_baseurl() . '/images/icons/16/' . $filetype . '.png');
} }
$files = array_map("files2", $files); $files = array_map("_map_files2", $files);
//echo "<pre>"; var_dump($files); killme();
$tpl = get_markup_template($template_file); $tpl = get_markup_template($template_file);

53
mod/follow.php Executable file → Normal file
View file

@ -15,6 +15,8 @@ function follow_content(&$a) {
$uid = local_user(); $uid = local_user();
$url = notags(trim($_REQUEST['url'])); $url = notags(trim($_REQUEST['url']));
$submit = t('Submit Request');
// There is a current issue. It seems as if you can't start following a Friendica that is following you // There is a current issue. It seems as if you can't start following a Friendica that is following you
// With Diaspora this works - but Friendica is special, it seems ... // With Diaspora this works - but Friendica is special, it seems ...
$r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND ((`rel` != %d) OR (`network` = '%s')) AND $r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND ((`rel` != %d) OR (`network` = '%s')) AND
@ -25,12 +27,34 @@ function follow_content(&$a) {
if ($r) { if ($r) {
notice(t('You already added this contact.').EOL); notice(t('You already added this contact.').EOL);
goaway($_SESSION['return_url']); $submit = "";
//goaway($_SESSION['return_url']);
// NOTREACHED // NOTREACHED
} }
$ret = probe_url($url); $ret = probe_url($url);
if (($ret["network"] == NETWORK_DIASPORA) AND !get_config('system','diaspora_enabled')) {
notice( t("Diaspora support isn't enabled. Contact can't be added.") . EOL);
$submit = "";
//goaway($_SESSION['return_url']);
// NOTREACHED
}
if (($ret["network"] == NETWORK_OSTATUS) AND get_config('system','ostatus_disabled')) {
notice( t("OStatus support is disabled. Contact can't be added.") . EOL);
$submit = "";
//goaway($_SESSION['return_url']);
// NOTREACHED
}
if ($ret["network"] == NETWORK_PHANTOM) {
notice( t("The network type couldn't be detected. Contact can't be added.") . EOL);
$submit = "";
//goaway($_SESSION['return_url']);
// NOTREACHED
}
if ($ret["network"] == NETWORK_MAIL) if ($ret["network"] == NETWORK_MAIL)
$ret["url"] = $ret["addr"]; $ret["url"] = $ret["addr"];
@ -55,16 +79,27 @@ function follow_content(&$a) {
// Makes the connection request for friendica contacts easier // Makes the connection request for friendica contacts easier
$_SESSION["fastlane"] = $ret["url"]; $_SESSION["fastlane"] = $ret["url"];
$r = q("SELECT `location`, `about`, `keywords` FROM `gcontact` WHERE `nurl` = '%s'",
normalise_link($ret["url"]));
if (!$r)
$r = array(array("location" => "", "about" => "", "keywords" => ""));
if($ret['network'] === NETWORK_DIASPORA) {
$r[0]["location"] = "";
$r[0]["about"] = "";
}
$header = $ret["name"]; $header = $ret["name"];
if ($ret["addr"] != "") if ($ret["addr"] != "")
$header .= " <".$ret["addr"].">"; $header .= " <".$ret["addr"].">";
$header .= " (".network_to_name($ret['network']).")"; $header .= " (".network_to_name($ret['network'], $ret['url']).")";
$o = replace_macros($tpl,array( $o = replace_macros($tpl,array(
'$header' => htmlentities($header), '$header' => htmlentities($header),
'$photo' => $ret["photo"], '$photo' => proxy_url($ret["photo"], false, PROXY_SIZE_SMALL),
'$desc' => "", '$desc' => "",
'$pls_answer' => t('Please answer the following:'), '$pls_answer' => t('Please answer the following:'),
'$does_know_you' => array('knowyou', sprintf(t('Does %s know you?'),$ret["name"]), false, '', array(t('No'),t('Yes'))), '$does_know_you' => array('knowyou', sprintf(t('Does %s know you?'),$ret["name"]), false, '', array(t('No'),t('Yes'))),
@ -77,13 +112,21 @@ function follow_content(&$a) {
'$your_address' => t('Your Identity Address:'), '$your_address' => t('Your Identity Address:'),
'$invite_desc' => "", '$invite_desc' => "",
'$emailnet' => "", '$emailnet' => "",
'$submit' => t('Submit Request'), '$submit' => $submit,
'$cancel' => t('Cancel'), '$cancel' => t('Cancel'),
'$nickname' => "", '$nickname' => "",
'$name' => $ret["name"], '$name' => $ret["name"],
'$url' => $ret["url"], '$url' => $ret["url"],
'$zrl' => zrl($ret["url"]),
'$url_label' => t("Profile URL"),
'$myaddr' => $myaddr, '$myaddr' => $myaddr,
'$request' => $request '$request' => $request,
'$location' => bbcode($r[0]["location"]),
'$location_label' => t("Location:"),
'$about' => bbcode($r[0]["about"], false, false),
'$about_label' => t("About:"),
'$keywords' => $r[0]["keywords"],
'$keywords_label' => t("Tags:")
)); ));
return $o; return $o;
} }

View file

@ -7,7 +7,7 @@ function validate_members(&$item) {
function group_init(&$a) { function group_init(&$a) {
if(local_user()) { if(local_user()) {
require_once('include/group.php'); require_once('include/group.php');
$a->page['aside'] = group_side('contacts','group',false,(($a->argc > 1) ? intval($a->argv[1]) : 0)); $a->page['aside'] = group_side('contacts','group','extended',(($a->argc > 1) ? intval($a->argv[1]) : 0));
} }
} }
@ -190,6 +190,7 @@ function group_content(&$a) {
'label_members' => t('Members'), 'label_members' => t('Members'),
'members' => array(), 'members' => array(),
'label_contacts' => t('All Contacts'), 'label_contacts' => t('All Contacts'),
'group_is_empty' => t('Group is empty'),
'contacts' => array(), 'contacts' => array(),
); );
@ -204,7 +205,7 @@ function group_content(&$a) {
group_rmv_member(local_user(),$group['name'],$member['id']); group_rmv_member(local_user(),$group['name'],$member['id']);
} }
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 and `pending` = 0 and `self` = 0 ORDER BY `name` ASC", $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `self` ORDER BY `name` ASC",
intval(local_user()) intval(local_user())
); );
@ -230,4 +231,3 @@ function group_content(&$a) {
return replace_macros($tpl, $context); return replace_macros($tpl, $context);
} }

View file

@ -1,4 +1,5 @@
<?php <?php
require_once "include/Photo.php";
$install_wizard_pass=1; $install_wizard_pass=1;
@ -10,6 +11,14 @@ function install_init(&$a){
echo "ok"; echo "ok";
killme(); killme();
} }
// We overwrite current theme css, because during install we could not have a working mod_rewrite
// so we could not have a css at all. Here we set a static css file for the install procedure pages
$a->config['system']['theme'] = "../install";
$a->theme['stylesheet'] = $a->get_baseurl()."/view/install/style.css";
global $install_wizard_pass; global $install_wizard_pass;
if (x($_POST,'pass')) if (x($_POST,'pass'))
$install_wizard_pass = intval($_POST['pass']); $install_wizard_pass = intval($_POST['pass']);
@ -177,6 +186,8 @@ function install_content(&$a) {
check_funcs($checks); check_funcs($checks);
check_imagik($checks);
check_htconfig($checks); check_htconfig($checks);
check_smarty3($checks); check_smarty3($checks);
@ -321,7 +332,7 @@ function check_php(&$phpath, &$checks) {
$help = ""; $help = "";
if(!$passed) { if(!$passed) {
$help .= t('Could not find a command line version of PHP in the web server PATH.'). EOL; $help .= t('Could not find a command line version of PHP in the web server PATH.'). EOL;
$help .= t("If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron. See <a href='http://friendica.com/node/27'>'Activating scheduled tasks'</a>") . EOL ; $help .= t("If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron. See <a href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-up-the-poller'>'Setup the poller'</a>") . EOL ;
$help .= EOL . EOL ; $help .= EOL . EOL ;
$tpl = get_markup_template('field_input.tpl'); $tpl = get_markup_template('field_input.tpl');
$help .= replace_macros($tpl, array( $help .= replace_macros($tpl, array(
@ -428,10 +439,21 @@ function check_funcs(&$checks) {
$ck_funcs[5]['help']= t('Error: mcrypt PHP module required but not installed.'); $ck_funcs[5]['help']= t('Error: mcrypt PHP module required but not installed.');
} }
$checks = array_merge($checks, $ck_funcs); $checks = array_merge($checks, $ck_funcs);
// check for 'mcrypt_create_iv()', needed for RINO2
if ($ck_funcs[5]['status']) {
if (function_exists('mcrypt_create_iv')) {
$__status = true;
$__help = "If you are using php_cli, please make sure that mcrypt module is enabled in its config file";
} else {
$__status = false;
$__help = t('Function mcrypt_create_iv() is not defined. This is needed to enable RINO2 encryption layer.');
}
check_add($checks, t('mcrypt_create_iv() function'), $__status, false, $__help);
}
/*if((x($_SESSION,'sysmsg')) && is_array($_SESSION['sysmsg']) && count($_SESSION['sysmsg'])) /*if((x($_SESSION,'sysmsg')) && is_array($_SESSION['sysmsg']) && count($_SESSION['sysmsg']))
notice( t('Please see the file "INSTALL.txt".') . EOL);*/ notice( t('Please see the file "INSTALL.txt".') . EOL);*/
} }
@ -490,6 +512,24 @@ function check_htaccess(&$checks) {
} }
} }
function check_imagik(&$checks) {
$imagick = false;
$gif = false;
if (class_exists('Imagick')) {
$imagick = true;
$supported = Photo::supportedTypes();
if (array_key_exists('image/gif', $supported)) {
$gif = true;
}
}
check_add($checks, t('ImageMagick PHP extension is installed'), $imagick, false, "");
if ($imagick) {
check_add($checks, t('ImageMagick supports GIF'), $gif, false, "");
}
}
function manual_config(&$a) { function manual_config(&$a) {
$data = htmlentities($a->data['txt'],ENT_COMPAT,'UTF-8'); $data = htmlentities($a->data['txt'],ENT_COMPAT,'UTF-8');

View file

@ -18,7 +18,6 @@
require_once('include/crypto.php'); require_once('include/crypto.php');
require_once('include/enotify.php'); require_once('include/enotify.php');
require_once('include/email.php'); require_once('include/email.php');
require_once('library/langdet/Text/LanguageDetect.php');
require_once('include/tags.php'); require_once('include/tags.php');
require_once('include/files.php'); require_once('include/files.php');
require_once('include/threads.php'); require_once('include/threads.php');
@ -268,32 +267,8 @@ function item_post(&$a) {
$guid = get_guid(32); $guid = get_guid(32);
$naked_body = preg_replace('/\[(.+?)\]/','',$body); item_add_language_opt($_REQUEST);
$postopts = $_REQUEST['postopts'] ? $_REQUEST['postopts'] : "";
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
$l = new Text_LanguageDetect;
//$lng = $l->detectConfidence($naked_body);
//$postopts = (($lng['language']) ? 'lang=' . $lng['language'] . ';' . $lng['confidence'] : '');
$lng = $l->detect($naked_body, 3);
if (sizeof($lng) > 0) {
$postopts = "";
foreach ($lng as $language => $score) {
if ($postopts == "")
$postopts = "lang=";
else
$postopts .= ":";
$postopts .= $language.";".$score;
}
}
logger('mod_item: detect language' . print_r($lng,true) . $naked_body, LOGGER_DATA);
}
else
$postopts = '';
$private = ((strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) ? 1 : 0); $private = ((strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) ? 1 : 0);
@ -387,8 +362,7 @@ function item_post(&$a) {
if((local_user()) && (local_user() == $profile_uid)) { if((local_user()) && (local_user() == $profile_uid)) {
$self = true; $self = true;
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1",
intval($_SESSION['uid']) intval($_SESSION['uid']));
);
} }
elseif(remote_user()) { elseif(remote_user()) {
if(is_array($_SESSION['remote'])) { if(is_array($_SESSION['remote'])) {

View file

@ -26,6 +26,18 @@ function like_content(&$a) {
case 'undislike': case 'undislike':
$activity = ACTIVITY_DISLIKE; $activity = ACTIVITY_DISLIKE;
break; break;
case 'attendyes':
case 'unattendyes':
$activity = ACTIVITY_ATTEND;
break;
case 'attendno':
case 'unattendno':
$activity = ACTIVITY_ATTENDNO;
break;
case 'attendmaybe':
case 'unattendmaybe':
$activity = ACTIVITY_ATTENDMAYBE;
break;
default: default:
return; return;
break; break;
@ -108,11 +120,18 @@ function like_content(&$a) {
// See if we've been passed a return path to redirect to // See if we've been passed a return path to redirect to
$return_path = ((x($_REQUEST,'return')) ? $_REQUEST['return'] : ''); $return_path = ((x($_REQUEST,'return')) ? $_REQUEST['return'] : '');
$verbs = " '".dbesc($activity)."' ";
$r = q("SELECT `id`, `guid` FROM `item` WHERE `verb` = '%s' AND `deleted` = 0 // event participation are essentially radio toggles. If you make a subsequent choice,
// we need to eradicate your first choice.
if($activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE) {
$verbs = " '" . dbesc(ACTIVITY_ATTEND) . "','" . dbesc(ACTIVITY_ATTENDNO) . "','" . dbesc(ACTIVITY_ATTENDMAYBE) . "' ";
}
$r = q("SELECT `id`, `guid` FROM `item` WHERE `verb` IN ( $verbs ) AND `deleted` = 0
AND `contact-id` = %d AND `uid` = %d AND `contact-id` = %d AND `uid` = %d
AND (`parent` = '%s' OR `parent-uri` = '%s' OR `thr-parent` = '%s') LIMIT 1", AND (`parent` = '%s' OR `parent-uri` = '%s' OR `thr-parent` = '%s') LIMIT 1",
dbesc($activity), intval($contact['id']), intval($owner_uid), intval($contact['id']), intval($owner_uid),
dbesc($item_id), dbesc($item_id), dbesc($item['uri']) dbesc($item_id), dbesc($item_id), dbesc($item['uri'])
); );
@ -147,6 +166,8 @@ function like_content(&$a) {
$uri = item_new_uri($a->get_hostname(),$owner_uid); $uri = item_new_uri($a->get_hostname(),$owner_uid);
$post_type = (($item['resource-id']) ? t('photo') : t('status')); $post_type = (($item['resource-id']) ? t('photo') : t('status'));
if($item['obj_type'] === ACTIVITY_OBJ_EVENT)
$post_type = t('event');
$objtype = (($item['resource-id']) ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE ); $objtype = (($item['resource-id']) ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE );
$link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ; $link = xmlify('<link rel="alternate" type="text/html" href="' . $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
$body = $item['body']; $body = $item['body'];
@ -166,6 +187,12 @@ EOT;
$bodyverb = t('%1$s likes %2$s\'s %3$s'); $bodyverb = t('%1$s likes %2$s\'s %3$s');
if($verb === 'dislike') if($verb === 'dislike')
$bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s'); $bodyverb = t('%1$s doesn\'t like %2$s\'s %3$s');
if($verb === 'attendyes')
$bodyverb = t('%1$s is attending %2$s\'s %3$s');
if($verb === 'attendno')
$bodyverb = t('%1$s is not attending %2$s\'s %3$s');
if($verb === 'attendmaybe')
$bodyverb = t('%1$s may attend %2$s\'s %3$s');
if(! isset($bodyverb)) if(! isset($bodyverb))
return; return;

Some files were not shown because too many files have changed in this diff Show more