Merge develop into 20170407_-_group_edit

Conflicts:
	mod/group.php
This commit is contained in:
rabuzarus 2017-04-21 16:09:48 +02:00
commit f99bb958f6
163 changed files with 14447 additions and 11967 deletions

View File

@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_CODENAME', 'Asparagus');
define ( 'FRIENDICA_VERSION', '3.5.2-dev' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1216 );
define ( 'DB_UPDATE_VERSION', 1219 );
/**
* @brief Constant with a HTML line break.
@ -382,6 +382,7 @@ define ( 'ACTIVITY_UPDATE', NAMESPACE_ACTIVITY_SCHEMA . 'update' );
define ( 'ACTIVITY_TAG', NAMESPACE_ACTIVITY_SCHEMA . 'tag' );
define ( 'ACTIVITY_FAVORITE', NAMESPACE_ACTIVITY_SCHEMA . 'favorite' );
define ( 'ACTIVITY_SHARE', NAMESPACE_ACTIVITY_SCHEMA . 'share' );
define ( 'ACTIVITY_DELETE', NAMESPACE_ACTIVITY_SCHEMA . 'delete' );
define ( 'ACTIVITY_POKE', NAMESPACE_ZOT . '/activity/poke' );
define ( 'ACTIVITY_MOOD', NAMESPACE_ZOT . '/activity/mood' );
@ -1366,11 +1367,15 @@ class App {
$cmdline = implode($args, " ");
if (get_config('system', 'proc_windows')) {
proc_close(proc_open('cmd /c start /b ' . $cmdline, array(), $foo, dirname(__FILE__)));
$resource = proc_open('cmd /c start /b ' . $cmdline, array(), $foo, dirname(__FILE__));
} else {
proc_close(proc_open($cmdline . " &", array(), $foo, dirname(__FILE__)));
$resource = proc_open($cmdline . " &", array(), $foo, dirname(__FILE__));
}
if (!is_resource($resource)) {
logger('We got no resource for command '.$cmdline, LOGGER_DEBUG);
return;
}
proc_close($resource);
}
/**
@ -2472,7 +2477,7 @@ function get_temppath() {
// Check if it is usable
if (($temppath != "") AND App::directory_usable($temppath)) {
// To avoid any interferences with other systems we create our own directory
$new_temppath .= "/".$a->get_hostname();
$new_temppath = $temppath."/".$a->get_hostname();
if (!is_dir($new_temppath)) {
/// @TODO There is a mkdir()+chmod() upwards, maybe generalize this (+ configurable) into a function/method?
mkdir($new_temppath);

View File

@ -15,6 +15,7 @@
"require": {
"ezyang/htmlpurifier": "~4.7.0",
"mobiledetect/mobiledetectlib": "2.8.*",
"league/html-to-markdown": "~4.4.1",
"pear-pear.php.net/Text_Highlighter": "*"
},
"repositories": [

66
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "4d3a9e742e7ad746fb7206f3b5aff5af",
"content-hash": "802372ddf124ef949e80dd8dc1d38797",
"packages": [
{
"name": "ezyang/htmlpurifier",
@ -50,6 +50,70 @@
],
"time": "2015-08-05T01:03:42+00:00"
},
{
"name": "league/html-to-markdown",
"version": "4.4.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/html-to-markdown.git",
"reference": "82ea375b5b2b1da1da222644c0565c695bf88186"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/82ea375b5b2b1da1da222644c0565c695bf88186",
"reference": "82ea375b5b2b1da1da222644c0565c695bf88186",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-xml": "*",
"php": ">=5.3.3"
},
"require-dev": {
"mikehaertl/php-shellcommand": "~1.1.0",
"phpunit/phpunit": "4.*",
"scrutinizer/ocular": "~1.1"
},
"bin": [
"bin/html-to-markdown"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.5-dev"
}
},
"autoload": {
"psr-4": {
"League\\HTMLToMarkdown\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "http://www.colinodell.com",
"role": "Lead Developer"
},
{
"name": "Nick Cernis",
"email": "nick@cern.is",
"homepage": "http://modernnerd.net",
"role": "Original Author"
}
],
"description": "An HTML-to-markdown conversion helper for PHP",
"homepage": "https://github.com/thephpleague/html-to-markdown",
"keywords": [
"html",
"markdown"
],
"time": "2017-03-16T00:45:59+00:00"
},
{
"name": "mobiledetect/mobiledetectlib",
"version": "2.8.25",

View File

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 3.5.2-dev (Asparagus)
-- DB_UPDATE_VERSION 1215
-- DB_UPDATE_VERSION 1219
-- ------------------------------------------
@ -17,7 +17,7 @@ CREATE TABLE IF NOT EXISTS `addon` (
`plugin_admin` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`),
UNIQUE INDEX `name` (`name`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE attach
@ -37,7 +37,7 @@ CREATE TABLE IF NOT EXISTS `attach` (
`deny_cid` mediumtext,
`deny_gid` mediumtext,
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE auth_codes
@ -49,7 +49,7 @@ CREATE TABLE IF NOT EXISTS `auth_codes` (
`expires` int(11) NOT NULL DEFAULT 0,
`scope` varchar(250) NOT NULL DEFAULT '',
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE cache
@ -61,7 +61,7 @@ CREATE TABLE IF NOT EXISTS `cache` (
`updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`k`),
INDEX `expire_mode_updated` (`expire_mode`,`updated`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE challenge
@ -74,7 +74,7 @@ CREATE TABLE IF NOT EXISTS `challenge` (
`type` varchar(255) NOT NULL DEFAULT '',
`last_update` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE clients
@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS `clients` (
`icon` text,
`uid` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY(`client_id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE config
@ -99,7 +99,7 @@ CREATE TABLE IF NOT EXISTS `config` (
`v` mediumtext,
PRIMARY KEY(`id`),
UNIQUE INDEX `cat_k` (`cat`,`k`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE contact
@ -159,7 +159,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`writable` tinyint(1) NOT NULL DEFAULT 0,
`forum` tinyint(1) NOT NULL DEFAULT 0,
`prv` tinyint(1) NOT NULL DEFAULT 0,
`contact-type` int(11) unsigned NOT NULL DEFAULT 0,
`contact-type` int(11) NOT NULL DEFAULT 0,
`hidden` tinyint(1) NOT NULL DEFAULT 0,
`archive` tinyint(1) NOT NULL DEFAULT 0,
`pending` tinyint(1) NOT NULL DEFAULT 1,
@ -169,7 +169,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`info` mediumtext,
`profile-id` int(11) NOT NULL DEFAULT 0,
`bdyear` varchar(4) NOT NULL DEFAULT '',
`bd` date NOT NULL DEFAULT '0000-00-00',
`bd` date NOT NULL DEFAULT '0001-01-01',
`notify_new_posts` tinyint(1) NOT NULL DEFAULT 0,
`fetch_further_information` tinyint(1) NOT NULL DEFAULT 0,
`ffi_keyword_blacklist` text,
@ -186,7 +186,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
INDEX `nick_uid` (`nick`(32),`uid`),
INDEX `dfrn-id` (`dfrn-id`),
INDEX `issued-id` (`issued-id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE conv
@ -202,7 +202,7 @@ CREATE TABLE IF NOT EXISTS `conv` (
`subject` text,
PRIMARY KEY(`id`),
INDEX `uid` (`uid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE event
@ -230,7 +230,7 @@ CREATE TABLE IF NOT EXISTS `event` (
`deny_gid` mediumtext,
PRIMARY KEY(`id`),
INDEX `uid_start` (`uid`,`start`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE fcontact
@ -256,7 +256,7 @@ CREATE TABLE IF NOT EXISTS `fcontact` (
PRIMARY KEY(`id`),
INDEX `addr` (`addr`(32)),
INDEX `url` (`url`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE ffinder
@ -267,7 +267,7 @@ CREATE TABLE IF NOT EXISTS `ffinder` (
`cid` int(10) unsigned NOT NULL DEFAULT 0,
`fid` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE fserver
@ -279,7 +279,7 @@ CREATE TABLE IF NOT EXISTS `fserver` (
`key` text,
PRIMARY KEY(`id`),
INDEX `server` (`server`(32))
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE fsuggest
@ -295,7 +295,7 @@ CREATE TABLE IF NOT EXISTS `fsuggest` (
`note` text,
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE gcign
@ -307,7 +307,7 @@ CREATE TABLE IF NOT EXISTS `gcign` (
PRIMARY KEY(`id`),
INDEX `uid` (`uid`),
INDEX `gcid` (`gcid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE gcontact
@ -328,7 +328,7 @@ CREATE TABLE IF NOT EXISTS `gcontact` (
`about` text,
`keywords` text,
`gender` varchar(32) NOT NULL DEFAULT '',
`birthday` varchar(32) NOT NULL DEFAULT '0000-00-00',
`birthday` varchar(32) NOT NULL DEFAULT '0001-01-01',
`community` tinyint(1) NOT NULL DEFAULT 0,
`contact-type` tinyint(1) NOT NULL DEFAULT -1,
`hide` tinyint(1) NOT NULL DEFAULT 0,
@ -346,7 +346,7 @@ CREATE TABLE IF NOT EXISTS `gcontact` (
INDEX `addr` (`addr`(64)),
INDEX `hide_network_updated` (`hide`,`network`,`updated`),
INDEX `updated` (`updated`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE glink
@ -361,7 +361,7 @@ CREATE TABLE IF NOT EXISTS `glink` (
PRIMARY KEY(`id`),
UNIQUE INDEX `cid_uid_gcid_zcid` (`cid`,`uid`,`gcid`,`zcid`),
INDEX `gcid` (`gcid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE group
@ -374,7 +374,7 @@ CREATE TABLE IF NOT EXISTS `group` (
`name` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY(`id`),
INDEX `uid` (`uid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE group_member
@ -388,7 +388,7 @@ CREATE TABLE IF NOT EXISTS `group_member` (
INDEX `contactid` (`contact-id`),
INDEX `gid_contactid` (`gid`,`contact-id`),
UNIQUE INDEX `uid_gid_contactid` (`uid`,`gid`,`contact-id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE gserver
@ -411,7 +411,7 @@ CREATE TABLE IF NOT EXISTS `gserver` (
`last_failure` datetime DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`id`),
INDEX `nurl` (`nurl`(32))
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE hook
@ -424,7 +424,7 @@ CREATE TABLE IF NOT EXISTS `hook` (
`priority` int(11) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY(`id`),
UNIQUE INDEX `hook_file_function` (`hook`(50),`file`(80),`function`(60))
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE intro
@ -442,7 +442,7 @@ CREATE TABLE IF NOT EXISTS `intro` (
`blocked` tinyint(1) NOT NULL DEFAULT 1,
`ignore` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE item
@ -539,7 +539,7 @@ CREATE TABLE IF NOT EXISTS `item` (
INDEX `uid_eventid` (`uid`,`event-id`),
INDEX `uid_authorlink` (`uid`,`author-link`),
INDEX `uid_ownerlink` (`uid`,`owner-link`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE item_id
@ -555,7 +555,7 @@ CREATE TABLE IF NOT EXISTS `item_id` (
INDEX `sid` (`sid`),
INDEX `service` (`service`(32)),
INDEX `iid` (`iid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE locks
@ -566,7 +566,7 @@ CREATE TABLE IF NOT EXISTS `locks` (
`locked` tinyint(1) NOT NULL DEFAULT 0,
`created` datetime DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE mail
@ -594,7 +594,7 @@ CREATE TABLE IF NOT EXISTS `mail` (
INDEX `convid` (`convid`),
INDEX `uri` (`uri`(64)),
INDEX `parent-uri` (`parent-uri`(64))
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE mailacct
@ -614,7 +614,7 @@ CREATE TABLE IF NOT EXISTS `mailacct` (
`pubmail` tinyint(1) NOT NULL DEFAULT 0,
`last_check` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE manage
@ -625,7 +625,7 @@ CREATE TABLE IF NOT EXISTS `manage` (
`mid` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`),
UNIQUE INDEX `uid_mid` (`uid`,`mid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE notify
@ -653,7 +653,7 @@ CREATE TABLE IF NOT EXISTS `notify` (
INDEX `seen_uid_date` (`seen`,`uid`,`date`),
INDEX `uid_date` (`uid`,`date`),
INDEX `uid_type_link` (`uid`,`type`,`link`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE notify-threads
@ -665,7 +665,7 @@ CREATE TABLE IF NOT EXISTS `notify-threads` (
`parent-item` int(10) unsigned NOT NULL DEFAULT 0,
`receiver-uid` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE oembed
@ -676,7 +676,7 @@ CREATE TABLE IF NOT EXISTS `oembed` (
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`url`),
INDEX `created` (`created`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE parsed_url
@ -689,7 +689,7 @@ CREATE TABLE IF NOT EXISTS `parsed_url` (
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`url`,`guessing`,`oembed`),
INDEX `created` (`created`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE pconfig
@ -702,7 +702,7 @@ CREATE TABLE IF NOT EXISTS `pconfig` (
`v` mediumtext,
PRIMARY KEY(`id`),
UNIQUE INDEX `uid_cat_k` (`uid`,`cat`,`k`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE photo
@ -736,7 +736,7 @@ CREATE TABLE IF NOT EXISTS `photo` (
INDEX `uid_album_scale_created` (`uid`,`album`(32),`scale`,`created`),
INDEX `uid_album_resource-id_created` (`uid`,`album`(32),`resource-id`(64),`created`),
INDEX `resource-id` (`resource-id`(64))
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE poll
@ -756,7 +756,7 @@ CREATE TABLE IF NOT EXISTS `poll` (
`q9` text,
PRIMARY KEY(`id`),
INDEX `uid` (`uid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE poll_result
@ -768,7 +768,7 @@ CREATE TABLE IF NOT EXISTS `poll_result` (
PRIMARY KEY(`id`),
INDEX `poll_id` (`poll_id`),
INDEX `choice` (`choice`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE process
@ -779,7 +779,7 @@ CREATE TABLE IF NOT EXISTS `process` (
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`pid`),
INDEX `command` (`command`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE profile
@ -792,7 +792,7 @@ CREATE TABLE IF NOT EXISTS `profile` (
`hide-friends` tinyint(1) NOT NULL DEFAULT 0,
`name` varchar(255) NOT NULL DEFAULT '',
`pdesc` varchar(255) NOT NULL DEFAULT '',
`dob` varchar(32) NOT NULL DEFAULT '0000-00-00',
`dob` varchar(32) NOT NULL DEFAULT '0001-01-01',
`address` varchar(255) NOT NULL DEFAULT '',
`locality` varchar(255) NOT NULL DEFAULT '',
`region` varchar(255) NOT NULL DEFAULT '',
@ -829,7 +829,7 @@ CREATE TABLE IF NOT EXISTS `profile` (
`net-publish` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`),
INDEX `uid_is-default` (`uid`,`is-default`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE profile_check
@ -842,7 +842,7 @@ CREATE TABLE IF NOT EXISTS `profile_check` (
`sec` varchar(255) NOT NULL DEFAULT '',
`expire` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE push_subscriber
@ -857,7 +857,7 @@ CREATE TABLE IF NOT EXISTS `push_subscriber` (
`last_update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
`secret` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE queue
@ -876,7 +876,7 @@ CREATE TABLE IF NOT EXISTS `queue` (
INDEX `last` (`last`),
INDEX `network` (`network`),
INDEX `batch` (`batch`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE register
@ -890,7 +890,7 @@ CREATE TABLE IF NOT EXISTS `register` (
`language` varchar(16) NOT NULL DEFAULT '',
`note` text,
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE search
@ -901,7 +901,7 @@ CREATE TABLE IF NOT EXISTS `search` (
`term` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY(`id`),
INDEX `uid` (`uid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE session
@ -914,7 +914,7 @@ CREATE TABLE IF NOT EXISTS `session` (
PRIMARY KEY(`id`),
INDEX `sid` (`sid`(64)),
INDEX `expire` (`expire`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE sign
@ -927,7 +927,7 @@ CREATE TABLE IF NOT EXISTS `sign` (
`signer` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY(`id`),
INDEX `iid` (`iid`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE spam
@ -944,7 +944,7 @@ CREATE TABLE IF NOT EXISTS `spam` (
INDEX `spam` (`spam`),
INDEX `ham` (`ham`),
INDEX `term` (`term`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE term
@ -967,7 +967,7 @@ CREATE TABLE IF NOT EXISTS `term` (
INDEX `uid_otype_type_term_global_created` (`uid`,`otype`,`type`,`term`(32),`global`,`created`),
INDEX `uid_otype_type_url` (`uid`,`otype`,`type`,`url`(64)),
INDEX `guid` (`guid`(64))
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE thread
@ -1007,7 +1007,7 @@ CREATE TABLE IF NOT EXISTS `thread` (
INDEX `uid_created` (`uid`,`created`),
INDEX `uid_commented` (`uid`,`commented`),
INDEX `uid_wall_created` (`uid`,`wall`,`created`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE tokens
@ -1020,7 +1020,7 @@ CREATE TABLE IF NOT EXISTS `tokens` (
`scope` varchar(200) NOT NULL DEFAULT '',
`uid` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE user
@ -1071,7 +1071,7 @@ CREATE TABLE IF NOT EXISTS `user` (
`openidserver` text,
PRIMARY KEY(`uid`),
INDEX `nickname` (`nickname`(32))
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE userd
@ -1081,7 +1081,7 @@ CREATE TABLE IF NOT EXISTS `userd` (
`username` varchar(255) NOT NULL,
PRIMARY KEY(`id`),
INDEX `username` (`username`(32))
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;
--
-- TABLE workerqueue
@ -1094,5 +1094,5 @@ CREATE TABLE IF NOT EXISTS `workerqueue` (
`pid` int(11) NOT NULL DEFAULT 0,
`executed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
PRIMARY KEY(`id`)
) DEFAULT CHARSET=utf8mb4;
) DEFAULT COLLATE utf8mb4_general_ci;

10
doc/KeyboardShortcuts.md Normal file
View File

@ -0,0 +1,10 @@
Keyboard shortcuts in Friendica
=======================
* [Home](help)
General
-------
* j: Scroll to next thread
* k: Scroll to previous thread

View File

@ -6,12 +6,10 @@ If you are the admin of a Friendica node, you have access to the so called **Adm
On the front page of the admin panel you will see a summary of information about your node.
These information include the amount of messages currently being processed in the queues.
The first number is the number of messages being actively sent.
This number should decrease quickly.
The second is the messages which could for various reasons not being delivered.
The first number is the number of messages which could not been delivered for various reasons.
They will be resend later.
You can have a quick glance into that second queus in the "Inspect Queue" section of the admin panel.
If you have activated the background workers, there is a third number representing the count of jobs queued for the workers.
The second number represents the current number of jobs for the background workers.
These worker tasks are prioritised and are done accordingly.
Then you get an overview of the accounts on your node, which can be moderated in the "Users" section of the panel.
@ -135,6 +133,9 @@ By default, any (valid) email address is allowed in registrations.
If you enable the `Allow Users to set remote_self` users can select Atom feeds from their contact list being their *remote self* in die advanced contact settings.
Which means that postings by the remote self are automatically reposted by Friendica in their names.
This feature can be used to let the user mirror e.g. blog postings into their Friendica postings.
It is disabled by default, as it causes additional load on the server and may be misused to distribute SPAM.
As admin of the node you can also set this flag directly in the database.
Before doing so, you should be sure you know what you do and have a backup of the database.
@ -169,6 +170,19 @@ This will mean you cannot connect (at all) to self-signed SSL sites.
### Worker
This section allows you to configure the background process that is triggered by the `cron` job that was created during the installation.
The process does check the available system resources before creating a new worker for a task.
Because of this, it may happen that the maximum number of worker processes you allow will not be reached.
If your server setup does not allow you to use the `proc_open` function of PHP, please disable it in this section.
The tasks for the background process have priorities.
To guarantee that important tasks are executed even though the system has a lot of work to do, it is useful to enable the *fastlane*.
Should you not be able to run a cron job on your server, you can also activate the *frontend* worker.
If you have done so, you can call `example.com/worker` (replace example.com with your actual domain name) on a regular basis from an external servie.
This will then trigger the execution of the background process.
### Relocate
## Users

View File

@ -14,7 +14,6 @@ Database Tables
| [config](help/database/db_config) | main configuration storage |
| [contact](help/database/db_contact) | contact table |
| [conv](help/database/db_conv) | private messages |
| [deliverq](help/database/db_deliverq) | |
| [event](help/database/db_event) | Events |
| [fcontact](help/database/db_fcontact) | friend suggestion stuff |
| [ffinder](help/database/db_ffinder) | friend suggestion stuff |

View File

@ -10,8 +10,8 @@ Table attach
| filetype | mimetype | varchar(64) | NO | | | |
| filesize | size in bytes | int(11) | NO | | 0 | |
| data | file data | longblob | NO | | NULL | |
| created | creation time | datetime | NO | | 0000-00-00 00:00:00 | |
| edited | last edit time | datetime | NO | | 0000-00-00 00:00:00 | |
| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
| allow_cid | Access Control - list of allowed contact.id '<19><78> | mediumtext | NO | | NULL | |
| allow_gid | Access Control - list of allowed groups | mediumtext | NO | | NULL | |
| deny_cid | Access Control - list of denied contact.id | mediumtext | NO | | NULL | |

View File

@ -5,7 +5,7 @@ Table cache
| ------------ | ---------------------------------- | ------------ | ---- | --- | ------------------- | ----- |
| k | horizontal width + url or resource | varchar(255) | NO | PRI | NULL | |
| v | OEmbed response from site | text | NO | | NULL | |
| updated | datetime of cache insertion | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| updated | datetime of cache insertion | datetime | NO | MUL | 0001-01-01 00:00:00 | |
| expire_mode | | int(11) | NO | | 0 | |
Return to [database documentation](help/database)

View File

@ -5,7 +5,7 @@ Table contact
|---------------------------|-----------------------------------------------------------|--------------|------|-----|---------------------|----------------|
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | |
| created | | datetime | NO | | 0000-00-00 00:00:00 | |
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
| self | 1 if the contact is the user him/her self | tinyint(1) | NO | | 0 | |
| remote_self | | tinyint(1) | NO | | 0 | |
| rel | The kind of the relation between the user and the contact | tinyint(1) | NO | | 0 | |
@ -41,14 +41,14 @@ Table contact
| usehub | | tinyint(1) | NO | | 0 | |
| subhub | | tinyint(1) | NO | | 0 | |
| hub-verify | | varchar(255) | NO | | | |
| last-update | Date of the last try to update the contact info | datetime | NO | | 0000-00-00 00:00:00 | |
| success_update | Date of the last successful contact update | datetime | NO | | 0000-00-00 00:00:00 | |
| failure_update | Date of the last failed update | datetime | NO | | 0000-00-00 00:00:00 | |
| name-date | | datetime | NO | | 0000-00-00 00:00:00 | |
| uri-date | | datetime | NO | | 0000-00-00 00:00:00 | |
| avatar-date | | datetime | NO | | 0000-00-00 00:00:00 | |
| term-date | | datetime | NO | | 0000-00-00 00:00:00 | |
| last-item | date of the last post | datetime | NO | | 0000-00-00 00:00:00 | |
| last-update | Date of the last try to update the contact info | datetime | NO | | 0001-01-01 00:00:00 | |
| success_update | Date of the last successful contact update | datetime | NO | | 0001-01-01 00:00:00 | |
| failure_update | Date of the last failed update | datetime | NO | | 0001-01-01 00:00:00 | |
| name-date | | datetime | NO | | 0001-01-01 00:00:00 | |
| uri-date | | datetime | NO | | 0001-01-01 00:00:00 | |
| avatar-date | | datetime | NO | | 0001-01-01 00:00:00 | |
| term-date | | datetime | NO | | 0001-01-01 00:00:00 | |
| last-item | date of the last post | datetime | NO | | 0001-01-01 00:00:00 | |
| priority | | tinyint(3) | NO | | 0 | |
| blocked | | tinyint(1) | NO | | 1 | |
| readonly | posts of the contact are readonly | tinyint(1) | NO | | 0 | |
@ -64,7 +64,7 @@ Table contact
| info | | mediumtext | NO | | NULL | |
| profile-id | | int(11) | NO | | 0 | |
| bdyear | | varchar(4) | NO | | | |
| bd | | date | NO | | 0000-00-00 | |
| bd | | date | NO | | 0001-01-01 | |
| notify_new_posts | | tinyint(1) | NO | | 0 | |
| fetch_further_information | | tinyint(1) | NO | | 0 | |
| ffi_keyword_blacklist | | mediumtext | NO | | NULL | |

View File

@ -8,8 +8,8 @@ Table conv
| recips | sender_handle;recipient_handle | mediumtext | NO | | NULL | |
| uid | user_id of the owner of this data | int(11) | NO | MUL | 0 | |
| creator | handle of creator | varchar(255) | NO | | | |
| created | creation timestamp | datetime | NO | | 0000-00-00 00:00:00 | |
| updated | edited timestamp | datetime | NO | | 0000-00-00 00:00:00 | |
| created | creation timestamp | datetime | NO | | 0001-01-01 00:00:00 | |
| updated | edited timestamp | datetime | NO | | 0001-01-01 00:00:00 | |
| subject | subject of initial message | mediumtext | NO | | NULL | |
Return to [database documentation](help/database)

View File

@ -1,12 +0,0 @@
Table deliverq
==============
| Field | Description | Type | Null | Key | Default | Extra |
|---------|------------------|------------------|------|-----|---------|----------------|
| id | sequential ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
| cmd | | varchar(32) | NO | | | |
| item | | int(11) | NO | | 0 | |
| contact | | int(11) | NO | | 0 | |
Return to [database documentation](help/database)

View File

@ -7,10 +7,10 @@ Table event
| uid | user_id of the owner of this data | int(11) | NO | MUL | 0 | |
| cid | contact_id (ID of the contact in contact table) | int(11) | NO | | 0 | |
| uri | | varchar(255) | NO | | | |
| created | creation time | datetime | NO | | 0000-00-00 00:00:00 | |
| edited | last edit time | datetime | NO | | 0000-00-00 00:00:00 | |
| start | event start time | datetime | NO | | 0000-00-00 00:00:00 | |
| finish | event end time | datetime | NO | | 0000-00-00 00:00:00 | |
| created | creation time | datetime | NO | | 0001-01-01 00:00:00 | |
| edited | last edit time | datetime | NO | | 0001-01-01 00:00:00 | |
| start | event start time | datetime | NO | | 0001-01-01 00:00:00 | |
| finish | event end time | datetime | NO | | 0001-01-01 00:00:00 | |
| summary | short description or title of the event | text | NO | | NULL | |
| desc | event description | text | NO | | NULL | |
| location | event location | text | NO | | NULL | |

View File

@ -19,6 +19,6 @@ Table fcontact
| network | | varchar(32) | NO | | | |
| alias | | varchar(255) | NO | | | |
| pubkey | | text | NO | | NULL | |
| updated | | datetime | NO | | 0000-00-00 00:00:00 | |
| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -11,6 +11,6 @@ Table fsuggest
| request | | varchar(255) | NO | | | |
| photo | | varchar(255) | NO | | | |
| note | | text | NO | | NULL | |
| created | | datetime | NO | | 0000-00-00 00:00:00 | |
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -10,15 +10,15 @@ Table gcontact
| nurl | | varchar(255) | NO | MUL | | |
| photo | Link to the profile photo | varchar(255) | NO | | | |
| connect | | varchar(255) | NO | | | |
| created | | datetime | NO | | 0000-00-00 00:00:00 | |
| updated | | datetime | YES | MUL | 0000-00-00 00:00:00 | |
| last_contact | | datetime | YES | | 0000-00-00 00:00:00 | |
| last_failure | | datetime | YES | | 0000-00-00 00:00:00 | |
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
| updated | | datetime | YES | MUL | 0001-01-01 00:00:00 | |
| last_contact | | datetime | YES | | 0001-01-01 00:00:00 | |
| last_failure | | datetime | YES | | 0001-01-01 00:00:00 | |
| location | | varchar(255) | NO | | | |
| about | | text | NO | | NULL | |
| keywords | puplic keywords (interests) | text | NO | | NULL | |
| gender | | varchar(32) | NO | | | |
| birthday | | varchar(32) | NO | | 0000-00-00 | |
| birthday | | varchar(32) | NO | | 0001-01-01 | |
| community | 1 if contact is forum account | tinyint(1) | NO | | 0 | |
| hide | 1 = should be hidden from search | tinyint(1) | NO | | 0 | |
| nsfw | 1 = contact posts nsfw content | tinyint(1) | NO | | 0 | |

View File

@ -8,6 +8,6 @@ Table glink
| uid | | int(11) | NO | | 0 | |
| gcid | | int(11) | NO | MUL | 0 | |
| zcid | | int(11) | NO | MUL | 0 | |
| updated | | datetime | NO | | 0000-00-00 00:00:00 | |
| updated | | datetime | NO | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -14,10 +14,10 @@ Table gserver
| noscrape | | varchar(255) | NO | | | |
| network | | varchar(32) | NO | | | |
| platform | | varchar(255) | NO | | | |
| created | | datetime | NO | | 0000-00-00 00:00:00 | |
| last_poco_query | | datetime | YES | | 0000-00-00 00:00:00 | |
| last_contact | | datetime | YES | | 0000-00-00 00:00:00 | |
| last_failure | | datetime | YES | | 0000-00-00 00:00:00 | |
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
| last_poco_query | | datetime | YES | | 0001-01-01 00:00:00 | |
| last_contact | | datetime | YES | | 0001-01-01 00:00:00 | |
| last_failure | | datetime | YES | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -11,7 +11,7 @@ Table intro
| duplex | | tinyint(1) | NO | | 0 | |
| note | | text | NO | | NULL | |
| hash | | varchar(255) | NO | | | |
| datetime | | datetime | NO | | 0000-00-00 00:00:00 | |
| datetime | | datetime | NO | | 0001-01-01 00:00:00 | |
| blocked | | tinyint(1) | NO | | 1 | |
| ignore | | tinyint(1) | NO | | 0 | |

View File

@ -16,11 +16,11 @@ Table item
| parent-uri | uri of the parent to this item | varchar(255) | NO | MUL | | |
| extid | | varchar(255 | NO | MUL | | |
| thr-parent | If the parent of this item is not the top-level item in the conversation, the uri of the immediate parent; otherwise set to parent-uri | varchar(255) | NO | | | |
| created | Creation timestamp. | datetime | NO | | 0000-00-00 00:00:00 | |
| edited | Date of last edit (default is created) | datetime | NO | | 0000-00-00 00:00:00 | |
| commented | Date of last comment/reply to this item | datetime | NO | | 0000-00-00 00:00:00 | |
| received | datetime | datetime | NO | | 0000-00-00 00:00:00 | |
| changed | Date that something in the conversation changed, indicating clients should fetch the conversation again | datetime | NO | | 0000-00-00 00:00:00 | |
| created | Creation timestamp. | datetime | NO | | 0001-01-01 00:00:00 | |
| edited | Date of last edit (default is created) | datetime | NO | | 0001-01-01 00:00:00 | |
| commented | Date of last comment/reply to this item | datetime | NO | | 0001-01-01 00:00:00 | |
| received | datetime | datetime | NO | | 0001-01-01 00:00:00 | |
| changed | Date that something in the conversation changed, indicating clients should fetch the conversation again | datetime | NO | | 0001-01-01 00:00:00 | |
| owner-name | Name of the owner of this item | varchar(255) | NO | | | |
| owner-link | Link to the profile page of the owner of this item | varchar(255) | NO | | | |
| owner-avatar | Link to the avatar picture of the owner of this item | varchar(255) | NO | | | |

View File

@ -6,6 +6,6 @@ Table locks
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
| name | | varchar(128) | NO | | | |
| locked | | tinyint(1) | NO | | 0 | |
| created | | datetime | YES | | 0000-00-00 00:00:00 | |
| created | | datetime | YES | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -19,6 +19,6 @@ Table mail
| unknown | if sender not in the contact table this is 1 | varchar(255) | NO | | 0 | |
| uri | | varchar(255) | NO | MUL | | |
| parent-uri | | varchar(255) | NO | MUL | | |
| created | creation time of the private message | datetime | NO | | 0000-00-00 00:00:00 | |
| created | creation time of the private message | datetime | NO | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -15,6 +15,6 @@ Table mailacct
| action | | int(11) | NO | | 0 | |
| movetofolder | | varchar(255) | NO | | | |
| pubmail | | tinyint(1) | NO | | 0 | |
| last_check | | datetime | NO | | 0000-00-00 00:00:00 | |
| last_check | | datetime | NO | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -9,7 +9,7 @@ Table notify
| name | | varchar(255) | NO | | | |
| url | | varchar(255) | NO | | | |
| photo | | varchar(255) | NO | | | |
| date | | datetime | NO | | 0000-00-00 00:00:00 | |
| date | | datetime | NO | | 0001-01-01 00:00:00 | |
| msg | | mediumtext | YES | | NULL | |
| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | |
| link | | varchar(255) | NO | | | |

View File

@ -5,6 +5,6 @@ Table oembed
| ------------ | ---------------------------------- | ------------ | ---- | --- | ------------------- | ----- |
| url | page url | varchar(255) | NO | PRI | NULL | |
| content | OEmbed data of the page | text | NO | | NULL | |
| created | datetime of creation | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| created | datetime of creation | datetime | NO | MUL | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -7,6 +7,6 @@ Table parsed_url
| guessing | is the "guessing" mode active? | tinyint(1) | NO | PRI | 0 | |
| oembed | is the data the result of oembed? | tinyint(1) | NO | PRI | 0 | |
| content | page data | text | NO | | NULL | |
| created | datetime of creation | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| created | datetime of creation | datetime | NO | MUL | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -8,8 +8,8 @@ Table photo
| contact-id | contact.id | int(10) unsigned | NO | | 0 | |
| guid | A unique identifier for this photo | varchar(64) | NO | MUL | | |
| resource-id | | varchar(255) | NO | MUL | | |
| created | creation date | datetime | NO | | 0000-00-00 00:00:00 | |
| edited | last edited date | datetime | NO | | 0000-00-00 00:00:00 | |
| created | creation date | datetime | NO | | 0001-01-01 00:00:00 | |
| edited | last edited date | datetime | NO | | 0001-01-01 00:00:00 | |
| title | | varchar(255) | NO | | | |
| desc | | text | NO | | NULL | |
| album | The name of the album to which the photo belongs | varchar(255) | NO | | | |

View File

@ -10,7 +10,7 @@ Table profile
| hide-friends | Hide friend list from viewers of this profile | tinyint(1) | NO | | 0 | |
| name | | varchar(255) | NO | | | |
| pdesc | Title or description | varchar(255) | NO | | | |
| dob | Day of birth | varchar(32) | NO | | 0000-00-00 | |
| dob | Day of birth | varchar(32) | NO | | 0001-01-01 | |
| address | | varchar(255) | NO | | | |
| locality | | varchar(255) | NO | | | |
| region | | varchar(255) | NO | | | |
@ -20,7 +20,7 @@ Table profile
| gender | | varchar(32) | NO | | | |
| marital | | varchar(255) | NO | | | |
| with | | text | NO | | NULL | |
| howlong | | datetime | NO | | 0000-00-00 00:00:00 | |
| howlong | | datetime | NO | | 0001-01-01 00:00:00 | |
| sexual | | varchar(255) | NO | | | |
| politic | | varchar(255) | NO | | | |
| religion | | varchar(255) | NO | | | |

View File

@ -6,8 +6,8 @@ Table queue
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
| cid | | int(11) | NO | MUL | 0 | |
| network | | varchar(32) | NO | MUL | | |
| created | | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| last | | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| created | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
| last | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
| content | | mediumtext | NO | | NULL | |
| batch | | tinyint(1) | NO | MUL | 0 | |

View File

@ -5,7 +5,7 @@ Table register
| -------- | ------------- | ---------------- | ---- | --- | ------------------- | --------------- |
| id | sequential ID | int(11) unsigned | NO | PRI | NULL | auto_increment |
| hash | | varchar(255) | NO | | | |
| created | | datetime | NO | | 0000-00-00 00:00:00 | |
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
| uid | user.id | int(11) unsigned | NO | | | |
| password | | varchar(255) | NO | | | |
| language | | varchar(16) | NO | | | |

View File

@ -8,6 +8,6 @@ Table spam
| spam | | int(11) | NO | MUL | 0 | |
| ham | | int(11) | NO | MUL | 0 | |
| term | | varchar(255) | NO | MUL | | |
| date | | datetime | NO | | 0000-00-00 00:00:00 | |
| date | | datetime | NO | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -12,8 +12,8 @@ Table term
| aid | | int(10) unsigned | NO | | 0 | |
| uid | | int(10) unsigned | NO | MUL | 0 | |
| guid | | varchar(255) | NO | MUL | | |
| created | | datetime | NO | | 0000-00-00 00:00:00 | |
| received | | datetime | NO | | 0000-00-00 00:00:00 | |
| created | | datetime | NO | | 0001-01-01 00:00:00 | |
| received | | datetime | NO | | 0001-01-01 00:00:00 | |
| global | | tinyint(1) | NO | | 0 | |
Return to [database documentation](help/database)

View File

@ -9,11 +9,11 @@ Table thread
| gcontact-id | Global Contact | int(11) unsigned | NO | | 0 | |
| owner-id | Item owner | int(11) unsigned | NO | MUL | 0 | |
| author-id | Item author | int(11) unsigned | NO | MUL | 0 | |
| created | | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| edited | | datetime | NO | | 0000-00-00 00:00:00 | |
| commented | | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| received | | datetime | NO | | 0000-00-00 00:00:00 | |
| changed | | datetime | NO | | 0000-00-00 00:00:00 | |
| created | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
| edited | | datetime | NO | | 0001-01-01 00:00:00 | |
| commented | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
| received | | datetime | NO | | 0001-01-01 00:00:00 | |
| changed | | datetime | NO | | 0001-01-01 00:00:00 | |
| wall | | tinyint(1) | NO | MUL | 0 | |
| private | | tinyint(1) | NO | | 0 | |
| pubmail | | tinyint(1) | NO | | 0 | |

View File

@ -12,8 +12,8 @@ Table user
| openid | | varchar(255) | NO | | | |
| timezone | PHP-legal timezone | varchar(128) | NO | | | |
| language | default language | varchar(32) | NO | | en | |
| register_date | timestamp of registration | datetime | NO | | 0000-00-00 00:00:00 | |
| login_date | timestamp of last login | datetime | NO | | 0000-00-00 00:00:00 | |
| register_date | timestamp of registration | datetime | NO | | 0001-01-01 00:00:00 | |
| login_date | timestamp of last login | datetime | NO | | 0001-01-01 00:00:00 | |
| default-location | Default for item.location | varchar(255) | NO | | | |
| allow_location | 1 allows to display the location | tinyint(1) | NO | | 0 | |
| theme | user theme preference | varchar(255) | NO | | | |
@ -36,8 +36,8 @@ Table user
| expire | | int(11) unsigned | NO | | 0 | |
| account_removed | if 1 the account is removed | tinyint(1) | NO | | 0 | |
| account_expired | | tinyint(1) | NO | | 0 | |
| account_expires_on | timestamp when account expires and will be deleted | datetime | NO | | 0000-00-00 00:00:00 | |
| expire_notification_sent | timestamp of last warning of account expiration | datetime | NO | | 0000-00-00 00:00:00 | |
| account_expires_on | timestamp when account expires and will be deleted | datetime | NO | | 0001-01-01 00:00:00 | |
| expire_notification_sent | timestamp of last warning of account expiration | datetime | NO | | 0001-01-01 00:00:00 | |
| service_class | service class for this account, determines what if any limits/restrictions are in place | varchar(32) | NO | | | |
| def_gid | | int(11) | NO | | 0 | |
| allow_cid | default permission for this user | mediumtext | NO | | NULL | |

View File

@ -6,8 +6,8 @@ Table workerqueue
| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
| parameter | | text | NO | | NULL | |
| priority | | tinyint(3) unsigned | NO | | 0 | |
| created | | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| created | | datetime | NO | MUL | 0001-01-01 00:00:00 | |
| pid | | int(11) | NO | | 0 | |
| executed | | datetime | NO | | 0000-00-00 00:00:00 | |
| executed | | datetime | NO | | 0001-01-01 00:00:00 | |
Return to [database documentation](help/database)

View File

@ -5,17 +5,14 @@
Wenn du der Administrator einer Friendica Instanz bist, hast du Zugriff auf das so genannte **Admin Panel** in dem du die Friendica Instanz konfigurieren kannst,
Auf der Startseite des Admin Panels werden die Informationen zu der Instanz zusammengefasst.
Diese Informationen beinhalten die Anzahl der Nachrichten, die sich aktuell in den Warteschlangen befinden.
Hierbei ist die erste Zahl die Zahl der Nachrichten die gerade aktiv verteilt werden.
Diese Zahl sollte sich relativ schnell sinken.
Die zweite Zahl gibt die Anzahl von Nachrichten an, die nicht zugestellt werden konnten.
Die erste Zahl gibt die Anzahl von Nachrichten an, die nicht zugestellt werden konnten.
Die Zustellung wird zu einem späteren Zeitpunkt noch einmal versucht.
Unter dem Punkt "Warteschlange Inspizieren" kannst du einen schnellen Blick auf die zweite Warteschlange werfen.
Solltest du für die Hintergrundprozesse die Worker aktiviert haben, wird eine dritte Zahl angezeigt.
Diese repräsentiert die Anzahl der Aufgaben, die die Worker noch vor sich haben.
Die zweite Zahl steht für die Anzahl der Aufgaben, die die Worker noch vor sich haben.
Die Worker arbeiten Hintergrundprozesse ab.
Die Aufgaben der Worker sind priorisiert und werden anhand dieser Prioritäten abgearbeitet.
Des weiteren findest du eine Übersicht über die Accounts auf dem Friendica Knoten, die unter dem Punkt "Nutzer" moderiert werden können.
Desweiteren findest du eine Übersicht über die Accounts auf dem Friendica Knoten, die unter dem Punkt "Nutzer" moderiert werden können.
Sowie eine Liste der derzeit aktivierten Addons.
Diese Liste ist verlinkt, so dass du schnellen Zugriff auf die Informationsseiten der einzelnen Addons hast.
Abschließend findest du auf der Startseite des Admin Panels die installierte Version von Friendica.
@ -129,6 +126,10 @@ Wildcards werden akzeptiert (Wildcard-Unterstützung unter Windows benötigt PHP
Webb du die Option `Nutzern erlauben das remote_self Flag zu setzen` aktivierst, können alle Nutzer Atom Feeds in den erweiterten Einstellungen des Kontakts als "Entferntes Konto" markieren.
Dadurch werden automatisch alle Beiträge dieser Feeds für diesen Nutzer gespiegelt und an die Kontakte bei Friendica verteilt.
Dieses Feature kann z.B. dafür genutzt werden Blogbeiträge zu spiegeln.
In der Grundeinstellung ist es nicht aktiviert, da es zusätzliche Last auf dem Server verursachen kann.
Außerdem könnte es durch Nutzer als Spam Verteiler missbraucht werden.
Als Administrator der Friendica Instanz kannst du diese Einstellungen ansonsten nur direkt in der Datenbank vornehmen.
Bevor du das tust solltest du sicherstellen, dass du ein Backup der Datenbank hast und genau weißt was die Änderungen an der Datenbank bewirken, die du vornehmen willst.
@ -165,6 +166,19 @@ Das führt dazu, dass du keinerlei Verbindung zu einer selbst unterzeichneten SS
### Worker
In diesem Abschnitt kann der Hintergrund-Prozess konfiguriert werden.
Bevor ein neuer *Worker* Prozess gestartet wird, überprüft das System, dass die vorhandenen Resourchen ausrechend sind,
Aus diesem Grund kann es sein, dass die maximale Zahl der Hintergrungprozesse nicht erreicht wird.
Sollte die PHP Funktion `proc_open` auf dem Server nicht verfügbar sein, kann die Verwendung durch Friendica hier unterbunden werden.
Die Aufgaben die im Hintergrund erledigt werden, haben Prioritäten zugeteilt.
Um garantieren zu können, das wichtige Prozesse schnellst möglich abgearbeitet werden können, selbst wenn das System gerade stark belastet ist, sollte die *fastlane* aktiviert sein.
Wenn es auf deinem Server nicht möglich ist, einen cron Job zu starten, kannst du den *frontend* Worker einschalten.
Nachdem dies geschehen ist, kannst du `example.com/worker` (tausche example.com mit dem echten Domainnamen aus) aufrufen werden.
Dadurch werden dann die Aufgaben aktiviert, die der cron Job sonst aktivieren würde.
### Umsiedeln
## Nutzer

File diff suppressed because one or more lines are too long

View File

@ -16,7 +16,7 @@ $db_user = 'mysqlusername';
$db_pass = 'mysqlpassword';
$db_data = 'mysqldatabasename';
// Set the database connection charset to UTF8.
// Set the database connection charset to full Unicode (utf8mb4).
// Changing this value will likely corrupt the special characters.
// You have been warned.
$a->config['system']['db_charset'] = "utf8mb4";
@ -87,7 +87,7 @@ $a->config['system']['no_regfullname'] = true;
//$a->config['system']['block_local_dir'] = false;
// Location of the global directory
$a->config['system']['directory'] = 'http://dir.friendi.ca';
$a->config['system']['directory'] = 'https://dir.friendica.social';
// Allowed protocols in link URLs; HTTP protocols always are accepted
$a->config['system']['allowed_link_protocols'] = array('ftp', 'ftps', 'mailto', 'cid', 'gopher');

View File

@ -212,6 +212,10 @@ function unmark_for_death($contact) {
function get_contact_details_by_url($url, $uid = -1, $default = array()) {
static $cache = array();
if ($url == '') {
return $default;
}
if ($uid == -1) {
$uid = local_user();
}
@ -254,7 +258,7 @@ function get_contact_details_by_url($url, $uid = -1, $default = array()) {
// "bd" always contains the upcoming birthday of a contact.
// "birthday" might contain the birthday including the year of birth.
if ($profile["birthday"] != "0000-00-00") {
if ($profile["birthday"] > '0001-01-01') {
$bd_timestamp = strtotime($profile["birthday"]);
$month = date("m", $bd_timestamp);
$day = date("d", $bd_timestamp);
@ -271,7 +275,7 @@ function get_contact_details_by_url($url, $uid = -1, $default = array()) {
$profile["bd"] = (++$current_year)."-".$month."-".$day;
}
} else {
$profile["bd"] = "0000-00-00";
$profile["bd"] = '0001-01-01';
}
} else {
$profile = $default;
@ -307,7 +311,7 @@ function get_contact_details_by_url($url, $uid = -1, $default = array()) {
$profile["location"] = "";
$profile["about"] = "";
$profile["gender"] = "";
$profile["birthday"] = "0000-00-00";
$profile["birthday"] = '0001-01-01';
}
$cache[$url][$uid] = $profile;
@ -328,6 +332,10 @@ function get_contact_details_by_url($url, $uid = -1, $default = array()) {
function get_contact_details_by_addr($addr, $uid = -1) {
static $cache = array();
if ($addr == '') {
return array();
}
if ($uid == -1) {
$uid = local_user();
}
@ -534,6 +542,10 @@ function get_contact($url, $uid = 0, $no_update = false) {
$data = array();
$contact_id = 0;
if ($url == '') {
return 0;
}
// We first try the nurl (http://server.tld/nick), most common case
$contacts = q("SELECT `id`, `avatar-date` FROM `contact`
WHERE `nurl` = '%s'

View File

@ -364,9 +364,9 @@ class Probe {
return self::mail($uri, $uid);
}
if ($network == NETWORK_MAIL)
if ($network == NETWORK_MAIL) {
return self::mail($uri, $uid);
}
// Remove "acct:" from the URI
$uri = str_replace('acct:', '', $uri);
@ -391,37 +391,37 @@ class Probe {
/// @todo Do we need the prefix "acct:" or "acct://"?
foreach ($lrdd AS $key => $link) {
if ($webfinger)
if ($webfinger) {
continue;
}
if (!in_array($key, array("lrdd", "lrdd-xml", "lrdd-json"))) {
continue;
}
// At first try it with the given uri
$path = str_replace('{uri}', urlencode($uri), $link);
$webfinger = self::webfinger($path);
if (!in_array($key, array("lrdd", "lrdd-xml", "lrdd-json")))
continue;
// We cannot be sure that the detected address was correct, so we don't use the values
if ($webfinger AND ($uri != $addr)) {
$nick = "";
$addr = "";
}
// Try webfinger with the address (user@domain.tld)
$path = str_replace('{uri}', urlencode($addr), $link);
$webfinger = self::webfinger($path);
if (!$webfinger) {
$path = str_replace('{uri}', urlencode($addr), $link);
$webfinger = self::webfinger($path);
}
// Mastodon needs to have it with "acct:"
if (!$webfinger) {
$path = str_replace('{uri}', urlencode("acct:".$addr), $link);
$webfinger = self::webfinger($path);
}
// If webfinger wasn't successful then try it with the URL - possibly in the format https://...
if (!$webfinger AND ($uri != $addr)) {
$path = str_replace('{uri}', urlencode($uri), $link);
$webfinger = self::webfinger($path);
// Since the detection with the address wasn't successful, we delete it.
if ($webfinger) {
$nick = "";
$addr = "";
}
}
}
if (!$webfinger)
if (!$webfinger) {
return self::feed($uri);
}
$result = false;

View File

@ -4,11 +4,11 @@
* @file include/acl_selectors.php
*/
require_once("include/contact_selectors.php");
require_once("include/contact_widgets.php");
require_once("include/DirSearch.php");
require_once("include/features.php");
require_once("mod/proxy.php");
require_once "include/contact_selectors.php";
require_once "include/contact_widgets.php";
require_once "include/DirSearch.php";
require_once "include/features.php";
require_once "mod/proxy.php";
/**
@ -35,10 +35,11 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
if (dbm::is_result($r)) {
foreach ($r as $rr) {
if((is_array($preselected)) && in_array($rr['id'], $preselected))
if ((is_array($preselected)) && in_array($rr['id'], $preselected)) {
$selected = " selected=\"selected\" ";
else
} else {
$selected = '';
}
$trimmed = mb_substr($rr['name'],0,12);
@ -54,7 +55,8 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
return $o;
}
/// @TODO after an optional parameter, no mandadory parameter can follow
/// @TODO find proper type-hints
function contact_selector($selname, $selclass, $preselected = false, $options) {
$a = get_app();
@ -66,40 +68,42 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
$size = 4;
if (is_array($options)) {
if (x($options,'size'))
if (x($options, 'size'))
$size = $options['size'];
if (x($options,'mutual_friends')) {
if (x($options, 'mutual_friends')) {
$mutual = true;
}
if (x($options,'single')) {
if (x($options, 'single')) {
$single = true;
}
if (x($options,'multiple')) {
if (x($options, 'multiple')) {
$single = false;
}
if (x($options,'exclude')) {
if (x($options, 'exclude')) {
$exclude = $options['exclude'];
}
if (x($options,'networks')) {
switch($options['networks']) {
if (x($options, 'networks')) {
switch ($options['networks']) {
case 'DFRN_ONLY':
$networks = array(NETWORK_DFRN);
break;
case 'PRIVATE':
if(is_array($a->user) && $a->user['prvnets'])
$networks = array(NETWORK_DFRN,NETWORK_MAIL,NETWORK_DIASPORA);
else
$networks = array(NETWORK_DFRN,NETWORK_FACEBOOK,NETWORK_MAIL, NETWORK_DIASPORA);
if (is_array($a->user) && $a->user['prvnets']) {
$networks = array(NETWORK_DFRN, NETWORK_MAIL, NETWORK_DIASPORA);
} else {
$networks = array(NETWORK_DFRN, NETWORK_FACEBOOK, NETWORK_MAIL, NETWORK_DIASPORA);
}
break;
case 'TWO_WAY':
if(is_array($a->user) && $a->user['prvnets'])
$networks = array(NETWORK_DFRN,NETWORK_MAIL,NETWORK_DIASPORA);
else
$networks = array(NETWORK_DFRN,NETWORK_FACEBOOK,NETWORK_MAIL,NETWORK_DIASPORA,NETWORK_OSTATUS);
if (is_array($a->user) && $a->user['prvnets']) {
$networks = array(NETWORK_DFRN, NETWORK_MAIL, NETWORK_DIASPORA);
} else {
$networks = array(NETWORK_DFRN, NETWORK_FACEBOOK, NETWORK_MAIL, NETWORK_DIASPORA, NETWORK_OSTATUS);
}
break;
default:
default: /// @TODO Maybe log this call?
break;
}
}
@ -113,26 +117,30 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
$sql_extra = '';
if($x['mutual']) {
if (x($x, 'mutual')) {
$sql_extra .= sprintf(" AND `rel` = %d ", intval(CONTACT_IS_FRIEND));
}
if(intval($x['exclude']))
if (x($x, 'exclude')) {
$sql_extra .= sprintf(" AND `id` != %d ", intval($x['exclude']));
}
if(is_array($x['networks']) && count($x['networks'])) {
for($y = 0; $y < count($x['networks']) ; $y ++)
if (is_array($x['networks']) && count($x['networks'])) {
/// @TODO rewrite to foreach()
for ($y = 0; $y < count($x['networks']) ; $y ++) {
$x['networks'][$y] = "'" . dbesc($x['networks'][$y]) . "'";
$str_nets = implode(',',$x['networks']);
}
$str_nets = implode(',', $x['networks']);
$sql_extra .= " AND `network` IN ( $str_nets ) ";
}
$tabindex = (x($options, 'tabindex') ? "tabindex=\"" . $options["tabindex"] . "\"" : "");
if($x['single'])
if ($x['single']) {
$o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"" . $x['size'] . "\" $tabindex >\r\n";
else
} else {
$o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"" . $x['size'] . "$\" $tabindex >\r\n";
}
$r = q("SELECT `id`, `name`, `url`, `network` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
@ -174,7 +182,7 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
function contact_select($selname, $selclass, $preselected = false, $size = 4, $privmail = false, $celeb = false, $privatenet = false, $tabindex = null) {
require_once("include/bbcode.php");
require_once "include/bbcode.php";
$a = get_app();
@ -185,29 +193,32 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
$sql_extra = '';
if($privmail || $celeb) {
if ($privmail || $celeb) {
$sql_extra .= sprintf(" AND `rel` = %d ", intval(CONTACT_IS_FRIEND));
}
if($privmail)
if ($privmail) {
$sql_extra .= sprintf(" AND `network` IN ('%s' , '%s') ",
NETWORK_DFRN, NETWORK_DIASPORA);
elseif($privatenet)
} elseif ($privatenet) {
$sql_extra .= sprintf(" AND `network` IN ('%s' , '%s', '%s', '%s') ",
NETWORK_DFRN, NETWORK_MAIL, NETWORK_FACEBOOK, NETWORK_DIASPORA);
}
$tabindex = ($tabindex > 0 ? "tabindex=\"$tabindex\"" : "");
if ($privmail AND $preselected) {
$sql_extra .= " AND `id` IN (".implode(",", $preselected).")";
$hidepreselected = ' style="display: none;"';
} else
} else {
$hidepreselected = "";
}
if($privmail)
if ($privmail) {
$o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"$size\" $tabindex $hidepreselected>\r\n";
else
} else {
$o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex >\r\n";
}
$r = q("SELECT `id`, `name`, `url`, `network` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
@ -229,8 +240,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
foreach ($r as $rr) {
if ((is_array($preselected)) && in_array($rr['id'], $preselected)) {
$selected = " selected=\"selected\" ";
}
else {
} else {
$selected = '';
}
@ -249,8 +259,9 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
$o .= "</select>\r\n";
if ($privmail AND $preselected)
if ($privmail AND $preselected) {
$o .= implode(", ", $receiverlist);
}
call_hooks($a->module . '_post_' . $selname, $o);
@ -259,7 +270,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
function fixacl(&$item) {
$item = intval(str_replace(array('<','>'),array('',''),$item));
$item = intval(str_replace(array('<', '>'), array('', ''), $item));
}
function prune_deadguys($arr) {
@ -268,7 +279,7 @@ function prune_deadguys($arr) {
return $arr;
}
$str = dbesc(implode(',',$arr));
$str = dbesc(implode(',', $arr));
$r = q("SELECT `id` FROM `contact` WHERE `id` IN ( " . $str . ") AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 ");
@ -287,7 +298,7 @@ function prune_deadguys($arr) {
function get_acl_permissions($user = null) {
$allow_cid = $allow_gid = $deny_cid = $deny_gid = false;
if(is_array($user)) {
if (is_array($user)) {
$allow_cid = ((strlen($user['allow_cid']))
? explode('><', $user['allow_cid']) : array() );
$allow_gid = ((strlen($user['allow_gid']))
@ -318,34 +329,36 @@ function populate_acl($user = null, $show_jotnets = false) {
$perms = get_acl_permissions($user);
$jotnets = '';
if($show_jotnets) {
if ($show_jotnets) {
$mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
$mail_enabled = false;
$pubmail_enabled = false;
if(! $mail_disabled) {
if (! $mail_disabled) {
$r = q("SELECT `pubmail` FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1",
intval(local_user())
);
if (dbm::is_result($r)) {
$mail_enabled = true;
if(intval($r[0]['pubmail']))
if (intval($r[0]['pubmail'])) {
$pubmail_enabled = true;
}
}
}
if (!$user['hidewall']) {
if($mail_enabled) {
if ($mail_enabled) {
$selected = (($pubmail_enabled) ? ' checked="checked" ' : '');
$jotnets .= '<div class="profile-jot-net"><input type="checkbox" name="pubmail_enable"' . $selected . ' value="1" /> ' . t("Post to Email") . '</div>';
}
call_hooks('jot_networks', $jotnets);
} else
} else {
$jotnets .= sprintf(t('Connectors disabled, since "%s" is enabled.'),
t('Hide your profile details from unknown viewers?'));
}
}
$tpl = get_markup_template("acl_selector.tpl");
$o = replace_macros($tpl, array(
@ -363,7 +376,7 @@ function populate_acl($user = null, $show_jotnets = false) {
'$aclModalTitle' => t('Permissions'),
'$aclModalDismiss' => t('Close'),
'$features' => array(
"aclautomention"=>(feature_enabled($user['uid'],"aclautomention")?"true":"false")
'aclautomention' => (feature_enabled($user['uid'], "aclautomention") ? "true" : "false")
),
));
@ -379,24 +392,26 @@ function construct_acl_data(App $a, $user) {
$user_defaults = get_acl_permissions($user);
if($acl_data['groups']) {
foreach($acl_data['groups'] as $key=>$group) {
if ($acl_data['groups']) {
foreach ($acl_data['groups'] as $key => $group) {
// Add a "selected" flag to groups that are posted to by default
if($user_defaults['allow_gid'] &&
in_array($group['id'], $user_defaults['allow_gid']) && !in_array($group['id'], $user_defaults['deny_gid']) )
if ($user_defaults['allow_gid'] &&
in_array($group['id'], $user_defaults['allow_gid']) && !in_array($group['id'], $user_defaults['deny_gid']) ) {
$acl_data['groups'][$key]['selected'] = 1;
else
} else {
$acl_data['groups'][$key]['selected'] = 0;
}
}
}
if($acl_data['contacts']) {
foreach($acl_data['contacts'] as $key=>$contact) {
if ($acl_data['contacts']) {
foreach ($acl_data['contacts'] as $key => $contact) {
// Add a "selected" flag to groups that are posted to by default
if($user_defaults['allow_cid'] &&
in_array($contact['id'], $user_defaults['allow_cid']) && !in_array($contact['id'], $user_defaults['deny_cid']) )
if ($user_defaults['allow_cid'] &&
in_array($contact['id'], $user_defaults['allow_cid']) && !in_array($contact['id'], $user_defaults['deny_cid']) ) {
$acl_data['contacts'][$key]['selected'] = 1;
else
} else {
$acl_data['contacts'][$key]['selected'] = 0;
}
}
}
@ -419,23 +434,25 @@ function acl_lookup(App $a, $out_type = 'json') {
// For use with jquery.textcomplete for private mail completion
if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) {
if(! $type)
if (x($_REQUEST, 'query') && strlen($_REQUEST['query'])) {
if (! $type) {
$type = 'm';
}
$search = $_REQUEST['query'];
}
logger("Searching for ".$search." - type ".$type, LOGGER_DEBUG);
if ($search!=""){
if ($search != "") {
$sql_extra = "AND `name` LIKE '%%".dbesc($search)."%%'";
$sql_extra2 = "AND (`attag` LIKE '%%".dbesc($search)."%%' OR `name` LIKE '%%".dbesc($search)."%%' OR `nick` LIKE '%%".dbesc($search)."%%')";
} else {
/// @TODO Avoid these needless else blocks by putting variable-initialization atop of if()
$sql_extra = $sql_extra2 = "";
}
// count groups and contacts
if ($type=='' || $type=='g'){
if ($type == '' || $type == 'g') {
$r = q("SELECT COUNT(*) AS g FROM `group` WHERE `deleted` = 0 AND `uid` = %d $sql_extra",
intval(local_user())
);
@ -446,8 +463,8 @@ function acl_lookup(App $a, $out_type = 'json') {
$sql_extra2 .= " ".unavailable_networks();
// autocomplete for editor mentions
if ($type=='' || $type=='c'){
if ($type == '' || $type == 'c') {
// autocomplete for editor mentions
$r = q("SELECT COUNT(*) AS c FROM `contact`
WHERE `uid` = %d AND NOT `self`
AND NOT `blocked` AND NOT `pending` AND NOT `archive`
@ -493,7 +510,7 @@ function acl_lookup(App $a, $out_type = 'json') {
$groups = array();
$contacts = array();
if ($type=='' || $type=='g'){
if ($type == '' || $type == 'g') {
/// @todo We should cache this query.
// This can be done when we can delete cache entries via wildcard
@ -502,7 +519,7 @@ function acl_lookup(App $a, $out_type = 'json') {
INNER JOIN `group_member` ON `group_member`.`gid`=`group`.`id` AND `group_member`.`uid` = `group`.`uid`
WHERE NOT `group`.`deleted` AND `group`.`uid` = %d
$sql_extra
GROUP BY `group`.`name`
GROUP BY `group`.`name`, `group`.`id`
ORDER BY `group`.`name`
LIMIT %d,%d",
intval(local_user()),
@ -510,7 +527,7 @@ function acl_lookup(App $a, $out_type = 'json') {
intval($count)
);
foreach($r as $g){
foreach ($r as $g) {
// logger('acl: group: ' . $g['name'] . ' members: ' . $g['uids']);
$groups[] = array(
"type" => "g",
@ -524,7 +541,7 @@ function acl_lookup(App $a, $out_type = 'json') {
}
}
if ($type==''){
if ($type == '') {
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `forum`, `prv` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
@ -534,9 +551,7 @@ function acl_lookup(App $a, $out_type = 'json') {
intval(local_user()),
dbesc(NETWORK_OSTATUS), dbesc(NETWORK_STATUSNET)
);
}
elseif ($type=='c'){
} elseif ($type == 'c') {
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `forum`, `prv` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
AND NOT (`network` IN ('%s'))
@ -546,7 +561,7 @@ function acl_lookup(App $a, $out_type = 'json') {
dbesc(NETWORK_STATUSNET)
);
}
elseif($type == 'm') {
elseif ($type == 'm') {
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive`
AND `network` IN ('%s','%s','%s')
@ -593,7 +608,7 @@ function acl_lookup(App $a, $out_type = 'json') {
if (dbm::is_result($r)) {
foreach ($r as $g){
foreach ($r as $g) {
$contacts[] = array(
'type' => 'c',
'photo' => proxy_url($g['micro'], false, PROXY_SIZE_MICRO),
@ -602,7 +617,7 @@ function acl_lookup(App $a, $out_type = 'json') {
'network' => $g['network'],
'link' => $g['url'],
'nick' => htmlentities(($g['attag']) ? $g['attag'] : $g['nick']),
'forum' => ((x($g['forum']) || x($g['prv'])) ? 1 : 0),
'forum' => ((x($g, 'forum') || x($g, 'prv')) ? 1 : 0),
);
}
}
@ -610,46 +625,50 @@ function acl_lookup(App $a, $out_type = 'json') {
$items = array_merge($groups, $contacts);
if ($conv_id) {
/* if $conv_id is set, get unknow contacts in thread */
/* but first get know contacts url to filter them out */
function _contact_link($i){ return dbesc($i['link']); }
$known_contacts = array_map(_contact_link, $contacts);
$unknow_contacts=array();
$r = q("SELECT `author-avatar`,`author-name`,`author-link`
/*
* if $conv_id is set, get unknown contacts in thread
* but first get known contacts url to filter them out
*/
$known_contacts = array_map(
function ($i) {
return dbesc($i['link']);
}
, $contacts);
$unknown_contacts = array();
$r = q("SELECT `author-link`
FROM `item` WHERE `parent` = %d
AND (`author-name` LIKE '%%%s%%' OR `author-link` LIKE '%%%s%%')
AND `author-link` NOT IN ('%s')
GROUP BY `author-link`
GROUP BY `author-link`, `author-avatar`, `author-name`
ORDER BY `author-name` ASC
",
intval($conv_id),
dbesc($search),
dbesc($search),
implode("','", $known_contacts)
implode("', '", $known_contacts)
);
if (dbm::is_result($r)){
if (dbm::is_result($r)) {
foreach ($r as $row) {
// nickname..
$up = parse_url($row['author-link']);
$nick = explode("/",$up['path']);
$nick = $nick[count($nick)-1];
$nick .= "@".$up['host'];
// /nickname
$unknow_contacts[] = array(
'type' => 'c',
'photo' => proxy_url($row['author-avatar'], false, PROXY_SIZE_MICRO),
'name' => htmlentities($row['author-name']),
'id' => '',
'network' => 'unknown',
'link' => $row['author-link'],
'nick' => htmlentities($nick),
'forum' => false
);
$contact = get_contact_details_by_url($row['author-link']);
if (count($contact) > 0) {
$unknown_contacts[] = array(
'type' => 'c',
'photo' => proxy_url($contact['micro'], false, PROXY_SIZE_MICRO),
'name' => htmlentities($contact['name']),
'id' => intval($contact['cid']),
'network' => $contact['network'],
'link' => $contact['url'],
'nick' => htmlentities($contact['nick'] ? : $contact['addr']),
'forum' => $contact['forum']
);
}
}
}
$items = array_merge($items, $unknow_contacts);
$tot += count($unknow_contacts);
$items = array_merge($items, $unknown_contacts);
$tot += count($unknown_contacts);
}
$results = array(
@ -665,7 +684,7 @@ function acl_lookup(App $a, $out_type = 'json') {
call_hooks('acl_lookup_end', $results);
if($out_type === 'html') {
if ($out_type === 'html') {
$o = array(
'tot' => $results['tot'],
'start' => $results['start'],

File diff suppressed because it is too large Load Diff

View File

@ -1060,13 +1060,14 @@ function z_mime_content_type($filename) {
'zsh' => 'text/x-script.zsh',
);
$dot = strpos($filename,'.');
if($dot !== false) {
$ext = strtolower(substr($filename,$dot+1));
$dot = strpos($filename, '.');
if ($dot !== false) {
$ext = strtolower(substr($filename, $dot + 1));
if (array_key_exists($ext, $mime_types)) {
return $mime_types[$ext];
}
}
/// @TODO Then let's get rid of it?
// can't use this because we're just passing a name, e.g. not a file that can be opened
// elseif (function_exists('finfo_open')) {
// $finfo = @finfo_open(FILEINFO_MIME);

View File

@ -1,11 +1,12 @@
<?php
require_once("include/oembed.php");
require_once("include/event.php");
require_once("library/markdown.php");
require_once("include/html2bbcode.php");
require_once("include/bbcode.php");
require_once("library/html-to-markdown/HTML_To_Markdown.php");
use League\HTMLToMarkdown\HtmlConverter;
require_once "include/oembed.php";
require_once "include/event.php";
require_once "library/markdown.php";
require_once "include/html2bbcode.php";
require_once "include/bbcode.php";
/**
* @brief Callback function to replace a Diaspora style mention in a mention for Friendica
@ -26,14 +27,15 @@ function diaspora_mention2bb($match) {
$name = $data['name'];
}
return '@[url='.$data['url'].']'.$name.'[/url]';
return '@[url=' . $data['url'] . ']' . $name . '[/url]';
}
// we don't want to support a bbcode specific markdown interpreter
// and the markdown library we have is pretty good, but provides HTML output.
// So we'll use that to convert to HTML, then convert the HTML back to bbcode,
// and then clean up a few Diaspora specific constructs.
/*
* we don't want to support a bbcode specific markdown interpreter
* and the markdown library we have is pretty good, but provides HTML output.
* So we'll use that to convert to HTML, then convert the HTML back to bbcode,
* and then clean up a few Diaspora specific constructs.
*/
function diaspora2bb($s) {
$s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
@ -92,59 +94,85 @@ function diaspora_mentions($match) {
$contact = get_contact_details_by_url($match[3]);
if (!isset($contact['addr'])) {
if (!x($contact, 'addr')) {
$contact = Probe::uri($match[3]);
}
if (!isset($contact['addr'])) {
if (!x($contact, 'addr')) {
return $match[0];
}
$mention = '@{'.$match[2].'; '.$contact['addr'].'}';
$mention = '@{' . $match[2] . '; ' . $contact['addr'] . '}';
return $mention;
}
function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
/**
* @brief Converts a BBCode text into Markdown
*
* This function converts a BBCode item body to be sent to Markdown-enabled
* systems like Diaspora and Libertree
*
* @param string $Text
* @param bool $preserve_nl Effects unclear, unused in Friendica
* @param bool $fordiaspora Diaspora requires more changes than Libertree
* @return string
*/
function bb2diaspora($Text, $preserve_nl = false, $fordiaspora = true) {
$a = get_app();
$OriginalText = $Text;
// Since Diaspora is creating a summary for links, this function removes them before posting
if ($fordiaspora)
if ($fordiaspora) {
$Text = bb_remove_share_information($Text);
}
/**
* Transform #tags, strip off the [url] and replace spaces with underscore
*/
$URLSearchString = "^\[\]";
$Text = preg_replace_callback("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/i", create_function('$match',
'return \'#\'. str_replace(\' \', \'_\', $match[2]);'
), $Text);
$Text = preg_replace_callback("/#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/i",
function ($matches) {
return '#' . str_replace(' ', '_', $matches[2]);
}
, $Text);
// 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);
// Extracting multi-line code blocks before the whitespace processing/code highlighter in bbcode()
$codeblocks = [];
$Text = preg_replace_callback('#\[code(?:=([^\]]*))?\](?=\n)(.*?)\[\/code\]#is',
function ($matches) use (&$codeblocks) {
$return = '#codeblock-' . count($codeblocks) . '#';
$prefix = '````' . $matches[1] . PHP_EOL;
$codeblocks[] = $prefix . trim($matches[2]) . PHP_EOL . '````';
return $return;
}
, $Text);
// Convert it to HTML - don't try oembed
if ($fordiaspora) {
$Text = bbcode($Text, $preserve_nl, false, 3);
// 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 = "";
foreach($tags[2] as $tag) {
foreach ($tags[2] as $tag) {
$tag = html_entity_decode($tag, ENT_QUOTES, 'UTF-8');
if (!strpos(html_entity_decode($Text, ENT_QUOTES, 'UTF-8'), "#".$tag))
$tagline .= "#".$tag." ";
if (!strpos(html_entity_decode($Text, ENT_QUOTES, 'UTF-8'), '#' . $tag)) {
$tagline .= '#' . $tag . ' ';
}
}
$Text = $Text." ".$tagline;
}
} else
} else {
$Text = bbcode($Text, $preserve_nl, false, 4);
}
// mask some special HTML chars from conversation to markdown
$Text = str_replace(array('&lt;','&gt;','&amp;'),array('&_lt_;','&_gt_;','&_amp_;'),$Text);
$Text = str_replace(array('&lt;', '&gt;', '&amp;'), array('&_lt_;', '&_gt_;', '&_amp_;'), $Text);
// If a link is followed by a quote then there should be a newline before it
// Maybe we should make this newline at every time before a quote.
@ -153,10 +181,11 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
$stamp1 = microtime(true);
// Now convert HTML to Markdown
$Text = new HTML_To_Markdown($Text);
$converter = new HtmlConverter();
$Text = $converter->convert($Text);
// unmask the special chars back to HTML
$Text = str_replace(array('&_lt_;','&_gt_;','&_amp_;'),array('&lt;','&gt;','&amp;'),$Text);
$Text = str_replace(array('&_lt_;', '&_gt_;', '&_amp_;'), array('&lt;', '&gt;', '&amp;'), $Text);
$a->save_timestamp($stamp1, "parser");
@ -172,20 +201,31 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
$Text = preg_replace_callback("/([@]\[(.*?)\])\(([$URLSearchString]*?)\)/ism", 'diaspora_mentions', $Text);
}
// Restore code blocks
$Text = preg_replace_callback('/#codeblock-([0-9]+)#/iU',
function ($matches) use ($codeblocks) {
$return = '';
if (isset($codeblocks[intval($matches[1])])) {
$return = $codeblocks[$matches[1]];
}
return $return;
}
, $Text);
call_hooks('bb2diaspora',$Text);
return $Text;
}
function unescape_underscores_in_links($m) {
$y = str_replace('\\_','_', $m[2]);
$y = str_replace('\\_', '_', $m[2]);
return('[' . $m[1] . '](' . $y . ')');
}
function format_event_diaspora($ev) {
if(! ((is_array($ev)) && count($ev)))
if (! ((is_array($ev)) && count($ev))) {
return '';
}
$bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM
@ -200,17 +240,19 @@ function format_event_diaspora($ev) {
$ev['start'] , $bd_format)))
. '](' . App::get_baseurl() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n";
if(! $ev['nofinish'])
if (! $ev['nofinish']) {
$o .= t('Finishes:') . ' ' . '['
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format )))
. '](' . App::get_baseurl() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n";
}
if(strlen($ev['location']))
if (strlen($ev['location'])) {
$o .= t('Location:') . bb2diaspora($ev['location'])
. "\n";
}
$o .= "\n";
return $o;

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ function cli_startup() {
require_once("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');

View File

@ -9,12 +9,12 @@ function contact_profile_assign($current,$foreign_net) {
$o .= "<select id=\"contact-profile-selector\" class=\"form-control\" $disabled name=\"profile-assign\" />\r\n";
$r = q("SELECT `id`, `profile-name` FROM `profile` WHERE `uid` = %d",
$r = q("SELECT `id`, `profile-name`, `is-default` FROM `profile` WHERE `uid` = %d",
intval($_SESSION['uid']));
if (dbm::is_result($r)) {
foreach ($r as $rr) {
$selected = (($rr['id'] == $current) ? " selected=\"selected\" " : "");
$selected = (($rr['id'] == $current || ($current == 0 && $rr['is-default'] == 1)) ? " selected=\"selected\" " : "");
$o .= "<option value=\"{$rr['id']}\" $selected >{$rr['profile-name']}</option>\r\n";
}
}
@ -37,7 +37,7 @@ function contact_reputation($current) {
5 => t('Reputable, has my trust')
);
foreach($rep as $k => $v) {
foreach ($rep as $k => $v) {
$selected = (($k == $current) ? " selected=\"selected\" " : "");
$o .= "<option value=\"$k\" $selected >$v</option>\r\n";
}
@ -61,7 +61,7 @@ function contact_poll_interval($current, $disabled = false) {
5 => t('Monthly')
);
foreach($rep as $k => $v) {
foreach ($rep as $k => $v) {
$selected = (($k == $current) ? " selected=\"selected\" " : "");
$o .= "<option value=\"$k\" $selected >$v</option>\r\n";
}

View File

@ -2,7 +2,7 @@
function follow_widget($value = "") {
return replace_macros(get_markup_template('follow.tpl'),array(
return replace_macros(get_markup_template('follow.tpl'), array(
'$connect' => t('Add New Contact'),
'$desc' => t('Enter address or web location'),
'$hint' => t('Example: bob@example.com, http://example.com/barbara'),
@ -13,20 +13,20 @@ function follow_widget($value = "") {
}
function findpeople_widget() {
require_once('include/Contact.php');
require_once 'include/Contact.php';
$a = get_app();
if(get_config('system','invitation_only')) {
$x = get_pconfig(local_user(),'system','invites_remaining');
if($x || is_site_admin()) {
if (get_config('system', 'invitation_only')) {
$x = get_pconfig(local_user(), 'system', 'invites_remaining');
if ($x || is_site_admin()) {
$a->page['aside'] .= '<div class="side-link" id="side-invite-remain">'
. sprintf( tt('%d invitation available','%d invitations available',$x), $x)
. sprintf( tt('%d invitation available', '%d invitations available', $x), $x)
. '</div>' . $inv;
}
}
return replace_macros(get_markup_template('peoplefind.tpl'),array(
return replace_macros(get_markup_template('peoplefind.tpl'), array(
'$findpeople' => t('Find People'),
'$desc' => t('Enter name or interest'),
'$label' => t('Connect/Follow'),
@ -45,32 +45,41 @@ function unavailable_networks() {
$networks = array();
if (!plugin_enabled("appnet"))
if (!plugin_enabled("appnet")) {
$networks[] = NETWORK_APPNET;
}
if (!plugin_enabled("fbpost") AND !plugin_enabled("facebook"))
if (!plugin_enabled("fbpost") AND !plugin_enabled("facebook")) {
$networks[] = NETWORK_FACEBOOK;
}
if (!plugin_enabled("statusnet"))
if (!plugin_enabled("statusnet")) {
$networks[] = NETWORK_STATUSNET;
}
if (!plugin_enabled("pumpio"))
if (!plugin_enabled("pumpio")) {
$networks[] = NETWORK_PUMPIO;
}
if (!plugin_enabled("twitter"))
if (!plugin_enabled("twitter")) {
$networks[] = NETWORK_TWITTER;
}
if (get_config("system","ostatus_disabled"))
if (get_config("system", "ostatus_disabled")) {
$networks[] = NETWORK_OSTATUS;
}
if (!get_config("system","diaspora_enabled"))
if (!get_config("system", "diaspora_enabled")) {
$networks[] = NETWORK_DIASPORA;
}
if (!plugin_enabled("pnut"))
if (!plugin_enabled("pnut")) {
$networks[] = NETWORK_PNUT;
}
if (!sizeof($networks))
if (!sizeof($networks)) {
return "";
}
$network_filter = implode("','", $networks);
@ -79,7 +88,7 @@ function unavailable_networks() {
return $network_filter;
}
function networks_widget($baseurl,$selected = '') {
function networks_widget($baseurl, $selected = '') {
$a = get_app();
@ -87,7 +96,7 @@ function networks_widget($baseurl,$selected = '') {
return '';
}
if (!feature_enabled(local_user(),'networks')) {
if (!feature_enabled(local_user(), 'networks')) {
return '';
}
@ -99,7 +108,7 @@ function networks_widget($baseurl,$selected = '') {
$nets = array();
if (dbm::is_result($r)) {
require_once('include/contact_selectors.php');
require_once 'include/contact_selectors.php';
foreach ($r as $rr) {
/// @TODO If 'network' is not there, this triggers an E_NOTICE
if ($rr['network']) {
@ -108,10 +117,11 @@ function networks_widget($baseurl,$selected = '') {
}
}
if(count($nets) < 2)
if (count($nets) < 2) {
return '';
}
return replace_macros(get_markup_template('nets.tpl'),array(
return replace_macros(get_markup_template('nets.tpl'), array(
'$title' => t('Networks'),
'$desc' => '',
'$sel_all' => (($selected == '') ? 'selected' : ''),
@ -122,31 +132,31 @@ function networks_widget($baseurl,$selected = '') {
));
}
function fileas_widget($baseurl,$selected = '') {
function fileas_widget($baseurl, $selected = '') {
if (! local_user()) {
return '';
}
if (! feature_enabled(local_user(),'filing')) {
if (! feature_enabled(local_user(), 'filing')) {
return '';
}
$saved = get_pconfig(local_user(),'system','filetags');
$saved = get_pconfig(local_user(), 'system', 'filetags');
if (! strlen($saved)) {
return;
}
$matches = false;
$terms = array();
$cnt = preg_match_all('/\[(.*?)\]/',$saved,$matches,PREG_SET_ORDER);
$cnt = preg_match_all('/\[(.*?)\]/', $saved, $matches, PREG_SET_ORDER);
if ($cnt) {
foreach($matches as $mtch) {
foreach ($matches as $mtch) {
$unescaped = xmlify(file_tag_decode($mtch[1]));
$terms[] = array('name' => $unescaped,'selected' => (($selected == $unescaped) ? 'selected' : ''));
$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
}
}
return replace_macros(get_markup_template('fileas_widget.tpl'),array(
return replace_macros(get_markup_template('fileas_widget.tpl'), array(
'$title' => t('Saved Folders'),
'$desc' => '',
'$sel_all' => (($selected == '') ? 'selected' : ''),
@ -157,30 +167,31 @@ function fileas_widget($baseurl,$selected = '') {
));
}
function categories_widget($baseurl,$selected = '') {
function categories_widget($baseurl, $selected = '') {
$a = get_app();
if (! feature_enabled($a->profile['profile_uid'],'categories')) {
if (! feature_enabled($a->profile['profile_uid'], 'categories')) {
return '';
}
$saved = get_pconfig($a->profile['profile_uid'],'system','filetags');
$saved = get_pconfig($a->profile['profile_uid'], 'system', 'filetags');
if (! strlen($saved)) {
return;
}
$matches = false;
$terms = array();
$cnt = preg_match_all('/<(.*?)>/',$saved,$matches,PREG_SET_ORDER);
if($cnt) {
foreach($matches as $mtch) {
$unescaped = xmlify(file_tag_decode($mtch[1]));
$terms[] = array('name' => $unescaped,'selected' => (($selected == $unescaped) ? 'selected' : ''));
$cnt = preg_match_all('/<(.*?)>/', $saved, $matches, PREG_SET_ORDER);
if ($cnt) {
foreach ($matches as $mtch) {
$unescaped = xmlify(file_tag_decode($mtch[1]));
$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
}
}
return replace_macros(get_markup_template('categories_widget.tpl'),array(
return replace_macros(get_markup_template('categories_widget.tpl'), array(
'$title' => t('Categories'),
'$desc' => '',
'$sel_all' => (($selected == '') ? 'selected' : ''),
@ -195,29 +206,30 @@ function common_friends_visitor_widget($profile_uid) {
$a = get_app();
if(local_user() == $profile_uid)
if (local_user() == $profile_uid) {
return;
}
$cid = $zcid = 0;
if(is_array($_SESSION['remote'])) {
foreach($_SESSION['remote'] as $visitor) {
if($visitor['uid'] == $profile_uid) {
if (is_array($_SESSION['remote'])) {
foreach ($_SESSION['remote'] as $visitor) {
if ($visitor['uid'] == $profile_uid) {
$cid = $visitor['cid'];
break;
}
}
}
if(! $cid) {
if(get_my_url()) {
if (! $cid) {
if (get_my_url()) {
$r = q("select id from contact where nurl = '%s' and uid = %d limit 1",
dbesc(normalise_link(get_my_url())),
intval($profile_uid)
);
if (dbm::is_result($r))
if (dbm::is_result($r)) {
$cid = $r[0]['id'];
else {
} else {
$r = q("select id from gcontact where nurl = '%s' limit 1",
dbesc(normalise_link(get_my_url()))
);
@ -227,22 +239,26 @@ function common_friends_visitor_widget($profile_uid) {
}
}
if($cid == 0 && $zcid == 0)
if ($cid == 0 && $zcid == 0) {
return;
}
require_once('include/socgraph.php');
require_once 'include/socgraph.php';
if($cid)
$t = count_common_friends($profile_uid,$cid);
else
$t = count_common_friends_zcid($profile_uid,$zcid);
if(! $t)
if ($cid) {
$t = count_common_friends($profile_uid, $cid);
} else {
$t = count_common_friends_zcid($profile_uid, $zcid);
}
if (! $t) {
return;
}
if($cid)
$r = common_friends($profile_uid,$cid,0,5,true);
else
$r = common_friends_zcid($profile_uid,$zcid,0,5,true);
if ($cid) {
$r = common_friends($profile_uid, $cid, 0, 5, true);
} else {
$r = common_friends_zcid($profile_uid, $zcid, 0, 5, true);
}
return replace_macros(get_markup_template('remote_friends_common.tpl'), array(
'$desc' => sprintf( tt("%d contact in common", "%d contacts in common", $t), $t),

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ use \Friendica\Core\Config;
function cron_run(&$argv, &$argc){
global $a;
require_once('include/datetime.php');
require_once 'include/datetime.php';
// Poll contacts with specific parameters
if ($argc > 1) {
@ -12,15 +12,16 @@ function cron_run(&$argv, &$argc){
return;
}
$last = get_config('system','last_cron');
$last = get_config('system', 'last_cron');
$poll_interval = intval(get_config('system','cron_interval'));
$poll_interval = intval(get_config('system', 'cron_interval'));
if (! $poll_interval) {
$poll_interval = 10;
}
if ($last) {
$next = $last + ($poll_interval * 60);
if($next > time()) {
if ($next > time()) {
logger('cron intervall not reached');
return;
}
@ -62,10 +63,10 @@ function cron_run(&$argv, &$argc){
proc_run(PRIORITY_LOW, "include/cronjobs.php", "repair_database");
// 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'));
$d1 = get_config('system', 'last_expire_day');
$d2 = intval(datetime_convert('UTC', 'UTC', 'now', 'd'));
if($d2 != intval($d1)) {
if ($d2 != intval($d1)) {
proc_run(PRIORITY_LOW, "include/cronjobs.php", "update_contact_birthdays");
@ -73,7 +74,7 @@ function cron_run(&$argv, &$argc){
proc_run(PRIORITY_LOW, "include/discover_poco.php", "suggestions");
set_config('system','last_expire_day',$d2);
set_config('system', 'last_expire_day', $d2);
proc_run(PRIORITY_LOW, 'include/expire.php');
@ -87,7 +88,7 @@ function cron_run(&$argv, &$argc){
logger('cron: end');
set_config('system','last_cron', time());
set_config('system', 'last_cron', time());
return;
}
@ -130,7 +131,7 @@ function cron_poll_contacts($argc, $argv) {
// 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_days = intval(get_config('system','account_abandon_days'));
$abandon_days = intval(get_config('system', 'account_abandon_days'));
if ($abandon_days < 1) {
$abandon_days = 0;
}
@ -156,7 +157,7 @@ function cron_poll_contacts($argc, $argv) {
dbesc(NETWORK_MAIL2)
);
if (!count($contacts)) {
if (!dbm::is_result($contacts)) {
return;
}
@ -170,7 +171,7 @@ function cron_poll_contacts($argc, $argv) {
continue;
}
foreach($res as $contact) {
foreach ($res as $contact) {
$xml = false;
@ -183,49 +184,48 @@ function cron_poll_contacts($argc, $argv) {
}
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');
/*
* 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;
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")) {
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")) {
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")) {
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")) {
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")) {
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 hour")) {
$update = true;
}
break;
@ -235,7 +235,7 @@ function cron_poll_contacts($argc, $argv) {
}
}
logger("Polling ".$contact["network"]." ".$contact["id"]." ".$contact["nick"]." ".$contact["name"]);
logger("Polling " . $contact["network"] . " " . $contact["id"] . " " . $contact["nick"] . " " . $contact["name"]);
if (($contact['network'] == NETWORK_FEED) AND ($contact['priority'] <= 3)) {
proc_run(PRIORITY_MEDIUM, 'include/onepoll.php', intval($contact['id']));

View File

@ -2,43 +2,45 @@
use \Friendica\Core\Config;
function cronhooks_run(&$argv, &$argc){
function cronhooks_run(&$argv, &$argc) {
global $a;
require_once('include/datetime.php');
require_once 'include/datetime.php';
if (($argc == 2) AND is_array($a->hooks) AND array_key_exists("cron", $a->hooks)) {
foreach ($a->hooks["cron"] as $hook)
foreach ($a->hooks["cron"] as $hook) {
if ($hook[1] == $argv[1]) {
logger("Calling cron hook '".$hook[1]."'", LOGGER_DEBUG);
logger("Calling cron hook '" . $hook[1] . "'", LOGGER_DEBUG);
call_single_hook($a, $name, $hook, $data);
}
}
return;
}
$last = get_config('system', 'last_cronhook');
$poll_interval = intval(get_config('system','cronhook_interval'));
if(! $poll_interval)
$poll_interval = intval(get_config('system', 'cronhook_interval'));
if (! $poll_interval) {
$poll_interval = 9;
}
if($last) {
if ($last) {
$next = $last + ($poll_interval * 60);
if($next > time()) {
if ($next > time()) {
logger('cronhook intervall not reached');
return;
}
}
$a->set_baseurl(get_config('system','url'));
$a->set_baseurl(get_config('system', 'url'));
logger('cronhooks: start');
$d = datetime_convert();
if (is_array($a->hooks) AND array_key_exists("cron", $a->hooks)) {
foreach ($a->hooks["cron"] as $hook) {
logger("Calling cronhooks for '".$hook[1]."'", LOGGER_DEBUG);
foreach ($a->hooks["cron"] as $hook) {
logger("Calling cronhooks for '" . $hook[1] . "'", LOGGER_DEBUG);
proc_run(PRIORITY_MEDIUM, "include/cronhooks.php", $hook[1]);
}
}

View File

@ -14,13 +14,20 @@ use \Friendica\Core\Config;
* @return int
*/
function timezone_cmp($a, $b) {
if(strstr($a,'/') && strstr($b,'/')) {
if ( t($a) == t($b)) return 0;
if (strstr($a, '/') && strstr($b, '/')) {
if ( t($a) == t($b)) {
return 0;
}
return ( t($a) < t($b)) ? -1 : 1;
}
if(strstr($a,'/')) return -1;
if(strstr($b,'/')) return 1;
if ( t($a) == t($b)) return 0;
if (strstr($a, '/')) {
return -1;
} elseif (strstr($b, '/')) {
return 1;
} elseif ( t($a) == t($b)) {
return 0;
}
return ( t($a) < t($b)) ? -1 : 1;
}
@ -39,23 +46,24 @@ function select_timezone($current = 'America/Los_Angeles') {
usort($timezone_identifiers, 'timezone_cmp');
$continent = '';
foreach($timezone_identifiers as $value) {
foreach ($timezone_identifiers as $value) {
$ex = explode("/", $value);
if(count($ex) > 1) {
if($ex[0] != $continent) {
if($continent != '')
if (count($ex) > 1) {
if ($ex[0] != $continent) {
if ($continent != '') {
$o .= '</optgroup>';
}
$continent = $ex[0];
$o .= '<optgroup label="' . t($continent) . '">';
}
if(count($ex) > 2)
if (count($ex) > 2) {
$city = substr($value,strpos($value,'/')+1);
else
} else {
$city = $ex[1];
}
else {
}
} else {
$city = $ex[0];
if($continent != t('Miscellaneous')) {
if ($continent != t('Miscellaneous')) {
$o .= '</optgroup>';
$continent = t('Miscellaneous');
$o .= '<optgroup label="' . t($continent) . '">';
@ -114,48 +122,50 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
// Defaults to UTC if nothing is set, but throws an exception if set to empty string.
// Provide some sane defaults regardless.
if($from === '')
if ($from === '') {
$from = 'UTC';
if($to === '')
}
if ($to === '') {
$to = 'UTC';
if( ($s === '') || (! is_string($s)) )
}
if ( ($s === '') || (! is_string($s)) ) {
$s = 'now';
}
// Slight hackish adjustment so that 'zero' datetime actually returns what is intended
// otherwise we end up with -0001-11-30 ...
// add 32 days so that we at least get year 00, and then hack around the fact that
// months and days always start with 1.
/*
* Slight hackish adjustment so that 'zero' datetime actually returns what is intended
* otherwise we end up with -0001-11-30 ...
* add 32 days so that we at least get year 00, and then hack around the fact that
* months and days always start with 1.
*/
if(substr($s,0,10) == '0000-00-00') {
if (substr($s,0,10) <= '0001-01-01') {
$d = new DateTime($s . ' + 32 days', new DateTimeZone('UTC'));
return str_replace('1','0',$d->format($fmt));
}
try {
$from_obj = new DateTimeZone($from);
}
catch(Exception $e) {
} catch (Exception $e) {
$from_obj = new DateTimeZone('UTC');
}
try {
$d = new DateTime($s, $from_obj);
}
catch(Exception $e) {
} catch (Exception $e) {
logger('datetime_convert: exception: ' . $e->getMessage());
$d = new DateTime('now', $from_obj);
}
try {
$to_obj = new DateTimeZone($to);
}
catch(Exception $e) {
} catch (Exception $e) {
$to_obj = new DateTimeZone('UTC');
}
$d->setTimeZone($to_obj);
return($d->format($fmt));
return $d->format($fmt);
}
@ -169,12 +179,14 @@ function dob($dob) {
list($year,$month,$day) = sscanf($dob,'%4d-%2d-%2d');
$f = get_config('system','birthday_input_format');
if(! $f)
if (! $f) {
$f = 'ymd';
if($dob === '0000-00-00')
}
if ($dob <= '0001-01-01') {
$value = '';
else
} else {
$value = (($year) ? datetime_convert('UTC','UTC',$dob,'Y-m-d') : datetime_convert('UTC','UTC',$dob,'m-d'));
}
$age = ((intval($value)) ? age($value, $a->user["timezone"], $a->user["timezone"]) : "");
@ -189,7 +201,8 @@ function dob($dob) {
)
));
// if ($dob && $dob != '0000-00-00')
/// @TODO Old-lost code?
// if ($dob && $dob > '0001-01-01')
// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),mktime(0,0,0,$month,$day,$year),'dob');
// else
// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),false,'dob');
@ -214,7 +227,7 @@ function dob($dob) {
* @return string Parsed HTML output.
*/
function datesel($format, $min, $max, $default, $id = 'datepicker') {
return datetimesel($format,$min,$max,$default,'',$id,true,false, '','');
return datetimesel($format, $min, $max, $default, '', $id, true, false, '', '');
}
/**
@ -231,8 +244,8 @@ function datesel($format, $min, $max, $default, $id = 'datepicker') {
*
* @return string Parsed HTML output.
*/
function timesel($format, $h, $m, $id='timepicker') {
return datetimesel($format,new DateTime(),new DateTime(),new DateTime("$h:$m"),'',$id,false,true);
function timesel($format, $h, $m, $id = 'timepicker') {
return datetimesel($format, new DateTime(), new DateTime(), new DateTime("$h:$m"), '', $id, false, true);
}
/**
@ -267,7 +280,9 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke
// First day of the week (0 = Sunday)
$firstDay = get_pconfig(local_user(),'system','first_day_of_week');
if ($firstDay === false) $firstDay=0;
if ($firstDay === false) {
$firstDay=0;
}
$lang = substr(get_browser_language(), 0, 2);
@ -279,9 +294,15 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke
$o = '';
$dateformat = '';
if($pickdate) $dateformat .= 'Y-m-d';
if($pickdate && $picktime) $dateformat .= ' ';
if($picktime) $dateformat .= 'H:i';
if ($pickdate) {
$dateformat .= 'Y-m-d';
}
if ($pickdate && $picktime) {
$dateformat .= ' ';
}
if ($picktime) {
$dateformat .= 'H:i';
}
$minjs = $min ? ",minDate: new Date({$min->getTimestamp()}*1000), yearStart: " . $min->format('Y') : '';
$maxjs = $max ? ",maxDate: new Date({$max->getTimestamp()}*1000), yearEnd: " . $max->format('Y') : '';
@ -290,15 +311,21 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke
$defaultdatejs = $default ? ",defaultDate: new Date({$default->getTimestamp()}*1000)" : '';
$pickers = '';
if(!$pickdate) $pickers .= ',datepicker: false';
if(!$picktime) $pickers .= ',timepicker: false';
if (!$pickdate) {
$pickers .= ',datepicker: false';
}
if (!$picktime) {
$pickers .= ',timepicker: false';
}
$extra_js = '';
$pickers .= ",dayOfWeekStart: ".$firstDay.",lang:'".$lang."'";
if($minfrom != '')
if ($minfrom != '') {
$extra_js .= "\$('#id_$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})";
if($maxfrom != '')
}
if ($maxfrom != '') {
$extra_js .= "\$('#id_$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#id_$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})";
}
$readable_format = $dateformat;
$readable_format = str_replace('Y','yyyy',$readable_format);
@ -393,13 +420,16 @@ function relative_date($posted_date, $format = null) {
*
* @return int Age in years
*/
function age($dob,$owner_tz = '',$viewer_tz = '') {
if(! intval($dob))
function age($dob, $owner_tz = '', $viewer_tz = '') {
if (! intval($dob)) {
return 0;
if(! $owner_tz)
}
if (! $owner_tz) {
$owner_tz = date_default_timezone_get();
if(! $viewer_tz)
}
if (! $viewer_tz) {
$viewer_tz = date_default_timezone_get();
}
$birthdate = datetime_convert('UTC',$owner_tz,$dob . ' 00:00:00+00:00','Y-m-d');
list($year,$month,$day) = explode("-",$birthdate);
@ -407,8 +437,9 @@ function age($dob,$owner_tz = '',$viewer_tz = '') {
$curr_month = datetime_convert('UTC',$viewer_tz,'now','m');
$curr_day = datetime_convert('UTC',$viewer_tz,'now','d');
if(($curr_month < $month) || (($curr_month == $month) && ($curr_day < $day)))
if (($curr_month < $month) || (($curr_month == $month) && ($curr_day < $day))) {
$year_diff--;
}
return $year_diff;
}
@ -430,11 +461,11 @@ function get_dim($y,$m) {
31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31);
if($m != 2)
if ($m != 2) {
return $dim[$m];
if(((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0))
} elseif (((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0)) {
return 29;
}
return $dim[2];
}
@ -473,8 +504,6 @@ function get_first_dim($y,$m) {
* @todo Provide (prev,next) links, define class variations for different size calendars
*/
function cal($y = 0,$m = 0, $links = false, $class='') {
// month table - start at 1 to match human usage.
$mtab = array(' ',
@ -486,10 +515,12 @@ function cal($y = 0,$m = 0, $links = false, $class='') {
$thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
$thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m');
if(! $y)
if (! $y) {
$y = $thisyear;
if(! $m)
}
if (! $m) {
$m = intval($thismonth);
}
$dn = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
$f = get_first_dim($y,$m);
@ -498,29 +529,33 @@ function cal($y = 0,$m = 0, $links = false, $class='') {
$dow = 0;
$started = false;
if(($y == $thisyear) && ($m == $thismonth))
if (($y == $thisyear) && ($m == $thismonth)) {
$tddate = intval(datetime_convert('UTC',date_default_timezone_get(),'now','j'));
}
$str_month = day_translate($mtab[$m]);
$o = '<table class="calendar' . $class . '">';
$o .= "<caption>$str_month $y</caption><tr>";
for($a = 0; $a < 7; $a ++)
for ($a = 0; $a < 7; $a ++) {
$o .= '<th>' . mb_substr(day_translate($dn[$a]),0,3,'UTF-8') . '</th>';
}
$o .= '</tr><tr>';
while($d <= $l) {
if(($dow == $f) && (! $started))
while ($d <= $l) {
if (($dow == $f) && (! $started)) {
$started = true;
}
$today = (((isset($tddate)) && ($tddate == $d)) ? "class=\"today\" " : '');
$o .= "<td $today>";
$day = str_replace(' ','&nbsp;',sprintf('%2.2d', $d));
if($started) {
if(is_array($links) && isset($links[$d]))
if ($started) {
if (is_array($links) && isset($links[$d])) {
$o .= "<a href=\"{$links[$d]}\">$day</a>";
else
} else {
$o .= $day;
}
$d ++;
} else {
@ -529,14 +564,16 @@ function cal($y = 0,$m = 0, $links = false, $class='') {
$o .= '</td>';
$dow ++;
if(($dow == 7) && ($d <= $l)) {
if (($dow == 7) && ($d <= $l)) {
$dow = 0;
$o .= '</tr><tr>';
}
}
if($dow)
for($a = $dow; $a < 7; $a ++)
if ($dow) {
for ($a = $dow; $a < 7; $a ++) {
$o .= '<td>&nbsp;</td>';
}
}
$o .= '</tr></table>'."\r\n";
@ -553,7 +590,7 @@ function update_contact_birthdays() {
// This only handles foreign or alien networks where a birthday has been provided.
// In-network birthdays are handled within local_delivery
$r = q("SELECT * FROM contact WHERE `bd` != '' AND `bd` != '0000-00-00' AND SUBSTRING(`bd`,1,4) != `bdyear` ");
$r = q("SELECT * FROM contact WHERE `bd` != '' AND `bd` > '0001-01-01' AND SUBSTRING(`bd`,1,4) != `bdyear` ");
if (dbm::is_result($r)) {
foreach ($r as $rr) {

View File

@ -20,6 +20,7 @@ class dba {
private $driver;
public $connected = false;
public $error = false;
private $_server_info = '';
function __construct($server, $user, $pass, $db, $install = false) {
$a = get_app();
@ -103,18 +104,20 @@ class dba {
* @return string
*/
public function server_info() {
switch ($this->driver) {
case 'pdo':
$version = $this->db->getAttribute(PDO::ATTR_SERVER_VERSION);
break;
case 'mysqli':
$version = $this->db->server_info;
break;
case 'mysql':
$version = mysql_get_server_info($this->db);
break;
if ($this->_server_info == '') {
switch ($this->driver) {
case 'pdo':
$this->_server_info = $this->db->getAttribute(PDO::ATTR_SERVER_VERSION);
break;
case 'mysqli':
$this->_server_info = $this->db->server_info;
break;
case 'mysql':
$this->_server_info = mysql_get_server_info($this->db);
break;
}
}
return $version;
return $this->_server_info;
}
/**
@ -474,6 +477,26 @@ class dba {
}
}
}
/**
* @brief Replaces ANY_VALUE() function by MIN() function,
* if the database server does not support ANY_VALUE().
*
* Considerations for Standard SQL, or MySQL with ONLY_FULL_GROUP_BY (default since 5.7.5).
* ANY_VALUE() is available from MySQL 5.7.5 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html
* A standard fall-back is to use MIN().
*
* @param string $sql An SQL string without the values
* @return string The input SQL string modified if necessary.
*/
public function any_value_fallback($sql) {
$server_info = $this->server_info();
if (version_compare($server_info, '5.7.5', '<') ||
(stripos($server_info, 'MariaDB') !== false)) {
$sql = str_ireplace('ANY_VALUE(', 'MIN(', $sql);
}
return $sql;
}
}
function printable($s) {
@ -514,6 +537,7 @@ function q($sql) {
unset($args[0]);
if ($db && $db->connected) {
$sql = $db->any_value_fallback($sql);
$stmt = @vsprintf($sql,$args); // Disabled warnings
//logger("dba: q: $stmt", LOGGER_ALL);
if ($stmt === false)
@ -550,6 +574,7 @@ function qu($sql) {
unset($args[0]);
if ($db && $db->connected) {
$sql = $db->any_value_fallback($sql);
$stmt = @vsprintf($sql,$args); // Disabled warnings
if ($stmt === false)
logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG);

View File

@ -34,7 +34,7 @@ $objDDDBLResultHandler->add('PDOStatement', array('HANDLER' => $cloPDOStatementR
*
*/
if(! class_exists('dba')) {
if (! class_exists('dba')) {
class dba {
private $debug = 0;
@ -66,9 +66,9 @@ class dba {
return;
}
if($install) {
if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
if(! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
if ($install) {
if (strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
if (! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
$this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
$this->connected = false;
$this->db = null;
@ -81,13 +81,13 @@ class dba {
\DDDBL\connect();
$this->db = \DDDBL\getDB();
if(\DDDBL\isConnected()) {
if (\DDDBL\isConnected()) {
$this->connected = true;
}
if(! $this->connected) {
if (! $this->connected) {
$this->db = null;
if(! $install)
if (! $install)
system_unavailable();
}
@ -109,11 +109,11 @@ class dba {
$objPreparedQueryPool = new \DDDBL\DataObjectPool('Query-Definition');
# check if query do not exists till now, if so create its definition
if(!$objPreparedQueryPool->exists($strQueryAlias))
if (!$objPreparedQueryPool->exists($strQueryAlias))
$objPreparedQueryPool->add($strQueryAlias, array('QUERY' => $sql,
'HANDLER' => $strHandler));
if((! $this->db) || (! $this->connected))
if ((! $this->db) || (! $this->connected))
return false;
$this->error = '';
@ -124,7 +124,7 @@ class dba {
$r = \DDDBL\get($strQueryAlias);
# bad workaround to emulate the bizzare behavior of mysql_query
if(in_array($strSQLType, array('INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'SET')))
if (in_array($strSQLType, array('INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'SET')))
$result = true;
$intErrorCode = false;
@ -138,7 +138,7 @@ class dba {
$a->save_timestamp($stamp1, "database");
if(x($a->config,'system') && x($a->config['system'],'db_log')) {
if (x($a->config,'system') && x($a->config['system'],'db_log')) {
if (($duration > $a->config["system"]["db_loglimit"])) {
$duration = round($duration, 3);
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
@ -149,20 +149,20 @@ class dba {
}
}
if($intErrorCode)
if ($intErrorCode)
$this->error = $intErrorCode;
if(strlen($this->error)) {
if (strlen($this->error)) {
logger('dba: ' . $this->error);
}
if($this->debug) {
if ($this->debug) {
$mesg = '';
if($result === false)
if ($result === false)
$mesg = 'false';
elseif($result === true)
elseif ($result === true)
$mesg = 'true';
else {
# this needs fixing, but is a bug itself
@ -182,13 +182,13 @@ class dba {
* These usually indicate SQL syntax errors that need to be resolved.
*/
if(isset($result) AND ($result === false)) {
if (isset($result) AND ($result === false)) {
logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error);
if(file_exists('dbfail.out'))
if (file_exists('dbfail.out'))
file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND);
}
if(isset($result) AND (($result === true) || ($result === false)))
if (isset($result) AND (($result === true) || ($result === false)))
return $result;
if ($onlyquery) {
@ -199,7 +199,7 @@ class dba {
//$a->save_timestamp($stamp1, "database");
if($this->debug)
if ($this->debug)
logger('dba: ' . printable(print_r($r, true)));
return($r);
}
@ -223,7 +223,7 @@ class dba {
}
public function escape($str) {
if($this->db && $this->connected) {
if ($this->db && $this->connected) {
$strQuoted = $this->db->quote($str);
# this workaround is needed, because quote creates "'" and the beginning and the end
# of the string, which is correct. but until now the queries set this delimiter manually,
@ -238,27 +238,27 @@ class dba {
}
}}
if(! function_exists('printable')) {
if (! function_exists('printable')) {
function printable($s) {
$s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s);
$s = str_replace("\x00",'.',$s);
if(x($_SERVER,'SERVER_NAME'))
if (x($_SERVER,'SERVER_NAME'))
$s = escape_tags($s);
return $s;
}}
// Procedural functions
if(! function_exists('dbg')) {
if (! function_exists('dbg')) {
function dbg($state) {
global $db;
if($db)
if ($db)
$db->dbg($state);
}}
if(! function_exists('dbesc')) {
if (! function_exists('dbesc')) {
function dbesc($str) {
global $db;
if($db && $db->connected)
if ($db && $db->connected)
return($db->escape($str));
else
return(str_replace("'","\\'",$str));
@ -271,17 +271,17 @@ function dbesc($str) {
// Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
// 'user', 1);
if(! function_exists('q')) {
if (! function_exists('q')) {
function q($sql) {
global $db;
$args = func_get_args();
unset($args[0]);
if($db && $db->connected) {
if ($db && $db->connected) {
$stmt = @vsprintf($sql,$args); // Disabled warnings
//logger("dba: q: $stmt", LOGGER_ALL);
if($stmt === false)
if ($stmt === false)
logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG);
return $db->q($stmt);
}
@ -303,11 +303,11 @@ function q($sql) {
*
*/
if(! function_exists('dbq')) {
if (! function_exists('dbq')) {
function dbq($sql) {
global $db;
if($db && $db->connected)
if ($db && $db->connected)
$ret = $db->q($sql);
else
$ret = false;
@ -321,21 +321,21 @@ function dbq($sql) {
// cast to int to avoid trouble.
if(! function_exists('dbesc_array_cb')) {
if (! function_exists('dbesc_array_cb')) {
function dbesc_array_cb(&$item, $key) {
if(is_string($item))
if (is_string($item))
$item = dbesc($item);
}}
if(! function_exists('dbesc_array')) {
if (! function_exists('dbesc_array')) {
function dbesc_array(&$arr) {
if(is_array($arr) && count($arr)) {
if (is_array($arr) && count($arr)) {
array_walk($arr,'dbesc_array_cb');
}
}}
if(! function_exists('dba_timer')) {
if (! function_exists('dba_timer')) {
function dba_timer() {
return microtime(true);
}}

View File

@ -78,8 +78,18 @@ function update_fail($update_id, $error_message){
function table_structure($table) {
$structures = q("DESCRIBE `%s`", $table);
$full_columns = q("SHOW FULL COLUMNS FROM `%s`", $table);
$indexes = q("SHOW INDEX FROM `%s`", $table);
$table_status = q("SHOW TABLE STATUS WHERE `name` = '%s'", $table);
if (dbm::is_result($table_status)) {
$table_status = $table_status[0];
} else {
$table_status = array();
}
$fielddata = array();
$indexdata = array();
@ -104,7 +114,6 @@ function table_structure($table) {
$indexdata[$index["Key_name"]][] = $column;
}
if (dbm::is_result($structures)) {
foreach ($structures AS $field) {
$fielddata[$field["Field"]]["type"] = $field["Type"];
@ -125,10 +134,16 @@ function table_structure($table) {
}
}
}
return(array("fields"=>$fielddata, "indexes"=>$indexdata));
if (dbm::is_result($full_columns)) {
foreach ($full_columns AS $column) {
$fielddata[$column["Field"]]["Collation"] = $column["Collation"];
}
}
return array("fields" => $fielddata, "indexes" => $indexdata, "table_status" => $table_status);
}
function print_structure($database, $charset) {
function print_structure($database) {
echo "-- ------------------------------------------\n";
echo "-- ".FRIENDICA_PLATFORM." ".FRIENDICA_VERSION." (".FRIENDICA_CODENAME,")\n";
echo "-- DB_UPDATE_VERSION ".DB_UPDATE_VERSION."\n";
@ -137,24 +152,33 @@ function print_structure($database, $charset) {
echo "--\n";
echo "-- TABLE $name\n";
echo "--\n";
db_create_table($name, $structure['fields'], $charset, true, false, $structure["indexes"]);
db_create_table($name, $structure['fields'], true, false, $structure["indexes"]);
echo "\n";
}
}
/**
* @brief Print out database error messages
*
* @param object $db Database object
* @param string $message Message to be added to the error message
*
* @return string Error message
*/
function print_update_error($db, $message) {
echo sprintf(t("\nError %d occured during database update:\n%s\n"),
$db->errorno, $db->error);
return t('Errors encountered performing database changes: ').$message.EOL;
}
function update_structure($verbose, $action, $tables=null, $definition=null) {
global $a, $db;
if ($action) {
Config::set('system', 'maintenance', 1);
Config::set('system', 'maintenance_reason', 'Database update');
}
if (isset($a->config["system"]["db_charset"])) {
$charset = $a->config["system"]["db_charset"];
} else {
$charset = "utf8";
Config::set('system', 'maintenance_reason', sprintf(t(': Database update'), dbm::date().' '.date('e')));
}
$errors = false;
@ -168,16 +192,18 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
$tables = q("SHOW TABLES");
}
foreach ($tables AS $table) {
$table = current($table);
if (dbm::is_result($tables)) {
foreach ($tables AS $table) {
$table = current($table);
logger(sprintf('updating structure for table %s ...', $table), LOGGER_DEBUG);
$database[$table] = table_structure($table);
logger(sprintf('updating structure for table %s ...', $table), LOGGER_DEBUG);
$database[$table] = table_structure($table);
}
}
// Get the definition
if (is_null($definition)) {
$definition = db_definition($charset);
$definition = db_definition();
}
// MySQL >= 5.7.4 doesn't support the IGNORE keyword in ALTER TABLE statements
@ -194,9 +220,9 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
$group_by = "";
$sql3 = "";
if (!isset($database[$name])) {
$r = db_create_table($name, $structure["fields"], $charset, $verbose, $action, $structure['indexes']);
$r = db_create_table($name, $structure["fields"], $verbose, $action, $structure['indexes']);
if (!dbm::is_result($r)) {
$errors .= t('Errors encountered creating database tables.').$name.EOL;
$errors .= print_update_error($db, $name);
}
$is_new_table = True;
} else {
@ -252,17 +278,24 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
}
} else {
// Compare the field definition
$current_field_definition = implode(",",$database[$name]["fields"][$fieldname]);
$new_field_definition = implode(",",$parameters);
$field_definition = $database[$name]["fields"][$fieldname];
// We change the collation after the indexes had been changed.
// This is done to avoid index length problems.
// So here we always ensure that there is no need to change it.
unset($parameters['Collation']);
unset($field_definition['Collation']);
$current_field_definition = implode(",", $field_definition);
$new_field_definition = implode(",", $parameters);
if ($current_field_definition != $new_field_definition) {
$sql2=db_modify_table_field($fieldname, $parameters);
$sql2 = db_modify_table_field($fieldname, $parameters);
if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
} else {
$sql3 .= ", ".$sql2;
}
}
}
}
}
@ -288,16 +321,59 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
$group_by = db_group_by($indexname, $fieldnames);
}
if ($sql2 != "") {
if ($sql3 == "")
if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
else
} else {
$sql3 .= ", ".$sql2;
}
}
}
}
if (isset($database[$name]["table_status"]["Collation"])) {
if ($database[$name]["table_status"]["Collation"] != 'utf8mb4_general_ci') {
$sql2 = "DEFAULT COLLATE utf8mb4_general_ci";
if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
} else {
$sql3 .= ", ".$sql2;
}
}
}
if ($sql3 != "") {
$sql3 .= "; ";
}
// Now have a look at the field collations
// Compare the field structure field by field
foreach ($structure["fields"] AS $fieldname => $parameters) {
// Compare the field definition
$field_definition = $database[$name]["fields"][$fieldname];
// Define the default collation if not given
if (!isset($parameters['Collation']) AND !is_null($field_definition['Collation'])) {
$parameters['Collation'] = 'utf8mb4_general_ci';
} else {
$parameters['Collation'] = null;
}
if ($field_definition['Collation'] != $parameters['Collation']) {
$sql2 = db_modify_table_field($fieldname, $parameters);
if (($sql3 == "") OR (substr($sql3, -2, 2) == "; ")) {
$sql3 .= "ALTER" . $ignore . " TABLE `".$temp_name."` ".$sql2;
} else {
$sql3 .= ", ".$sql2;
}
}
}
}
if ($sql3 != "") {
$sql3 .= ";";
if (substr($sql3, -2, 2) != "; ") {
$sql3 .= ";";
}
if ($verbose) {
// Ensure index conversion to unique removes duplicates
@ -323,6 +399,8 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
}
if ($action) {
Config::set('system', 'maintenance_reason', sprintf(t('%s: updating %s table.'), dbm::date().' '.date('e'), $name));
// Ensure index conversion to unique removes duplicates
if ($is_unique) {
if ($ignore != "") {
@ -330,33 +408,33 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
} else {
$r = $db->q("CREATE TABLE `".$temp_name."` LIKE `".$name."`;");
if (!dbm::is_result($r)) {
$errors .= t('Errors encountered performing database changes.').$sql3.EOL;
$errors .= print_update_error($db, $sql3);
return $errors;
}
}
}
$r = @$db->q($sql3);
if (!dbm::is_result($r))
$errors .= t('Errors encountered performing database changes.').$sql3.EOL;
if (!dbm::is_result($r)) {
$errors .= print_update_error($db, $sql3);
}
if ($is_unique) {
if ($ignore != "") {
$db->q("SET session old_alter_table=0;");
} else {
$r = $db->q("INSERT INTO `".$temp_name."` SELECT * FROM `".$name."`".$group_by.";");
if (!dbm::is_result($r)) {
$errors .= t('Errors encountered performing database changes.').$sql3.EOL;
$errors .= print_update_error($db, $sql3);
return $errors;
}
$r = $db->q("DROP TABLE `".$name."`;");
if (!dbm::is_result($r)) {
$errors .= t('Errors encountered performing database changes.').$sql3.EOL;
$errors .= print_update_error($db, $sql3);
return $errors;
}
$r = $db->q("RENAME TABLE `".$temp_name."` TO `".$name."`;");
if (!dbm::is_result($r)) {
$errors .= t('Errors encountered performing database changes.').$sql3.EOL;
$errors .= print_update_error($db, $sql3);
return $errors;
}
}
@ -376,6 +454,10 @@ function update_structure($verbose, $action, $tables=null, $definition=null) {
function db_field_command($parameters, $create = true) {
$fieldstruct = $parameters["type"];
if (!is_null($parameters["Collation"])) {
$fieldstruct .= " COLLATE ".$parameters["Collation"];
}
if ($parameters["not null"])
$fieldstruct .= " NOT NULL";
@ -395,7 +477,7 @@ function db_field_command($parameters, $create = true) {
return($fieldstruct);
}
function db_create_table($name, $fields, $charset, $verbose, $action, $indexes=null) {
function db_create_table($name, $fields, $verbose, $action, $indexes=null) {
global $a, $db;
$r = true;
@ -404,7 +486,7 @@ function db_create_table($name, $fields, $charset, $verbose, $action, $indexes=n
$sql_rows = array();
$primary_keys = array();
foreach($fields AS $fieldname => $field) {
foreach ($fields AS $fieldname => $field) {
$sql_rows[] = "`".dbesc($fieldname)."` ".db_field_command($field);
if (x($field,'primary') and $field['primary']!=''){
$primary_keys[] = $fieldname;
@ -420,7 +502,7 @@ function db_create_table($name, $fields, $charset, $verbose, $action, $indexes=n
$sql = implode(",\n\t", $sql_rows);
$sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT CHARSET=".$charset;
$sql = sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n\t", dbesc($name)).$sql."\n) DEFAULT COLLATE utf8mb4_general_ci";
if ($verbose)
echo $sql.";\n";
@ -503,18 +585,7 @@ function db_group_by($indexname, $fieldnames) {
return $sql;
}
function db_index_suffix($charset, $reduce = 0) {
if ($charset != "utf8mb4") {
return "";
}
// On utf8mb4 indexes can only have a length of 191
$indexlength = 191 - $reduce;
return "(".$indexlength.")";
}
function db_definition($charset) {
function db_definition() {
$database = array();
@ -671,7 +742,7 @@ function db_definition($charset) {
"writable" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"forum" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"prv" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"contact-type" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"),
"contact-type" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"hidden" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"archive" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"pending" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"),
@ -681,7 +752,7 @@ function db_definition($charset) {
"info" => array("type" => "mediumtext"),
"profile-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"),
"bdyear" => array("type" => "varchar(4)", "not null" => "1", "default" => ""),
"bd" => array("type" => "date", "not null" => "1", "default" => "0000-00-00"),
"bd" => array("type" => "date", "not null" => "1", "default" => "0001-01-01"),
"notify_new_posts" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"fetch_further_information" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"ffi_keyword_blacklist" => array("type" => "text"),
@ -840,7 +911,7 @@ function db_definition($charset) {
"about" => array("type" => "text"),
"keywords" => array("type" => "text"),
"gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""),
"birthday" => array("type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00"),
"birthday" => array("type" => "varchar(32)", "not null" => "1", "default" => "0001-01-01"),
"community" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"contact-type" => array("type" => "tinyint(1)", "not null" => "1", "default" => "-1"),
"hide" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
@ -1304,7 +1375,7 @@ function db_definition($charset) {
"hide-friends" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"pdesc" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"dob" => array("type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00"),
"dob" => array("type" => "varchar(32)", "not null" => "1", "default" => "0001-01-01"),
"address" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"locality" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"region" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
@ -1621,11 +1692,11 @@ function db_definition($charset) {
function dbstructure_run(&$argv, &$argc) {
global $a, $db;
if(is_null($a)){
if (is_null($a)){
$a = new App;
}
if(is_null($db)) {
if (is_null($db)) {
@include(".htconfig.php");
require_once("include/dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
@ -1650,7 +1721,7 @@ function dbstructure_run(&$argv, &$argc) {
$current = intval(DB_UPDATE_VERSION);
// run any left update_nnnn functions in update.php
for($x = $stored; $x < $current; $x ++) {
for ($x = $stored; $x < $current; $x ++) {
$r = run_update_function($x);
if (!$r) break;
}
@ -1658,9 +1729,7 @@ function dbstructure_run(&$argv, &$argc) {
set_config('system','build',DB_UPDATE_VERSION);
return;
case "dumpsql":
// For the dump that is used to create the database.sql we always assume utfmb4
$charset = "utf8mb4";
print_structure(db_definition($charset), $charset);
print_structure(db_definition());
return;
}
}

View File

@ -554,8 +554,9 @@ class dfrn {
xml::add_element($doc, $author, "poco:displayName", $profile["name"]);
xml::add_element($doc, $author, "poco:updated", $namdate);
if (trim($profile["dob"]) != "0000-00-00")
if (trim($profile["dob"]) > '0001-01-01') {
xml::add_element($doc, $author, "poco:birthday", "0000-".date("m-d", strtotime($profile["dob"])));
}
xml::add_element($doc, $author, "poco:note", $profile["about"]);
xml::add_element($doc, $author, "poco:preferredUsername", $profile["nickname"]);
@ -867,7 +868,7 @@ class dfrn {
// The signed text contains the content in Markdown, the sender handle and the signatur for the content
// It is needed for relayed comments to Diaspora.
if($item['signed_text']) {
if ($item['signed_text']) {
$sign = base64_encode(json_encode(array('signed_text' => $item['signed_text'],'signature' => $item['signature'],'signer' => $item['signer'])));
xml::add_element($doc, $entry, "dfrn:diaspora_signature", $sign);
}
@ -1287,7 +1288,7 @@ class dfrn {
$href = "";
$width = 0;
foreach ($avatar->attributes AS $attributes) {
/// @TODO Rewrite these similar if() to one switch
/// @TODO Rewrite these similar if () to one switch
if ($attributes->name == "href") {
$href = $attributes->textContent;
}
@ -1402,7 +1403,7 @@ class dfrn {
// "poco:birthday" is the birthday in the format "yyyy-mm-dd"
$value = $xpath->evaluate($element . "/poco:birthday/text()", $context)->item(0)->nodeValue;
if (!in_array($value, array("", "0000-00-00"))) {
if (!in_array($value, array("", "0000-00-00", "0001-01-01"))) {
$bdyear = date("Y");
$value = str_replace("0000", $bdyear, $value);
@ -2164,7 +2165,7 @@ class dfrn {
$title = "";
foreach ($links AS $link) {
foreach ($link->attributes AS $attributes) {
/// @TODO Rewrite these repeated (same) if() statements to a switch()
/// @TODO Rewrite these repeated (same) if () statements to a switch()
if ($attributes->name == "href") {
$href = $attributes->textContent;
}
@ -2414,7 +2415,7 @@ class dfrn {
// When activated, forums don't work.
// And: Why should we disallow commenting by followers?
// the behaviour is now similar to the Diaspora part.
//if($importer["rel"] == CONTACT_IS_FOLLOWER) {
//if ($importer["rel"] == CONTACT_IS_FOLLOWER) {
// logger("Contact ".$importer["id"]." is only follower. Quitting", LOGGER_DEBUG);
// return;
//}
@ -2539,7 +2540,7 @@ class dfrn {
logger("Item was stored with id ".$posted_id, LOGGER_DEBUG);
if(stristr($item["verb"],ACTIVITY_POKE))
if (stristr($item["verb"],ACTIVITY_POKE))
self::do_poke($item, $importer, $posted_id);
}
}
@ -2666,7 +2667,7 @@ class dfrn {
create_tags_from_itemuri($uri, $importer["uid"]);
create_files_from_itemuri($uri, $importer["uid"]);
update_thread_uri($uri, $importer["importer_uid"]);
if($item["last-child"]) {
if ($item["last-child"]) {
// ensure that last-child is set in case the comment that had it just got wiped.
q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
dbesc(datetime_convert()),

View File

@ -45,7 +45,7 @@ class Diaspora {
$servers = explode(",", $serverdata);
foreach($servers AS $server) {
foreach ($servers AS $server) {
$server = trim($server);
$addr = "relay@".str_replace("http://", "", normalise_link($server));
$batch = $server."/receive/public";
@ -207,7 +207,7 @@ class Diaspora {
$children = $basedom->children('https://joindiaspora.com/protocol');
if($children->header) {
if ($children->header) {
$public = true;
$author_link = str_replace('acct:','',$children->header->author_id);
} else {
@ -240,11 +240,11 @@ class Diaspora {
// figure out where in the DOM tree our data is hiding
if($dom->provenance->data)
if ($dom->provenance->data)
$base = $dom->provenance;
elseif($dom->env->data)
elseif ($dom->env->data)
$base = $dom->env;
elseif($dom->data)
elseif ($dom->data)
$base = $dom;
if (!$base) {
@ -277,7 +277,7 @@ class Diaspora {
$data = base64url_decode($data);
if($public)
if ($public)
$inner_decrypted = $data;
else {
@ -578,7 +578,7 @@ class Diaspora {
logger("Fetching diaspora key for: ".$handle);
$r = self::person_by_handle($handle);
if($r)
if ($r)
return $r["pubkey"];
return "";
@ -634,7 +634,7 @@ class Diaspora {
*/
private static function add_fcontact($arr, $update = false) {
if($update) {
if ($update) {
$r = q("UPDATE `fcontact` SET
`name` = '%s',
`photo` = '%s',
@ -818,7 +818,7 @@ class Diaspora {
// perhaps we were already sharing with this person. Now they're sharing with us.
// That makes us friends.
// 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_FREELOVE))) {
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",
intval(CONTACT_IS_FRIEND),
intval($contact["id"]),
@ -828,12 +828,12 @@ class Diaspora {
logger("defining user ".$contact["nick"]." as friend");
}
if(($contact["blocked"]) || ($contact["readonly"]) || ($contact["archive"]))
if (($contact["blocked"]) || ($contact["readonly"]) || ($contact["archive"]))
return false;
if($contact["rel"] == CONTACT_IS_SHARING || $contact["rel"] == CONTACT_IS_FRIEND)
if ($contact["rel"] == CONTACT_IS_SHARING || $contact["rel"] == CONTACT_IS_FRIEND)
return true;
if($contact["rel"] == CONTACT_IS_FOLLOWER)
if(($importer["page-flags"] == PAGE_COMMUNITY) OR $is_comment)
if ($contact["rel"] == CONTACT_IS_FOLLOWER)
if (($importer["page-flags"] == PAGE_COMMUNITY) OR $is_comment)
return true;
// Messages for the global users are always accepted
@ -991,7 +991,7 @@ class Diaspora {
logger("Fetch post from ".$source_url, LOGGER_DEBUG);
$envelope = fetch_url($source_url);
if($envelope) {
if ($envelope) {
logger("Envelope was fetched.", LOGGER_DEBUG);
$x = self::verify_magic_envelope($envelope);
if (!$x)
@ -1007,7 +1007,7 @@ class Diaspora {
logger("Fetch post from ".$source_url, LOGGER_DEBUG);
$x = fetch_url($source_url);
if(!$x)
if (!$x)
return false;
}
@ -1064,7 +1064,7 @@ class Diaspora {
FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
intval($uid), dbesc($guid));
if(!$r) {
if (!$r) {
$result = self::store_by_guid($guid, $contact["url"], $uid);
if (!$result) {
@ -1325,7 +1325,7 @@ class Diaspora {
}
// If we are the origin of the parent we store the original data and notify our followers
if($message_id AND $parent_item["origin"]) {
if ($message_id AND $parent_item["origin"]) {
// Formerly we stored the signed text, the signature and the author in different fields.
// We now store the raw data so that we are more flexible.
@ -1502,7 +1502,7 @@ class Diaspora {
intval($importer["uid"]),
dbesc($guid)
);
if($c)
if ($c)
$conversation = $c[0];
else {
$r = q("INSERT INTO `conv` (`uid`, `guid`, `creator`, `created`, `updated`, `subject`, `recips`)
@ -1515,13 +1515,13 @@ class Diaspora {
dbesc($subject),
dbesc($participants)
);
if($r)
if ($r)
$c = q("SELECT * FROM `conv` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
intval($importer["uid"]),
dbesc($guid)
);
if($c)
if ($c)
$conversation = $c[0];
}
if (!$conversation) {
@ -1529,7 +1529,7 @@ class Diaspora {
return;
}
foreach($messages as $mesg)
foreach ($messages as $mesg)
self::receive_conversation_message($importer, $contact, $data, $msg, $mesg, $conversation);
return true;
@ -1659,7 +1659,7 @@ class Diaspora {
logger("Stored like ".$datarray["guid"]." with message id ".$message_id, LOGGER_DEBUG);
// If we are the origin of the parent we store the original data and notify our followers
if($message_id AND $parent_item["origin"]) {
if ($message_id AND $parent_item["origin"]) {
// Formerly we stored the signed text, the signature and the author in different fields.
// We now store the raw data so that we are more flexible.
@ -1834,10 +1834,10 @@ class Diaspora {
$handle_parts = explode("@", $author);
$nick = $handle_parts[0];
if($name === "")
if ($name === "")
$name = $handle_parts[0];
if( preg_match("|^https?://|", $image_url) === 0)
if ( preg_match("|^https?://|", $image_url) === 0)
$image_url = "http://".$handle_parts[1].$image_url;
update_contact_avatar($image_url, $importer["uid"], $contact["id"]);
@ -1852,7 +1852,7 @@ class Diaspora {
// this is to prevent multiple birthday notifications in a single year
// if we already have a stored birthday and the 'm-d' part hasn't changed, preserve the entry, which will preserve the notify year
if(substr($birthday,5) === substr($contact["bd"],5))
if (substr($birthday,5) === substr($contact["bd"],5))
$birthday = $contact["bd"];
$r = q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `addr` = '%s', `name-date` = '%s', `bd` = '%s',
@ -1895,7 +1895,7 @@ class Diaspora {
$a = get_app();
if($contact["rel"] == CONTACT_IS_FOLLOWER && in_array($importer["page-flags"], array(PAGE_FREELOVE))) {
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",
intval(CONTACT_IS_FRIEND),
intval($contact["id"]),
@ -1908,7 +1908,7 @@ class Diaspora {
intval($importer["uid"])
);
if($r && !$r[0]["hide-friends"] && !$contact["hidden"] && intval(get_pconfig($importer["uid"], "system", "post_newfriend"))) {
if ($r && !$r[0]["hide-friends"] && !$contact["hidden"] && intval(get_pconfig($importer["uid"], "system", "post_newfriend"))) {
$self = q("SELECT * FROM `contact` WHERE `self` AND `uid` = %d LIMIT 1",
intval($importer["uid"])
@ -1916,7 +1916,7 @@ class Diaspora {
// they are not CONTACT_IS_FOLLOWER anymore but that's what we have in the array
if($self && $contact["rel"] == CONTACT_IS_FOLLOWER) {
if ($self && $contact["rel"] == CONTACT_IS_FOLLOWER) {
$arr = array();
$arr["uri"] = $arr["parent-uri"] = item_new_uri($a->get_hostname(), $importer["uid"]);
@ -1947,7 +1947,7 @@ class Diaspora {
$arr["deny_gid"] = $user[0]["deny_gid"];
$i = item_store($arr);
if($i)
if ($i)
proc_run(PRIORITY_HIGH, "include/notifier.php", "activity", $i);
}
}
@ -2086,12 +2086,12 @@ class Diaspora {
$def_gid = get_default_group($importer['uid'], $ret["network"]);
if(intval($def_gid))
if (intval($def_gid))
group_add_member($importer["uid"], "", $contact_record["id"], $def_gid);
update_contact_avatar($ret["photo"], $importer['uid'], $contact_record["id"], true);
if($importer["page-flags"] == PAGE_NORMAL) {
if ($importer["page-flags"] == PAGE_NORMAL) {
logger("Sending intra message for author ".$author.".", LOGGER_DEBUG);
@ -2141,7 +2141,7 @@ class Diaspora {
);
$u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer["uid"]));
if($u) {
if ($u) {
logger("Sending share message (Relation: ".$new_relation.") to author ".$author." - Contact: ".$contact_record["id"]." - User: ".$importer["uid"], LOGGER_DEBUG);
$ret = self::send_share($u[0], $contact_record);
@ -2765,7 +2765,7 @@ class Diaspora {
$a = get_app();
$enabled = intval(get_config("system", "diaspora_enabled"));
if(!$enabled)
if (!$enabled)
return 200;
$logid = random_string(4);
@ -3104,14 +3104,14 @@ class Diaspora {
$body = html_entity_decode(bb2diaspora($body));
// Adding the title
if(strlen($title))
if (strlen($title))
$body = "## ".html_entity_decode($title)."\n\n".$body;
if ($item["attach"]) {
$cnt = preg_match_all('/href=\"(.*?)\"(.*?)title=\"(.*?)\"/ism', $item["attach"], $matches, PREG_SET_ORDER);
if(cnt) {
if (cnt) {
$body .= "\n".t("Attachments:")."\n";
foreach($matches as $mtch)
foreach ($matches as $mtch)
$body .= "[".$mtch[3]."](".$mtch[1].")\n";
}
}
@ -3591,7 +3591,7 @@ class Diaspora {
if ($searchable === 'true') {
$dob = '1000-00-00';
if (($profile['dob']) && ($profile['dob'] != '0000-00-00'))
if (($profile['dob']) && ($profile['dob'] > '0001-01-01'))
$dob = ((intval($profile['dob'])) ? intval($profile['dob']) : '1000') .'-'. datetime_convert('UTC','UTC',$profile['dob'],'m-d');
$about = $profile['about'];
@ -3604,7 +3604,7 @@ class Diaspora {
$kw = str_replace(' ',' ',$kw);
$arr = explode(' ',$profile['pub_keywords']);
if (count($arr)) {
for($x = 0; $x < 5; $x ++) {
for ($x = 0; $x < 5; $x ++) {
if (trim($arr[$x]))
$tags .= '#'. trim($arr[$x]) .' ';
}
@ -3626,7 +3626,7 @@ class Diaspora {
"searchable" => $searchable,
"tag_string" => $tags);
foreach($recips as $recip) {
foreach ($recips as $recip) {
logger("Send updated profile data for user ".$uid." to contact ".$recip["id"], LOGGER_DEBUG);
self::build_and_transmit($profile, $recip, "profile", $message, false, "", true);
}
@ -3649,17 +3649,20 @@ class Diaspora {
}
$r = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1", intval($contact['uid']));
if(!$r)
if (!dbm::is_result($r)) {
return false;
}
$contact["uprvkey"] = $r[0]['prvkey'];
$r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1", intval($post_id));
if (!$r)
if (!dbm::is_result($r)) {
return false;
}
if (!in_array($r[0]["verb"], array(ACTIVITY_LIKE, ACTIVITY_DISLIKE)))
if (!in_array($r[0]["verb"], array(ACTIVITY_LIKE, ACTIVITY_DISLIKE))) {
return false;
}
$message = self::construct_like($r[0], $contact);
$message["author_signature"] = self::signature($contact, $message);

View File

@ -1,17 +1,19 @@
<?php
/// @TODO no longer used?
use \Friendica\Core\Config;
function directory_run(&$argv, &$argc){
if ($argc != 2) {
return;
}
$dir = get_config('system', 'directory');
if (!strlen($dir)) {
return;
}
if ($argc < 2) {
directory_update_all();
return;
}
$dir .= "/submit";
$arr = array('url' => $argv[1]);
@ -22,5 +24,20 @@ function directory_run(&$argv, &$argc){
if (strlen($arr['url'])) {
fetch_url($dir . '?url=' . bin2hex($arr['url']));
}
return;
}
function directory_update_all() {
$r = q("SELECT `url` FROM `contact`
INNER JOIN `profile` ON `profile`.`uid` = `contact`.`uid`
INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`self` AND `profile`.`net-publish` AND `profile`.`is-default` AND
NOT `user`.`account_expired` AND `user`.`verified`");
if (dbm::is_result($r)) {
foreach ($r AS $user) {
proc_run(PRIORITY_LOW, 'include/directory.php', $user['url']);
}
}
}

View File

@ -209,10 +209,10 @@ function discover_directory($search) {
$j = json_decode($x);
if (count($j->results)) {
foreach($j->results as $jj) {
foreach ($j->results as $jj) {
// Check if the contact already exists
$exists = q("SELECT `id`, `last_contact`, `last_failure`, `updated` FROM `gcontact` WHERE `nurl` = '%s'", normalise_link($jj->url));
if ($exists) {
if (dbm::is_result($exists)) {
logger("Profile ".$jj->url." already exists (".$search.")", LOGGER_DEBUG);
if (($exists[0]["last_contact"] < $exists[0]["last_failure"]) AND
@ -272,12 +272,16 @@ function gs_search_user($search) {
if (!$result["success"]) {
return false;
}
$contacts = json_decode($result["body"]);
if ($contacts->status == 'ERROR') {
return false;
}
foreach($contacts->data AS $user) {
/// @TODO AS is considered as a notation for constants (as they usually being written all upper-case)
/// @TODO find all those and convert to all lower-case which is a keyword then
foreach ($contacts->data AS $user) {
$contact = probe_url($user->site_address."/".$user->name);
if ($contact["network"] != NETWORK_PHANTOM) {
$contact["about"] = $user->description;

View File

@ -4,7 +4,7 @@ require_once('include/msgclean.php');
require_once('include/quoteconvert.php');
function email_connect($mailbox,$username,$password) {
if(! function_exists('imap_open'))
if (! function_exists('imap_open'))
return false;
$mbox = @imap_open($mailbox,$username,$password);
@ -14,23 +14,23 @@ function email_connect($mailbox,$username,$password) {
function email_poll($mbox,$email_addr) {
if(! ($mbox && $email_addr))
if (! ($mbox && $email_addr))
return array();
$search1 = @imap_search($mbox,'FROM "' . $email_addr . '"', SE_UID);
if(! $search1)
if (! $search1)
$search1 = array();
$search2 = @imap_search($mbox,'TO "' . $email_addr . '"', SE_UID);
if(! $search2)
if (! $search2)
$search2 = array();
$search3 = @imap_search($mbox,'CC "' . $email_addr . '"', SE_UID);
if(! $search3)
if (! $search3)
$search3 = array();
$search4 = @imap_search($mbox,'BCC "' . $email_addr . '"', SE_UID);
if(! $search4)
if (! $search4)
$search4 = array();
$res = array_unique(array_merge($search1,$search2,$search3,$search4));
@ -57,8 +57,8 @@ function email_msg_headers($mbox,$uid) {
$raw_header = str_replace("\r",'',$raw_header);
$ret = array();
$h = explode("\n",$raw_header);
if(count($h))
foreach($h as $line ) {
if (count($h))
foreach ($h as $line ) {
if (preg_match("/^[a-zA-Z]/", $line)) {
$key = substr($line,0,strpos($line,':'));
$value = substr($line,strpos($line,':')+1);
@ -79,10 +79,10 @@ function email_get_msg($mbox,$uid, $reply) {
$struc = (($mbox && $uid) ? @imap_fetchstructure($mbox,$uid,FT_UID) : null);
if(! $struc)
if (! $struc)
return $ret;
if(! $struc->parts) {
if (! $struc->parts) {
$ret['body'] = email_get_part($mbox,$uid,$struc,0, 'html');
$html = $ret['body'];
@ -94,7 +94,7 @@ function email_get_msg($mbox,$uid, $reply) {
else {
$text = '';
$html = '';
foreach($struc->parts as $ptop => $p) {
foreach ($struc->parts as $ptop => $p) {
$x = email_get_part($mbox,$uid,$p,$ptop + 1, 'plain');
if ($x) {
$text .= $x;
@ -206,16 +206,16 @@ function email_get_part($mbox,$uid,$p,$partno, $subtype) {
function email_header_encode($in_str, $charset) {
$out_str = $in_str;
$out_str = $in_str;
$need_to_convert = false;
for($x = 0; $x < strlen($in_str); $x ++) {
if((ord($in_str[$x]) == 0) || ((ord($in_str[$x]) > 128))) {
for ($x = 0; $x < strlen($in_str); $x ++) {
if ((ord($in_str[$x]) == 0) || ((ord($in_str[$x]) > 128))) {
$need_to_convert = true;
}
}
if(! $need_to_convert)
if (! $need_to_convert)
return $in_str;
if ($out_str && $charset) {

View File

@ -411,10 +411,12 @@ function notification($params) {
$hash = random_string();
$r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' LIMIT 1",
dbesc($hash));
if (dbm::is_result($r))
if (dbm::is_result($r)) {
$dups = true;
} while($dups == true);
}
} while ($dups == true);
/// @TODO One statement is enough
$datarray = array();
$datarray['hash'] = $hash;
$datarray['name'] = $params['source_name'];

View File

@ -10,7 +10,7 @@ require_once 'include/datetime.php';
function format_event_html($ev, $simple = false) {
if(! ((is_array($ev)) && count($ev))) {
if (! ((is_array($ev)) && count($ev))) {
return '';
}
@ -98,26 +98,26 @@ function parse_event($h) {
logger('parse_event: parse error: ' . $e);
}
if(! $dom)
if (! $dom)
return $ret;
$items = $dom->getElementsByTagName('*');
foreach($items as $item) {
if(attribute_contains($item->getAttribute('class'), 'vevent')) {
foreach ($items as $item) {
if (attribute_contains($item->getAttribute('class'), 'vevent')) {
$level2 = $item->getElementsByTagName('*');
foreach($level2 as $x) {
if(attribute_contains($x->getAttribute('class'),'dtstart') && $x->getAttribute('title')) {
foreach ($level2 as $x) {
if (attribute_contains($x->getAttribute('class'),'dtstart') && $x->getAttribute('title')) {
$ret['start'] = $x->getAttribute('title');
if(! strpos($ret['start'],'Z'))
if (! strpos($ret['start'],'Z'))
$ret['adjust'] = true;
}
if(attribute_contains($x->getAttribute('class'),'dtend') && $x->getAttribute('title'))
if (attribute_contains($x->getAttribute('class'),'dtend') && $x->getAttribute('title'))
$ret['finish'] = $x->getAttribute('title');
if(attribute_contains($x->getAttribute('class'),'description'))
if (attribute_contains($x->getAttribute('class'),'description'))
$ret['desc'] = $x->textContent;
if(attribute_contains($x->getAttribute('class'),'location'))
if (attribute_contains($x->getAttribute('class'),'location'))
$ret['location'] = $x->textContent;
}
}
@ -125,23 +125,23 @@ function parse_event($h) {
// sanitise
if((x($ret,'desc')) && ((strpos($ret['desc'],'<') !== false) || (strpos($ret['desc'],'>') !== false))) {
if ((x($ret,'desc')) && ((strpos($ret['desc'],'<') !== false) || (strpos($ret['desc'],'>') !== false))) {
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.DefinitionImpl', null);
$purifier = new HTMLPurifier($config);
$ret['desc'] = html2bbcode($purifier->purify($ret['desc']));
}
if((x($ret,'location')) && ((strpos($ret['location'],'<') !== false) || (strpos($ret['location'],'>') !== false))) {
if ((x($ret,'location')) && ((strpos($ret['location'],'<') !== false) || (strpos($ret['location'],'>') !== false))) {
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.DefinitionImpl', null);
$purifier = new HTMLPurifier($config);
$ret['location'] = html2bbcode($purifier->purify($ret['location']));
}
if(x($ret,'start'))
if (x($ret,'start'))
$ret['start'] = datetime_convert('UTC','UTC',$ret['start']);
if(x($ret,'finish'))
if (x($ret,'finish'))
$ret['finish'] = datetime_convert('UTC','UTC',$ret['finish']);
return $ret;
@ -595,7 +595,7 @@ function event_by_id($owner_uid = 0, $event_params, $sql_extra = '') {
*/
function events_by_date($owner_uid = 0, $event_params, $sql_extra = '') {
// Only allow events if there is a valid owner_id
if($owner_uid == 0) {
if ($owner_uid == 0) {
return;
}

View File

@ -11,12 +11,13 @@ function expire_run(&$argv, &$argc){
// physically remove anything that has been deleted for more than two months
$r = q("delete from item where deleted = 1 and changed < UTC_TIMESTAMP() - INTERVAL 60 DAY");
$r = q("DELETE FROM `item` WHERE `deleted` = 1 AND `changed` < UTC_TIMESTAMP() - INTERVAL 60 DAY");
// make this optional as it could have a performance impact on large sites
if(intval(get_config('system','optimize_items')))
q("optimize table item");
if (intval(get_config('system','optimize_items'))) {
q("OPTIMIZE TABLE `item`");
}
logger('expire: start');

View File

@ -200,7 +200,6 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
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;
@ -210,12 +209,17 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
if ($item["uri"] == "") {
$item["uri"] = $item["plink"];
}
$orig_plink = $item["plink"];
$item["plink"] = original_url($item["plink"]);
$item["parent-uri"] = $item["uri"];
if (!$simulate) {
$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) {
if (dbm::is_result($r)) {
logger("Item with uri ".$item["uri"]." for user ".$importer["uid"]." already existed under id ".$r[0]["id"], LOGGER_DEBUG);
continue;
}
@ -340,6 +344,7 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
// Distributed items should have a well formatted URI.
// Additionally we have to avoid conflicts with identical URI between imported feeds and these items.
if ($notify) {
$item['guid'] = uri_to_guid($orig_plink, $a->get_hostname());
unset($item['uri']);
unset($item['parent-uri']);
}

View File

@ -202,6 +202,9 @@ function profile_sidebar($profile, $block = 0) {
$address = false;
// $pdesc = true;
// This function can also use contact information in $profile
$is_contact = x($profile, 'cid');
if((! is_array($profile)) && (! count($profile)))
return $o;
@ -281,7 +284,7 @@ function profile_sidebar($profile, $block = 0) {
}
// show edit profile to yourself
if ($profile['uid'] == local_user() && feature_enabled(local_user(),'multi_profiles')) {
if (!$is_contact && $profile['uid'] == local_user() && feature_enabled(local_user(),'multi_profiles')) {
$profile['edit'] = array(App::get_baseurl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles'));
$r = q("SELECT * FROM `profile` WHERE `uid` = %d",
local_user());
@ -310,7 +313,7 @@ function profile_sidebar($profile, $block = 0) {
}
}
if ($profile['uid'] == local_user() && !feature_enabled(local_user(),'multi_profiles')) {
if (!$is_contact && $profile['uid'] == local_user() && !feature_enabled(local_user(),'multi_profiles')) {
$profile['edit'] = array(App::get_baseurl(). '/profiles/'.$profile['id'], t('Edit profile'),"", t('Edit profile'));
$profile['menu'] = array(
'chg_photo' => t('Change profile photo'),
@ -628,7 +631,7 @@ function advanced_profile(App $a) {
if($a->profile['gender']) $profile['gender'] = array( t('Gender:'), $a->profile['gender'] );
if(($a->profile['dob']) && ($a->profile['dob'] != '0000-00-00')) {
if(($a->profile['dob']) && ($a->profile['dob'] > '0001-01-01')) {
$year_bd_format = t('j F, Y');
$short_bd_format = t('j F');

File diff suppressed because it is too large Load Diff

View File

@ -516,7 +516,8 @@ function notifier_run(&$argv, &$argc){
$r0 = Diaspora::relay_list();
}
$r1 = q("SELECT DISTINCT(`batch`), `id`, `name`,`network` FROM `contact` WHERE `network` = '%s'
$r1 = q("SELECT `batch`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`name`) AS `name`, ANY_VALUE(`network`) AS `network`
FROM `contact` WHERE `network` = '%s'
AND `uid` = %d AND `rel` != %d AND NOT `blocked` AND NOT `pending` AND NOT `archive` GROUP BY `batch` ORDER BY rand()",
dbesc(NETWORK_DIASPORA),
intval($owner['uid']),

View File

@ -355,6 +355,14 @@ class ostatus {
$item["body"] = add_page_info_to_body(html2bbcode($xpath->query('atom:content/text()', $entry)->item(0)->nodeValue));
$item["object-type"] = $xpath->query('activity:object-type/text()', $entry)->item(0)->nodeValue;
$item["verb"] = $xpath->query('activity:verb/text()', $entry)->item(0)->nodeValue;
// Mastodon Content Warning
if (($item["verb"] == ACTIVITY_POST) AND $xpath->evaluate('boolean(atom:summary)', $entry)) {
$clear_text = $xpath->query('atom:summary/text()', $entry)->item(0)->nodeValue;
$item["body"] = html2bbcode($clear_text) . '[spoiler]' . $item["body"] . '[/spoiler]';
}
if (($item["object-type"] == ACTIVITY_OBJ_BOOKMARK) OR ($item["object-type"] == ACTIVITY_OBJ_EVENT)) {
$item["title"] = $xpath->query('atom:title/text()', $entry)->item(0)->nodeValue;
@ -363,11 +371,10 @@ class ostatus {
$item["title"] = $xpath->query('atom:title/text()', $entry)->item(0)->nodeValue;
}
$item["object"] = $xml;
$item["verb"] = $xpath->query('activity:verb/text()', $entry)->item(0)->nodeValue;
/// @TODO
/// Delete a message
if ($item["verb"] == "qvitter-delete-notice") {
if ($item["verb"] == "qvitter-delete-notice" || $item["verb"] == ACTIVITY_DELETE) {
// ignore "Delete" messages (by now)
logger("Ignore delete message ".print_r($item, true));
continue;
@ -713,11 +720,11 @@ class ostatus {
$conversations = q("SELECT `term`.`oid`, `term`.`url`, `term`.`uid` FROM `term`
STRAIGHT_JOIN `thread` ON `thread`.`iid` = `term`.`oid` AND `thread`.`uid` = `term`.`uid`
WHERE `term`.`type` = 7 AND `term`.`term` > '%s' AND `thread`.`mention`
GROUP BY `term`.`url`, `term`.`uid` ORDER BY `term`.`term` DESC", dbesc($start));
GROUP BY `term`.`url`, `term`.`uid`, `term`.`oid`, `term`.`term` ORDER BY `term`.`term` DESC", dbesc($start));
} else {
$conversations = q("SELECT `oid`, `url`, `uid` FROM `term`
WHERE `type` = 7 AND `term` > '%s'
GROUP BY `url`, `uid` ORDER BY `term` DESC", dbesc($start));
GROUP BY `url`, `uid`, `oid`, `term` ORDER BY `term` DESC", dbesc($start));
}
foreach ($conversations AS $conversation) {
@ -1472,15 +1479,7 @@ class ostatus {
$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;
switch ($siteinfo["type"]) {
case 'photo':
$imgdata = get_photo_info($siteinfo["image"]);
$attributes = array("rel" => "enclosure",
@ -1502,29 +1501,31 @@ class ostatus {
}
if (($siteinfo["type"] != "photo") AND isset($siteinfo["image"])) {
$photodata = get_photo_info($siteinfo["image"]);
$imgdata = get_photo_info($siteinfo["image"]);
$attributes = array("rel" => "enclosure",
"href" => $siteinfo["image"],
"type" => $imgdata["mime"],
"length" => intval($imgdata["size"]));
$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) {
$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) {
$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]))
if (intval($matches[2])) {
$attributes["length"] = intval($matches[2]);
if(trim($matches[4]) != "")
}
if (trim($matches[4]) != "") {
$attributes["title"] = trim($matches[4]);
}
xml::add_element($doc, $root, "link", "", $attributes);
}
}
@ -2052,7 +2053,7 @@ class ostatus {
$mentioned = array();
if (($item['parent'] != $item['id']) || ($item['parent-uri'] !== $item['uri']) || (($item['thr-parent'] !== '') && ($item['thr-parent'] !== $item['uri']))) {
if (($item['parent'] != $item['id']) OR ($item['parent-uri'] !== $item['uri']) OR (($item['thr-parent'] !== '') AND ($item['thr-parent'] !== $item['uri']))) {
$parent = q("SELECT `guid`, `author-link`, `owner-link` FROM `item` WHERE `id` = %d", intval($item["parent"]));
$parent_item = (($item['thr-parent']) ? $item['thr-parent'] : $item['parent-uri']);
@ -2082,7 +2083,13 @@ class ostatus {
if (intval($item["parent"]) > 0) {
$conversation = App::get_baseurl()."/display/".$owner["nick"]."/".$item["parent"];
xml::add_element($doc, $entry, "link", "", array("rel" => "ostatus:conversation", "href" => $conversation));
xml::add_element($doc, $entry, "ostatus:conversation", $conversation);
$attributes = array(
"href" => $conversation,
"local_id" => $item["parent"],
"ref" => $conversation);
xml::add_element($doc, $entry, "ostatus:conversation", $conversation, $attributes);
}
$tags = item_getfeedtags($item);

View File

@ -44,7 +44,7 @@ function get_browser_language() {
// check if we have translations for the preferred languages and pick the 1st that has
for ($i=0; $i<count($lang_list); $i++) {
$lang = $lang_list[$i];
if(file_exists("view/lang/$lang") && is_dir("view/lang/$lang")) {
if ($lang === 'en' || (file_exists("view/lang/$lang") && is_dir("view/lang/$lang"))) {
$preferred = $lang;
break;
}

View File

@ -48,7 +48,7 @@ function photo_albums($uid, $update = false) {
if (!Config::get('system', 'no_count', false)) {
/// @todo This query needs to be renewed. It is really slow
// At this time we just store the data in the cache
$albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`
$albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`, ANY_VALUE(`created`) AS `created`
FROM `photo`
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra
GROUP BY `album` ORDER BY `created` DESC",
@ -59,9 +59,8 @@ function photo_albums($uid, $update = false) {
} else {
// This query doesn't do the count and is much faster
$albums = qu("SELECT DISTINCT(`album`), '' AS `total`
FROM `photo`
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra
GROUP BY `album` ORDER BY `created` DESC",
FROM `photo` USE INDEX (`uid_album_scale_created`)
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra",
intval($uid),
dbesc('Contact Photos'),
dbesc(t('Contact Photos'))

View File

@ -3,21 +3,20 @@
require_once('include/crypto.php');
require_once('include/Probe.php');
function get_salmon_key($uri,$keyhash) {
function get_salmon_key($uri, $keyhash) {
$ret = array();
logger('Fetching salmon key for '.$uri);
$arr = Probe::lrdd($uri);
if(is_array($arr)) {
foreach($arr as $a) {
if($a['@attributes']['rel'] === 'magic-public-key') {
if (is_array($arr)) {
foreach ($arr as $a) {
if ($a['@attributes']['rel'] === 'magic-public-key') {
$ret[] = $a['@attributes']['href'];
}
}
}
else {
} else {
return '';
}
@ -26,11 +25,11 @@ function get_salmon_key($uri,$keyhash) {
if (count($ret) > 0) {
for ($x = 0; $x < count($ret); $x ++) {
if (substr($ret[$x],0,5) === 'data:') {
if (strstr($ret[$x],',')) {
$ret[$x] = substr($ret[$x],strpos($ret[$x],',')+1);
if (substr($ret[$x], 0, 5) === 'data:') {
if (strstr($ret[$x], ',')) {
$ret[$x] = substr($ret[$x], strpos($ret[$x], ',') + 1);
} else {
$ret[$x] = substr($ret[$x],5);
$ret[$x] = substr($ret[$x], 5);
}
} elseif (normalise_link($ret[$x]) == 'http://') {
$ret[$x] = fetch_url($ret[$x]);
@ -39,7 +38,7 @@ function get_salmon_key($uri,$keyhash) {
}
logger('Key located: ' . print_r($ret,true));
logger('Key located: ' . print_r($ret, true));
if (count($ret) == 1) {
@ -50,10 +49,9 @@ function get_salmon_key($uri,$keyhash) {
// have one key we'll be right.
return $ret[0];
}
else {
} else {
foreach ($ret as $a) {
$hash = base64url_encode(hash('sha256',$a));
$hash = base64url_encode(hash('sha256', $a));
if ($hash == $keyhash) {
return $a;
}
@ -65,17 +63,17 @@ function get_salmon_key($uri,$keyhash) {
function slapper($owner,$url,$slap) {
function slapper($owner, $url, $slap) {
// does contact have a salmon endpoint?
if(! strlen($url))
if (! strlen($url)) {
return;
}
if(! $owner['sprvkey']) {
if (! $owner['sprvkey']) {
logger(sprintf("user '%s' (%d) does not have a salmon private key. Send failed.",
$owner['username'],$owner['uid']));
$owner['username'], $owner['uid']));
return;
}
@ -87,30 +85,33 @@ function slapper($owner,$url,$slap) {
$data_type = 'application/atom+xml';
$encoding = 'base64url';
$algorithm = 'RSA-SHA256';
$keyhash = base64url_encode(hash('sha256',salmon_key($owner['spubkey'])),true);
$keyhash = base64url_encode(hash('sha256', salmon_key($owner['spubkey'])), true);
// precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
$precomputed = '.' . base64url_encode($data_type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($algorithm);
$precomputed = '.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
// GNU Social format
$signature = base64url_encode(rsa_sign($data . $precomputed, $owner['sprvkey']));
$signature = base64url_encode(rsa_sign(str_replace('=','',$data . $precomputed),$owner['sprvkey']));
// Compliant format
$signature2 = base64url_encode(rsa_sign(str_replace('=', '', $data . $precomputed), $owner['sprvkey']));
$signature2 = base64url_encode(rsa_sign($data . $precomputed,$owner['sprvkey']));
// Old Status.net format
$signature3 = base64url_encode(rsa_sign($data, $owner['sprvkey']));
$signature3 = base64url_encode(rsa_sign($data,$owner['sprvkey']));
// At first try the non compliant method that works for GNU Social
$xmldata = array("me:env" => array("me:data" => $data,
"@attributes" => array("type" => $data_type),
"me:encoding" => $encoding,
"me:alg" => $algorithm,
"me:sig" => $signature,
"@attributes2" => array("key_id" => $keyhash)));
$salmon_tpl = get_markup_template('magicsig.tpl');
$namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env");
$salmon = replace_macros($salmon_tpl,array(
'$data' => $data,
'$encoding' => $encoding,
'$algorithm' => $algorithm,
'$keyhash' => $keyhash,
'$signature' => $signature
));
$salmon = xml::from_array($xmldata, $xml, false, $namespaces);
// slap them
post_url($url,$salmon, array(
post_url($url, $salmon, array(
'Content-type: application/magic-envelope+xml',
'Content-length: ' . strlen($salmon)
));
@ -120,60 +121,59 @@ function slapper($owner,$url,$slap) {
// check for success, e.g. 2xx
if($return_code > 299) {
if ($return_code > 299) {
logger('compliant salmon failed. Falling back to status.net hack2');
logger('GNU Social salmon failed. Falling back to compliant mode');
// Entirely likely that their salmon implementation is
// non-compliant. Let's try once more, this time only signing
// the data, without stripping '=' chars
// Now try the compliant mode that normally isn't used for GNU Social
$xmldata = array("me:env" => array("me:data" => $data,
"@attributes" => array("type" => $data_type),
"me:encoding" => $encoding,
"me:alg" => $algorithm,
"me:sig" => $signature2,
"@attributes2" => array("key_id" => $keyhash)));
$salmon = replace_macros($salmon_tpl,array(
'$data' => $data,
'$encoding' => $encoding,
'$algorithm' => $algorithm,
'$keyhash' => $keyhash,
'$signature' => $signature2
));
$namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env");
$salmon = xml::from_array($xmldata, $xml, false, $namespaces);
// slap them
post_url($url,$salmon, array(
post_url($url, $salmon, array(
'Content-type: application/magic-envelope+xml',
'Content-length: ' . strlen($salmon)
));
$return_code = $a->get_curl_code();
if($return_code > 299) {
logger('compliant salmon failed. Falling back to status.net hack3');
// Entirely likely that their salmon implementation is
// non-compliant. Let's try once more, this time only signing
// the data, without the precomputed blob
$salmon = replace_macros($salmon_tpl,array(
'$data' => $data,
'$encoding' => $encoding,
'$algorithm' => $algorithm,
'$keyhash' => $keyhash,
'$signature' => $signature3
));
// slap them
post_url($url,$salmon, array(
'Content-type: application/magic-envelope+xml',
'Content-length: ' . strlen($salmon)
));
$return_code = $a->get_curl_code();
}
}
logger('slapper for '.$url.' returned ' . $return_code);
if(! $return_code)
return(-1);
if(($return_code == 503) && (stristr($a->get_curl_headers(),'retry-after')))
return(-1);
if ($return_code > 299) {
logger('compliant salmon failed. Falling back to old status.net');
// Last try. This will most likely fail as well.
$xmldata = array("me:env" => array("me:data" => $data,
"@attributes" => array("type" => $data_type),
"me:encoding" => $encoding,
"me:alg" => $algorithm,
"me:sig" => $signature3,
"@attributes2" => array("key_id" => $keyhash)));
$namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env");
$salmon = xml::from_array($xmldata, $xml, false, $namespaces);
// slap them
post_url($url, $salmon, array(
'Content-type: application/magic-envelope+xml',
'Content-length: ' . strlen($salmon)
));
$return_code = $a->get_curl_code();
}
logger('slapper for '.$url.' returned ' . $return_code);
if (! $return_code) {
return(-1);
}
if (($return_code == 503) && (stristr($a->get_curl_headers(), 'retry-after'))) {
return(-1);
}
return ((($return_code >= 200) && ($return_code < 300)) ? 0 : 1);
}

View File

@ -7,6 +7,8 @@
* @todo Detect if it is a forum
*/
use \Friendica\Core\Config;
require_once('include/datetime.php');
require_once("include/Scrape.php");
require_once("include/network.php");
@ -1656,6 +1658,20 @@ function poco_discover_federation() {
}
}
// Disvover Mastodon servers
if (!Config::get('system','ostatus_disabled')) {
$serverdata = fetch_url("https://instances.mastodon.xyz/instances.json");
if ($serverdata) {
$servers = json_decode($serverdata);
foreach ($servers AS $server) {
$url = (is_null($server->https_score) ? 'http' : 'https').'://'.$server->name;
proc_run(PRIORITY_LOW, "include/discover_poco.php", "server", base64_encode($url));
}
}
}
// Currently disabled, since the service isn't available anymore.
// It is not removed since I hope that there will be a successor.
// Discover GNU Social Servers.
@ -2096,7 +2112,7 @@ function update_gcontact($contact) {
fix_alternate_contact_address($contact);
if (!isset($contact["updated"]))
$contact["updated"] = datetime_convert();
$contact["updated"] = dbm::date();
if ($contact["server_url"] == "") {
$server_url = $contact["url"];
@ -2151,7 +2167,7 @@ function update_gcontact($contact) {
dbesc($contact["gender"]), dbesc($contact["keywords"]), intval($contact["hide"]),
intval($contact["nsfw"]), intval($contact["contact-type"]), dbesc($contact["alias"]),
dbesc($contact["notify"]), dbesc($contact["url"]), dbesc($contact["location"]),
dbesc($contact["about"]), intval($contact["generation"]), dbesc($contact["updated"]),
dbesc($contact["about"]), intval($contact["generation"]), dbesc(dbm::date($contact["updated"])),
dbesc($contact["server_url"]), dbesc($contact["connect"]),
dbesc(normalise_link($contact["url"])), intval($contact["generation"]));

View File

@ -65,7 +65,7 @@ ACL.prototype.add_mention = function(id) {
if (this.element.val().indexOf( searchText) >= 0 ) {
return;
}
this.element.val(searchText + this.element.val());
this.element.val(searchText + this.element.val()).trigger('change');
}
ACL.prototype.on_submit = function(){

View File

@ -166,7 +166,7 @@ function listNewLineAutocomplete(id) {
if (word != null) {
var textBefore = text.value.substring(0, caretPos);
var textAfter = text.value.substring(caretPos, text.length);
$('#' + id).val(textBefore + '\r\n[*] ' + textAfter);
$('#' + id).val(textBefore + '\r\n[*] ' + textAfter).trigger('change');
setCaretPosition(text, caretPos + 5);
return true;
}

View File

@ -101,6 +101,7 @@
var start = textarea.selectionStart;
var end = textarea.selectionEnd;
textarea.value = textarea.value.substring(0, start) + bbcode + textarea.value.substring(end, textarea.value.length);
$(textarea).trigger('change');
});
@ -223,8 +224,11 @@
var nnm = $("#nav-notifications-menu");
nnm.html(notifications_all + notifications_mark);
var notification_lastitem = parseInt(localStorage.getItem("notification-lastitem"));
var lastItemStorageKey = "notification-lastitem:" + localUser;
var notification_lastitem = parseInt(localStorage.getItem(lastItemStorageKey));
var notification_id = 0;
// Insert notifs into the notifications-menu
$(data.notifications).each(function(key, notif){
var text = notif.message.format('<span class="contactname">' + notif.name + '</span>');
var contact = ('<a href="' + notif.url + '"><span class="contactname">' + notif.name + '</span></a>');
@ -232,19 +236,21 @@
var html = notifications_tpl.format(
notif.href, // {0} // link to the source
notif.photo, // {1} // photo of the contact
text, // {2} // preformatted text (autor + text)
text, // {2} // preformatted text (autor + text)
notif.date, // {3} // date of notification (time ago)
seenclass, // {4} // visited status of the notification
seenclass, // {4} // visited status of the notification
new Date(notif.timestamp*1000), // {5} // date of notification
notif.url, // {6} // profile url of the contact
notif.message.format(contact), // {7} // preformatted html (text including author profile url)
'' // {8} // Deprecated
'' // {8} // Deprecated
);
nnm.append(html);
});
// Desktop Notifications
$(data.notifications.reverse()).each(function(key, e){
notification_id = parseInt(e.timestamp);
if (notification_lastitem !== null && notification_id > notification_lastitem) {
if (notification_lastitem !== null && notification_id > notification_lastitem && Number(e.seen) === 0) {
if (getNotificationPermission() === "granted") {
var notification = new Notification(document.title, {
body: decodeHtml(e.message.replace('&rarr; ', '').format(e.name)),
@ -259,7 +265,7 @@
});
notification_lastitem = notification_id;
localStorage.setItem("notification-lastitem", notification_lastitem)
localStorage.setItem(lastItemStorageKey, notification_lastitem)
$("img[data-src]", nnm).each(function(i, el){
// Add src attribute for images with a data-src attribute
@ -285,7 +291,7 @@
$.jGrowl(message, {sticky: false, theme: 'info', life: 5000});
});
/* update the js scrollbars */
// Update the js scrollbars
$('#nav-notifications-menu').perfectScrollbar('update');
});
@ -317,6 +323,30 @@
}
});
// Scroll to the next/previous thread when pressing J and K
$(document).keydown(function (event) {
var threads = $('.thread_level_1');
if ((event.keyCode === 74 || event.keyCode === 75) && !$(event.target).is('textarea, input')) {
var scrollTop = $(window).scrollTop();
if (event.keyCode === 75) {
threads = $(threads.get().reverse());
}
threads.each(function(key, item) {
var comparison;
var top = $(item).offset().top - 100;
if (event.keyCode === 74) {
comparison = top > scrollTop + 1;
} else if (event.keyCode === 75) {
comparison = top < scrollTop - 1;
}
if (comparison) {
$('html, body').animate({ scrollTop: top }, 200);
return false;
}
});
}
});
// Set an event listener for infinite scroll
if(typeof infinite_scroll !== 'undefined') {
$(window).scroll(function(e){

View File

@ -1,3 +0,0 @@
~*
vendor
composer.lock

View File

@ -1,6 +0,0 @@
language: php
php:
- "5.5"
- "5.4"
- "5.3"
script: phpunit --no-configuration HTML_To_MarkdownTest ./tests/HTML_To_MarkdownTest.php

View File

@ -1,598 +0,0 @@
<?php
/**
* Class HTML_To_Markdown
*
* A helper class to convert HTML to Markdown.
*
* @version 2.2.1
* @author Nick Cernis <nick@cern.is>
* @link https://github.com/nickcernis/html2markdown/ Latest version on GitHub.
* @link http://twitter.com/nickcernis Nick on twitter.
* @license http://www.opensource.org/licenses/mit-license.php MIT
*/
class HTML_To_Markdown
{
/**
* @var DOMDocument The root of the document tree that holds our HTML.
*/
private $document;
/**
* @var string|boolean The Markdown version of the original HTML, or false if conversion failed
*/
private $output;
/**
* @var array Class-wide options users can override.
*/
private $options = array(
'header_style' => 'setext', // Set to "atx" to output H1 and H2 headers as # Header1 and ## Header2
'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML
'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output.
'bold_style' => '**', // Set to '__' if you prefer the underlined style
'italic_style' => '*', // Set to '_' if you prefer the underlined style
'remove_nodes' => '', // space-separated list of dom nodes that should be removed. example: "meta style script"
);
/**
* Constructor
*
* Set up a new DOMDocument from the supplied HTML, convert it to Markdown, and store it in $this->$output.
*
* @param string $html The HTML to convert to Markdown.
* @param array $overrides [optional] List of style and error display overrides.
*/
public function __construct($html = null, $overrides = null)
{
if ($overrides)
$this->options = array_merge($this->options, $overrides);
if ($html)
$this->convert($html);
}
/**
* Setter for conversion options
*
* @param $name
* @param $value
*/
public function set_option($name, $value)
{
$this->options[$name] = $value;
}
/**
* Convert
*
* Loads HTML and passes to get_markdown()
*
* @param $html
* @return string The Markdown version of the html
*/
public function convert($html)
{
$html = preg_replace('~>\s+<~', '><', $html); // Strip white space between tags to prevent creation of empty #text nodes
$this->document = new DOMDocument();
if ($this->options['suppress_errors'])
libxml_use_internal_errors(true); // Suppress conversion errors (from http://bit.ly/pCCRSX )
$this->document->loadHTML('<?xml encoding="UTF-8">' . $html); // Hack to load utf-8 HTML (from http://bit.ly/pVDyCt )
$this->document->encoding = 'UTF-8';
if ($this->options['suppress_errors'])
libxml_clear_errors();
return $this->get_markdown($html);
}
/**
* Is Child Of?
*
* Is the node a child of the given parent tag?
*
* @param $parent_name string|array The name of the parent node(s) to search for e.g. 'code' or array('pre', 'code')
* @param $node
* @return bool
*/
private static function is_child_of($parent_name, $node)
{
for ($p = $node->parentNode; $p != false; $p = $p->parentNode) {
if (is_null($p))
return false;
if ( is_array($parent_name) && in_array($p->nodeName, $parent_name) )
return true;
if ($p->nodeName == $parent_name)
return true;
}
return false;
}
/**
* Convert Children
*
* Recursive function to drill into the DOM and convert each node into Markdown from the inside out.
*
* Finds children of each node and convert those to #text nodes containing their Markdown equivalent,
* starting with the innermost element and working up to the outermost element.
*
* @param $node
*/
private function convert_children($node)
{
// Don't convert HTML code inside <code> and <pre> blocks to Markdown - that should stay as HTML
if (self::is_child_of(array('pre', 'code'), $node))
return;
// If the node has children, convert those to Markdown first
if ($node->hasChildNodes()) {
$length = $node->childNodes->length;
for ($i = 0; $i < $length; $i++) {
$child = $node->childNodes->item($i);
$this->convert_children($child);
}
}
// Now that child nodes have been converted, convert the original node
$markdown = $this->convert_to_markdown($node);
// Create a DOM text node containing the Markdown equivalent of the original node
$markdown_node = $this->document->createTextNode($markdown);
// Replace the old $node e.g. "<h3>Title</h3>" with the new $markdown_node e.g. "### Title"
$node->parentNode->replaceChild($markdown_node, $node);
}
/**
* Get Markdown
*
* Sends the body node to convert_children() to change inner nodes to Markdown #text nodes, then saves and
* returns the resulting converted document as a string in Markdown format.
*
* @return string|boolean The converted HTML as Markdown, or false if conversion failed
*/
private function get_markdown()
{
// Work on the entire DOM tree (including head and body)
$input = $this->document->getElementsByTagName("html")->item(0);
if (!$input)
return false;
// Convert all children of this root element. The DOMDocument stored in $this->doc will
// then consist of #text nodes, each containing a Markdown version of the original node
// that it replaced.
$this->convert_children($input);
// Sanitize and return the body contents as a string.
$markdown = $this->document->saveHTML(); // stores the DOMDocument as a string
$markdown = html_entity_decode($markdown, ENT_QUOTES, 'UTF-8');
$markdown = html_entity_decode($markdown, ENT_QUOTES, 'UTF-8'); // Double decode to cover cases like &amp;nbsp; http://www.php.net/manual/en/function.htmlentities.php#99984
$markdown = preg_replace("/<!DOCTYPE [^>]+>/", "", $markdown); // Strip doctype declaration
$unwanted = array('<html>', '</html>', '<body>', '</body>', '<head>', '</head>', '<?xml encoding="UTF-8">', '&#xD;');
$markdown = str_replace($unwanted, '', $markdown); // Strip unwanted tags
$markdown = trim($markdown, "\n\r\0\x0B");
$this->output = $markdown;
return $markdown;
}
/**
* Convert to Markdown
*
* Converts an individual node into a #text node containing a string of its Markdown equivalent.
*
* Example: An <h3> node with text content of "Title" becomes a text node with content of "### Title"
*
* @param $node
* @return string The converted HTML as Markdown
*/
private function convert_to_markdown($node)
{
$tag = $node->nodeName; // the type of element, e.g. h1
$value = $node->nodeValue; // the value of that element, e.g. The Title
// Strip nodes named in remove_nodes
$tags_to_remove = explode(' ', $this->options['remove_nodes']);
if ( in_array($tag, $tags_to_remove) )
return false;
switch ($tag) {
case "p":
$markdown = (trim($value)) ? rtrim($value) . PHP_EOL . PHP_EOL : '';
break;
case "pre":
$markdown = PHP_EOL . $this->convert_code($node) . PHP_EOL;
break;
case "h1":
case "h2":
$markdown = $this->convert_header($tag, $node);
break;
case "h3":
$markdown = "### " . $value . PHP_EOL . PHP_EOL;
break;
case "h4":
$markdown = "#### " . $value . PHP_EOL . PHP_EOL;
break;
case "h5":
$markdown = "##### " . $value . PHP_EOL . PHP_EOL;
break;
case "h6":
$markdown = "###### " . $value . PHP_EOL . PHP_EOL;
break;
case "em":
case "i":
case "strong":
case "b":
$markdown = $this->convert_emphasis($tag, $value);
break;
case "hr":
$markdown = "- - - - - -" . PHP_EOL . PHP_EOL;
break;
case "br":
$markdown = " " . PHP_EOL;
break;
case "blockquote":
$markdown = $this->convert_blockquote($node);
break;
case "code":
$markdown = $this->convert_code($node);
break;
case "ol":
case "ul":
$markdown = $value . PHP_EOL;
break;
case "li":
$markdown = $this->convert_list($node);
break;
case "img":
$markdown = $this->convert_image($node);
break;
case "a":
$markdown = $this->convert_anchor($node);
break;
case "#text":
$markdown = preg_replace('~\s+~', ' ', $value);
$markdown = preg_replace('~^#~', '\\\\#', $markdown);
break;
case "#comment":
$markdown = '';
break;
case "div":
$markdown = ($this->options['strip_tags']) ? $value . PHP_EOL . PHP_EOL : html_entity_decode($node->C14N());
break;
default:
// If strip_tags is false (the default), preserve tags that don't have Markdown equivalents,
// such as <span> nodes on their own. C14N() canonicalizes the node to a string.
// See: http://www.php.net/manual/en/domnode.c14n.php
$markdown = ($this->options['strip_tags']) ? $value : html_entity_decode($node->C14N());
}
return $markdown;
}
/**
* Convert Header
*
* Converts h1 and h2 headers to Markdown-style headers in setext style,
* matching the number of underscores with the length of the title.
*
* e.g. Header 1 Header Two
* ======== ----------
*
* Returns atx headers instead if $this->options['header_style'] is "atx"
*
* e.g. # Header 1 ## Header Two
*
* @param string $level The header level, including the "h". e.g. h1
* @param string $node The node to convert.
* @return string The Markdown version of the header.
*/
private function convert_header($level, $node)
{
$content = $node->nodeValue;
if (!$this->is_child_of('blockquote', $node) && $this->options['header_style'] == "setext") {
$length = (function_exists('mb_strlen')) ? mb_strlen($content, 'utf-8') : strlen($content);
$underline = ($level == "h1") ? "=" : "-";
$markdown = $content . PHP_EOL . str_repeat($underline, $length) . PHP_EOL . PHP_EOL; // setext style
} else {
$prefix = ($level == "h1") ? "# " : "## ";
$markdown = $prefix . $content . PHP_EOL . PHP_EOL; // atx style
}
return $markdown;
}
/**
* Converts inline styles
* This function is used to render strong and em tags
*
* eg <strong>bold text</strong> becomes **bold text** or __bold text__
*
* @param string $tag
* @param string $value
* @return string
*/
private function convert_emphasis($tag, $value)
{
if ($tag == 'i' || $tag == 'em') {
$markdown = $this->options['italic_style'] . $value . $this->options['italic_style'];
} else {
$markdown = $this->options['bold_style'] . $value . $this->options['bold_style'];
}
return $markdown;
}
/**
* Convert Image
*
* Converts <img /> tags to Markdown.
*
* e.g. <img src="/path/img.jpg" alt="alt text" title="Title" />
* becomes ![alt text](/path/img.jpg "Title")
*
* @param $node
* @return string
*/
private function convert_image($node)
{
$src = $node->getAttribute('src');
$alt = $node->getAttribute('alt');
$title = $node->getAttribute('title');
if ($title != "") {
$markdown = '![' . $alt . '](' . $src . ' "' . $title . '")'; // No newlines added. <img> should be in a block-level element.
} else {
$markdown = '![' . $alt . '](' . $src . ')';
}
return $markdown;
}
/**
* Convert Anchor
*
* Converts <a> tags to Markdown.
*
* e.g. <a href="http://modernnerd.net" title="Title">Modern Nerd</a>
* becomes [Modern Nerd](http://modernnerd.net "Title")
*
* @param $node
* @return string
*/
private function convert_anchor($node)
{
$href = $node->getAttribute('href');
$title = $node->getAttribute('title');
$text = $node->nodeValue;
if ($title != "") {
$markdown = '[' . $text . '](' . $href . ' "' . $title . '")';
} else {
$markdown = '[' . $text . '](' . $href . ')';
}
if (! $href)
$markdown = html_entity_decode($node->C14N());
// Append a space if the node after this one is also an anchor
$next_node_name = $this->get_next_node_name($node);
if ($next_node_name == 'a')
$markdown = $markdown . ' ';
return $markdown;
}
/**
* Convert List
*
* Converts <ul> and <ol> lists to Markdown.
*
* @param $node
* @return string
*/
private function convert_list($node)
{
// If parent is an ol, use numbers, otherwise, use dashes
$list_type = $node->parentNode->nodeName;
$value = $node->nodeValue;
if ($list_type == "ul") {
$markdown = "- " . trim($value) . PHP_EOL;
} else {
$number = $this->get_position($node);
$markdown = $number . ". " . trim($value) . PHP_EOL;
}
return $markdown;
}
/**
* Convert Code
*
* Convert code tags by indenting blocks of code and wrapping single lines in backticks.
*
* @param DOMNode $node
* @return string
*/
private function convert_code($node)
{
// Store the content of the code block in an array, one entry for each line
$markdown = '';
$code_content = html_entity_decode($node->C14N());
$code_content = str_replace(array("<code>", "</code>"), "", $code_content);
$code_content = str_replace(array("<pre>", "</pre>"), "", $code_content);
$lines = preg_split('/\r\n|\r|\n/', $code_content);
$total = count($lines);
// If there's more than one line of code, prepend each line with four spaces and no backticks.
if ($total > 1 || $node->nodeName === 'pre') {
// Remove the first and last line if they're empty
$first_line = trim($lines[0]);
$last_line = trim($lines[$total - 1]);
$first_line = trim($first_line, "&#xD;"); //trim XML style carriage returns too
$last_line = trim($last_line, "&#xD;");
if (empty($first_line))
array_shift($lines);
if (empty($last_line))
array_pop($lines);
$count = 1;
foreach ($lines as $line) {
$line = str_replace('&#xD;', '', $line);
$markdown .= " " . $line;
// Add newlines, except final line of the code
if ($count != $total)
$markdown .= PHP_EOL;
$count++;
}
$markdown .= PHP_EOL;
} else { // There's only one line of code. It's a code span, not a block. Just wrap it with backticks.
$markdown .= "`" . $lines[0] . "`";
}
return $markdown;
}
/**
* Convert blockquote
*
* Prepend blockquotes with > chars.
*
* @param $node
* @return string
*/
private function convert_blockquote($node)
{
// Contents should have already been converted to Markdown by this point,
// so we just need to add ">" symbols to each line.
$markdown = '';
$quote_content = trim($node->nodeValue);
$lines = preg_split('/\r\n|\r|\n/', $quote_content);
$total_lines = count($lines);
foreach ($lines as $i => $line) {
$markdown .= "> " . $line . PHP_EOL;
if ($i + 1 == $total_lines)
$markdown .= PHP_EOL;
}
return $markdown;
}
/**
* Get Position
*
* Returns the numbered position of a node inside its parent
*
* @param $node
* @return int The numbered position of the node, starting at 1.
*/
private function get_position($node)
{
// Get all of the nodes inside the parent
$list_nodes = $node->parentNode->childNodes;
$total_nodes = $list_nodes->length;
$position = 1;
// Loop through all nodes and find the given $node
for ($a = 0; $a < $total_nodes; $a++) {
$current_node = $list_nodes->item($a);
if ($current_node->isSameNode($node))
$position = $a + 1;
}
return $position;
}
/**
* Get Next Node Name
*
* Return the name of the node immediately after the passed one.
*
* @param $node
* @return string|null The node name (e.g. 'h1') or null.
*/
private function get_next_node_name($node)
{
$next_node_name = null;
$current_position = $this->get_position($node);
$next_node = $node->parentNode->childNodes->item($current_position);
if ($next_node)
$next_node_name = $next_node->nodeName;
return $next_node_name;
}
/**
* To String
*
* Magic method to return Markdown output when HTML_To_Markdown instance is treated as a string.
*
* @return string
*/
public function __toString()
{
return $this->output();
}
/**
* Output
*
* Getter for the converted Markdown contents stored in $this->output
*
* @return string
*/
public function output()
{
if (!$this->output) {
return '';
} else {
return $this->output;
}
}
}

View File

@ -1,138 +0,0 @@
HTML To Markdown for PHP
========================
A helper class that converts HTML to [Markdown](http://daringfireball.net/projects/markdown/) for your sanity and convenience.
[![Build Status](https://travis-ci.org/nickcernis/html-to-markdown.png?branch=master)](https://travis-ci.org/nickcernis/html-to-markdown)
**Version**: 2.2.1
**Requires**: PHP 5.3+
**Author**: [@nickcernis](http://twitter.com/nickcernis)
**License**: [MIT](http://www.opensource.org/licenses/mit-license.php)
### Why convert HTML to Markdown?
*"What alchemy is this?"* you mutter. *"I can see why you'd convert [Markdown to HTML](http://michelf.com/projects/php-markdown/),"* you continue, already labouring the question somewhat, *"but why go the other way?"*
Typically you would convert HTML to Markdown if:
1. You have an existing HTML document that needs to be edited by people with good taste.
2. You want to store new content in HTML format but edit it as Markdown.
3. You want to convert HTML email to plain text email.
4. You know a guy who's been converting HTML to Markdown for years, and now he can speak Elvish. You'd quite like to be able to speak Elvish.
5. You just really like Markdown.
### How to use it
Either include HTML_To_Markdown.php directly:
require_once( dirname( __FILE__) . '/HTML_To_Markdown.php' );
Or, require the library in your composer.json:
{
"require": {
"nickcernis/html-to-markdown": "dev-master"
}
}
Then `composer install` and add `require 'vendor/autoload.php';` to the top of your script.
Next, create a new HTML_To_Markdown instance, passing in your valid HTML code:
$html = "<h3>Quick, to the Batpoles!</h3>";
$markdown = new HTML_To_Markdown($html);
The `$markdown` object now contains the Markdown version of your HTML. Use it like a string:
echo $markdown; // ==> ### Quick, to the Batpoles!
Or access the Markdown output directly:
$string = $markdown->output();
The included `demo` directory contains an HTML->Markdown conversion form to try out.
### Conversion options
By default, HTML To Markdown preserves HTML tags without Markdown equivalents, like `<span>` and `<div>`.
To strip HTML tags that don't have a Markdown equivalent while preserving the content inside them, set `strip_tags` to true, like this:
$html = '<span>Turnips!</span>';
$markdown = new HTML_To_Markdown($html, array('strip_tags' => true)); // $markdown now contains "Turnips!"
Or more explicitly, like this:
$html = '<span>Turnips!</span>';
$markdown = new HTML_To_Markdown();
$markdown->set_option('strip_tags', true);
$markdown->convert($html); // $markdown now contains "Turnips!"
Note that only the tags themselves are stripped, not the content they hold.
To strip tags and their content, pass a space-separated list of tags in `remove_nodes`, like this:
$html = '<span>Turnips!</span><div>Monkeys!</div>';
$markdown = new HTML_To_Markdown($html, array('remove_nodes' => 'span div')); // $markdown now contains ""
### Style options
Bold and italic tags are converted using the asterisk syntax by default. Change this to the underlined syntax using the `bold_style` and `italic_style` options.
$html = '<em>Italic</em> and a <strong>bold</strong>';
$markdown = new HTML_To_Markdown();
$markdown->set_option('italic_style', '_');
$markdown->set_option('bold_style', '__');
$markdown->convert($html); // $markdown now contains "_Italic_ and a __bold__"
### Limitations
- Markdown Extra, MultiMarkdown and other variants aren't supported just Markdown.
### Known issues
- Nested lists and lists containing multiple paragraphs aren't converted correctly.
- Lists inside blockquotes aren't converted correctly.
- Any reported [open issues here](https://github.com/nickcernis/html-to-markdown/issues?state=open).
[Report your issue or request a feature here.](https://github.com/nickcernis/html2markdown/issues/new) Issues with patches or failing tests are especially welcome.
### Style notes
- Setext (underlined) headers are the default for H1 and H2. If you prefer the ATX style for H1 and H2 (# Header 1 and ## Header 2), set `header_style` to 'atx' in the options array when you instantiate the object:
`$markdown = new HTML_To_Markdown( $html, array('header_style'=>'atx') );`
Headers of H3 priority and lower always use atx style.
- Links and images are referenced inline. Footnote references (where image src and anchor href attributes are listed in the footnotes) are not used.
- Blockquotes aren't line wrapped it makes the converted Markdown easier to edit.
### Dependencies
HTML To Markdown requires PHP's [xml](http://www.php.net/manual/en/xml.installation.php), [lib-xml](http://www.php.net/manual/en/libxml.installation.php), and [dom](http://www.php.net/manual/en/dom.installation.php) extensions, all of which are enabled by default on most distributions.
Errors such as "Fatal error: Class 'DOMDocument' not found" on distributions such as CentOS that disable PHP's xml extension can be resolved by installing php-xml.
### Architecture notes
HTML To Markdown is a single file that uses native DOM manipulation libraries (DOMDocument), not regex voodoo, to convert code.
### Contributors
Many thanks to all [contributors](https://github.com/nickcernis/html2markdown/graphs/contributors) so far. Further improvements and feature suggestions are very welcome.
### How it works
HTML To Markdown creates a DOMDocument from the supplied HTML, walks through the tree, and converts each node to a text node containing the equivalent markdown, starting from the most deeply nested node and working inwards towards the root node.
### To-do
- Support for nested lists and lists inside blockquotes.
- Offer an option to preserve tags as HTML if they contain attributes that can't be represented with Markdown (e.g. `style`).
### Trying to convert Markdown to HTML?
Use [PHP Markdown](http://michelf.com/projects/php-markdown/) from Michel Fortin. No guarantees about the Elvish, though.

View File

@ -1,4 +0,0 @@
test:
override:
- phpunit --no-configuration HTML_To_MarkdownTest ./tests/HTML_To_MarkdownTest.php

View File

@ -1,25 +0,0 @@
{
"name": "nickcernis/html-to-markdown",
"type": "library",
"description": "An HTML-to-markdown conversion helper for PHP",
"keywords": ["markdown", "html"],
"homepage": "https://github.com/nickcernis/html-to-markdown",
"license": "MIT",
"authors": [
{
"name": "Nick Cernis",
"email": "nick@cern.is",
"homepage": "http://modernnerd.net"
}
],
"autoload": {
"classmap": [ "HTML_To_Markdown.php" ]
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"php": ">=5.3.3",
"phpunit/phpunit": "4.*"
}
}

View File

@ -1,7 +1,7 @@
<?php
/* ACL selector json backend */
require_once("include/acl_selectors.php");
require_once 'include/acl_selectors.php';
function acl_init(App $a) {
acl_lookup($a);

View File

@ -290,7 +290,8 @@ function admin_page_federation(App $a) {
foreach ($platforms as $p) {
// get a total count for the platform, the name and version of the
// highest version and the protocol tpe
$c = qu('SELECT COUNT(*) AS `total`, `platform`, `network`, `version` FROM `gserver`
$c = qu('SELECT COUNT(*) AS `total`, ANY_VALUE(`platform`) AS `platform`,
ANY_VALUE(`network`) AS `network`, MAX(`version`) AS `version` FROM `gserver`
WHERE `platform` LIKE "%s" AND `last_contact` >= `last_failure`
ORDER BY `version` ASC;', $p);
$total = $total + $c[0]['total'];
@ -474,9 +475,6 @@ function admin_page_summary(App $a) {
$r = qu("SELECT COUNT(`id`) AS `count` FROM `register`");
$pending = $r[0]['count'];
$r = qu("SELECT COUNT(*) AS `total` FROM `deliverq` WHERE 1");
$deliverq = (($r) ? $r[0]['total'] : 0);
$r = qu("SELECT COUNT(*) AS `total` FROM `queue` WHERE 1");
$queue = (($r) ? $r[0]['total'] : 0);
@ -485,7 +483,7 @@ function admin_page_summary(App $a) {
// We can do better, but this is a quick queue status
$queues = array('label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue, 'workerq' => $workerqueue);
$queues = array('label' => t('Message queues'), 'queue' => $queue, 'workerq' => $workerqueue);
$t = get_markup_template("admin_summary.tpl");
@ -655,7 +653,6 @@ function admin_page_site_post(App $a) {
$force_ssl = ((x($_POST,'force_ssl')) ? True : False);
$hide_help = ((x($_POST,'hide_help')) ? True : False);
$suppress_tags = ((x($_POST,'suppress_tags')) ? True : False);
$use_fulltext_engine = ((x($_POST,'use_fulltext_engine')) ? True : False);
$itemcache = ((x($_POST,'itemcache')) ? notags(trim($_POST['itemcache'])) : '');
$itemcache_duration = ((x($_POST,'itemcache_duration')) ? intval($_POST['itemcache_duration']) : 0);
$max_comments = ((x($_POST,'max_comments')) ? intval($_POST['max_comments']) : 0);
@ -670,6 +667,12 @@ function admin_page_site_post(App $a) {
$worker_fastlane = ((x($_POST,'worker_fastlane')) ? True : False);
$worker_frontend = ((x($_POST,'worker_frontend')) ? True : False);
// Has the directory url changed? If yes, then resubmit the existing profiles there
if ($global_directory != Config::get('system', 'directory') AND ($global_directory != '')) {
Config::set('system', 'directory', $global_directory);
proc_run(PRIORITY_LOW, 'include/directory.php');
}
if ($a->get_path() != "") {
$diaspora_enabled = false;
}
@ -773,7 +776,6 @@ function admin_page_site_post(App $a) {
set_config('system', 'allowed_email', $allowed_email);
set_config('system', 'block_public', $block_public);
set_config('system', 'publish_all', $force_publish);
set_config('system', 'directory', $global_directory);
set_config('system', 'thread_allow', $thread_allow);
set_config('system', 'newuser_private', $newuser_private);
set_config('system', 'enotify_no_content', $enotify_no_content);
@ -799,7 +801,6 @@ function admin_page_site_post(App $a) {
set_config('system', 'force_ssl', $force_ssl);
set_config('system', 'hide_help', $hide_help);
set_config('system', 'use_fulltext_engine', $use_fulltext_engine);
set_config('system', 'itemcache', $itemcache);
set_config('system', 'itemcache_duration', $itemcache_duration);
set_config('system', 'max_comments', $max_comments);
@ -971,7 +972,7 @@ function admin_page_site(App $a) {
'$banner' => array('banner', t("Banner/Logo"), $banner, ""),
'$shortcut_icon' => array('shortcut_icon', t("Shortcut icon"), get_config('system','shortcut_icon'), t("Link to an icon that will be used for browsers.")),
'$touch_icon' => array('touch_icon', t("Touch icon"), get_config('system','touch_icon'), t("Link to an icon that will be used for tablets and mobiles.")),
'$info' => array('info',t('Additional Info'), $info, sprintf(t('For public servers: you can add additional information here that will be listed at %s/siteinfo.'), get_server())),
'$info' => array('info', t('Additional Info'), $info, sprintf(t('For public servers: you can add additional information here that will be listed at %s/siteinfo.'), get_server())),
'$language' => array('language', t("System language"), get_config('system','language'), "", $lang_choices),
'$theme' => array('theme', t("System theme"), get_config('system','theme'), t("Default system theme - may be over-ridden by user profiles - <a href='#' id='cnftheme'>change theme settings</a>"), $theme_choices),
'$theme_mobile' => array('theme_mobile', t("Mobile system theme"), get_config('system','mobile-theme'), t("Theme for mobile devices"), $theme_choices_mobile),
@ -1028,7 +1029,6 @@ function admin_page_site(App $a) {
'$nodeinfo' => array('nodeinfo', t("Publish server information"), get_config('system','nodeinfo'), t("If enabled, general server and usage data will be published. The data contains the name and version of the server, number of users with public profiles, number of posts and the activated protocols and connectors. See <a href='http://the-federation.info/'>the-federation.info</a> for details.")),
'$use_fulltext_engine' => array('use_fulltext_engine', t("Use MySQL full text engine"), get_config('system','use_fulltext_engine'), t("Activates the full text engine. Speeds up search - but can only search for four and more characters.")),
'$suppress_tags' => array('suppress_tags', t("Suppress Tags"), get_config('system','suppress_tags'), t("Suppress showing a list of hashtags at the end of the posting.")),
'$itemcache' => array('itemcache', t("Path to item cache"), get_config('system','itemcache'), t("The item caches buffers generated bbcode and external images.")),
'$itemcache_duration' => array('itemcache_duration', t("Cache duration in seconds"), get_config('system','itemcache_duration'), t("How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1.")),
@ -2058,8 +2058,8 @@ function admin_page_features(App $a) {
$set = $f[3];
}
$arr[$fname][1][] = array(
array('feature_' .$f[0],$f[1],$set,$f[2],array(t('Off'),t('On'))),
array('featurelock_' .$f[0],sprintf(t('Lock feature %s'),$f[1]),(($f[4] !== false) ? "1" : ''),'',array(t('Off'),t('On')))
array('feature_' .$f[0],$f[1],$set,$f[2],array(t('Off'), t('On'))),
array('featurelock_' .$f[0],sprintf(t('Lock feature %s'),$f[1]),(($f[4] !== false) ? "1" : ''),'',array(t('Off'), t('On')))
);
}
}

View File

@ -269,8 +269,8 @@ function cal_content(App $a) {
'$tabs' => $tabs,
'$title' => t('Events'),
'$view' => t('View'),
'$previous' => array(App::get_baseurl()."/events/$prevyear/$prevmonth",t('Previous'),'',''),
'$next' => array(App::get_baseurl()."/events/$nextyear/$nextmonth",t('Next'),'',''),
'$previous' => array(App::get_baseurl()."/events/$prevyear/$prevmonth", t('Previous'),'',''),
'$next' => array(App::get_baseurl()."/events/$nextyear/$nextmonth", t('Next'),'',''),
'$calendar' => cal($y,$m,$links, ' eventcal'),
'$events' => $events,

View File

@ -872,7 +872,7 @@ function dfrn_request_content(App $a) {
'$header' => t('Friend/Connection Request'),
'$desc' => t('Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, testuser@identi.ca'),
'$pls_answer' => t('Please answer the following:'),
'$does_know_you' => array('knowyou', sprintf(t('Does %s know you?'),$a->profile['name']), false, '', array(t('No'),t('Yes'))),
'$does_know_you' => array('knowyou', sprintf(t('Does %s know you?'),$a->profile['name']), false, '', array(t('No'), t('Yes'))),
/*'$does_know' => sprintf( t('Does %s know you?'),$a->profile['name']),
'$yes' => t('Yes'),
'$no' => t('No'), */

View File

@ -110,7 +110,7 @@ function follow_content(App $a) {
//'$photo' => proxy_url($ret["photo"], false, PROXY_SIZE_SMALL),
'$desc' => "",
'$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'))),
'$add_note' => t('Add a personal note:'),
'$page_desc' => "",
'$friendica' => "",

View File

@ -75,7 +75,7 @@ function hovercard_content() {
'tags' => $contact["keywords"],
// 'nsfw' => intval($contact["nsfw"]),
// 'server_url' => $contact["server_url"],
'bd' => (($contact["birthday"] == "0000-00-00") ? "" : $contact["birthday"]),
'bd' => (($contact["birthday"] <= '0001-01-01') ? "" : $contact["birthday"]),
// 'generation' => $contact["generation"],
'account_type' => account_type($contact),
'actions' => $actions,

View File

@ -48,7 +48,7 @@ function install_post(App $a) {
$db = new dba($dbhost, $dbuser, $dbpass, '', true);
if(! get_db_errno()) {
$r = q("CREATE DATABASE '%s'",
$r = q("CREATE DATABASE '%s' DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci",
dbesc($dbdata)
);
if ($r) {

26
mod/manifest.php Normal file
View File

@ -0,0 +1,26 @@
<?php
use Friendica\Core\Config;
function manifest_content(App $a) {
$tpl = get_markup_template('manifest.tpl');
header('Content-type: application/manifest+json');
$touch_icon = Config::get('system', 'touch_icon', 'images/friendica-128.png');
if ($touch_icon == '') {
$touch_icon = 'images/friendica-128.png';
}
$o = replace_macros($tpl, array(
'$baseurl' => App::get_baseurl(),
'$touch_icon' => $touch_icon,
'$title' => Config::get('config', 'sitename', 'Friendica'),
));
echo $o;
killme();
}
?>

View File

@ -349,7 +349,7 @@ function message_content(App $a) {
$o .= $header;
$r = q("SELECT count(*) AS `total` FROM `mail`
$r = q("SELECT count(*) AS `total` FROM `mail`, ANY_VALUE(`created`) AS `created`
WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `created` DESC",
intval(local_user())
);
@ -528,12 +528,20 @@ function message_content(App $a) {
}
function get_messages($user, $lstart, $lend) {
//TODO: rewritte with a sub-query to get the first message of each private thread with certainty
return q("SELECT max(`mail`.`created`) AS `mailcreated`, min(`mail`.`seen`) AS `mailseen`,
`mail`.* , `contact`.`name`, `contact`.`url`, `contact`.`thumb` , `contact`.`network`,
count( * ) as count
ANY_VALUE(`mail`.`id`) AS `id`, ANY_VALUE(`mail`.`uid`) AS `uid`, ANY_VALUE(`mail`.`guid`) AS `guid`,
ANY_VALUE(`mail`.`from-name`) AS `from-name`, ANY_VALUE(`mail`.`from-photo`) AS `from-photo`,
ANY_VALUE(`mail`.`from-url`) AS `from-url`, ANY_VALUE(`mail`.`contact-id`) AS `contact-id`,
ANY_VALUE(`mail`.`convid`) AS `convid`, ANY_VALUE(`mail`.`title`) AS `title`, ANY_VALUE(`mail`.`body`) AS `body`,
ANY_VALUE(`mail`.`seen`) AS `seen`, ANY_VALUE(`mail`.`reply`) AS `reply`, ANY_VALUE(`mail`.`replied`) AS `replied`,
ANY_VALUE(`mail`.`unknown`) AS `unknown`, ANY_VALUE(`mail`.`uri`) AS `uri`,
`mail`.`parent-uri`,
ANY_VALUE(`mail`.`created`) AS `created`, ANY_VALUE(`contact`.`name`) AS `name`, ANY_VALUE(`contact`.`url`) AS `url`,
ANY_VALUE(`contact`.`thumb`) AS `thumb`, ANY_VALUE(`contact`.`network`) AS `network`,
count( * ) as `count`
FROM `mail` LEFT JOIN `contact` ON `mail`.`contact-id` = `contact`.`id`
WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `mailcreated` DESC LIMIT %d , %d ",
WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `mailcreated` DESC LIMIT %d , %d ",
intval($user), intval($lstart), intval($lend)
);
}

View File

@ -581,11 +581,7 @@ function network_content(App $a, $update = 0) {
$sql_order = "`item`.`id`";
$order_mode = "id";
} else {
// Disabled until final decision what to do with this
//if (get_config('system','use_fulltext_engine'))
// $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search)));
//else
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
$sql_order = "`item`.`id`";
$order_mode = "id";
}

View File

@ -292,7 +292,7 @@ function notifications_content(App $a) {
'$item_link' => $it['link'],
'$item_image' => $it['image'],
'$item_url' => $it['url'],
'$item_text' => htmlentities($it['text']),
'$item_text' => $it['text'],
'$item_when' => $it['when'],
'$item_ago' => $it['ago'],
'$item_seen' => $it['seen'],

View File

@ -1240,7 +1240,10 @@ function photos_content(App $a) {
$order = 'DESC';
}
$r = q("SELECT `resource-id`, `id`, `filename`, type, max(`scale`) AS `scale`, `desc` FROM `photo` WHERE `uid` = %d AND `album` = '%s'
$r = q("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`,
ANY_VALUE(`type`) AS `type`, max(`scale`) AS `scale`, ANY_VALUE(`desc`) as `desc`,
ANY_VALUE(`created`) as `created`
FROM `photo` WHERE `uid` = %d AND `album` = '%s'
AND `scale` <= 4 $sql_extra GROUP BY `resource-id` ORDER BY `created` $order LIMIT %d , %d",
intval($owner_uid),
dbesc($album),
@ -1581,9 +1584,9 @@ function photos_content(App $a) {
'$album' => array('albname', t('New album name'), $album_e,''),
'$caption' => array('desc', t('Caption'), $caption_e, ''),
'$tags' => array('newtag', t('Add a Tag'), "", t('Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping')),
'$rotate_none' => array('rotate',t('Do not rotate'),0,'', true),
'$rotate_cw' => array('rotate',t('Rotate CW (right)'),1,''),
'$rotate_ccw' => array('rotate',t('Rotate CCW (left)'),2,''),
'$rotate_none' => array('rotate', t('Do not rotate'),0,'', true),
'$rotate_cw' => array('rotate', t('Rotate CW (right)'),1,''),
'$rotate_ccw' => array('rotate', t('Rotate CCW (left)'),2,''),
'$nickname' => $a->data['user']['nickname'],
'$resource_id' => $ph[0]['resource-id'],
@ -1840,7 +1843,9 @@ function photos_content(App $a) {
$a->set_pager_itemspage(20);
}
$r = qu("SELECT `resource-id`, `id`, `filename`, type, `album`, max(`scale`) AS `scale` FROM `photo`
$r = qu("SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`,
ANY_VALUE(`type`) AS `type`, ANY_VALUE(`album`) AS `album`, max(`scale`) AS `scale`,
ANY_VALUE(`created`) AS `created` FROM `photo`
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s'
$sql_extra GROUP BY `resource-id` ORDER BY `created` DESC LIMIT %d , %d",
intval($a->data['user']['uid']),

View File

@ -199,7 +199,7 @@ function ping_init(App $a)
$cachekey = "ping_init:".local_user();
$ev = Cache::get($cachekey);
if (is_null($ev)) {
$ev = qu("SELECT count(`event`.`id`) AS total, type, start, adjust FROM `event`
$ev = qu("SELECT type, start, adjust FROM `event`
WHERE `event`.`uid` = %d AND `start` < '%s' AND `finish` > '%s' and `ignore` = 0
ORDER BY `start` ASC ",
intval(local_user()),
@ -212,7 +212,7 @@ function ping_init(App $a)
}
if (dbm::is_result($ev)) {
$all_events = intval($ev[0]['total']);
$all_events = count($ev);
if ($all_events) {
$str_now = datetime_convert('UTC', $a->timezone, 'now', 'Y-m-d');

View File

@ -4,6 +4,13 @@ require_once('include/Scrape.php');
function probe_content(App $a) {
if (!local_user()) {
http_status_exit(403,
array("title" => t("Public access denied."),
"description" => t("Only logged in users are permitted to perform a probing.")));
killme();
}
$o .= '<h3>Probe Diagnostic</h3>';
$o .= '<form action="probe" method="get">';

View File

@ -210,7 +210,7 @@ function profile_content(App $a, $update = 0) {
if ($update) {
$r = q("SELECT distinct(parent) AS `item_id`, `item`.`network` AS `item_network`
$r = q("SELECT distinct(parent) AS `item_id`, `item`.`network` AS `item_network`, `item`.`created`
FROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND

View File

@ -193,7 +193,7 @@ function profiles_post(App $a) {
return;
}
$dob = $_POST['dob'] ? escape_tags(trim($_POST['dob'])) : '0000-00-00'; // FIXME: Needs to be validated?
$dob = $_POST['dob'] ? escape_tags(trim($_POST['dob'])) : '0001-01-01'; // FIXME: Needs to be validated?
$y = substr($dob, 0, 4);
if ((! ctype_digit($y)) || ($y < 1900)) {
@ -201,15 +201,15 @@ function profiles_post(App $a) {
} else {
$ignore_year = false;
}
if ($dob != '0000-00-00') {
if (strpos($dob, '0000-') === 0) {
if (!in_array($dob, array('0000-00-00', '0001-01-01'))) {
if (strpos($dob, '0000-') === 0 || strpos($dob, '0001-') === 0) {
$ignore_year = true;
$dob = substr($dob, 5);
}
$dob = datetime_convert('UTC', 'UTC', (($ignore_year) ? '1900-' . $dob : $dob), (($ignore_year) ? 'm-d' : 'Y-m-d'));
if ($ignore_year) {
$dob = '0000-' . $dob;
$dob = '0001-' . $dob;
}
}
@ -637,7 +637,7 @@ function profiles_content(App $a) {
t('Hide contacts and friends:'), //Label
!!$r[0]['hide-friends'], //Value
'', //Help string
array(t('No'),t('Yes')) //Off - On strings
array(t('No'), t('Yes')) //Off - On strings
),
'$desc' => t('Hide your contact/friend list from viewers of this profile?'),
'$yes_str' => t('Yes'),
@ -739,7 +739,7 @@ function profiles_content(App $a) {
'$tv' => array('tv', t('Television'), $r[0]['tv']),
'$film' => array('film', t('Film/dance/culture/entertainment'), $r[0]['film']),
'$interest' => array('interest', t('Hobbies/Interests'), $r[0]['interest']),
'$romance' => array('romance',t('Love/romance'), $r[0]['romance']),
'$romance' => array('romance', t('Love/romance'), $r[0]['romance']),
'$work' => array('work', t('Work/employment'), $r[0]['work']),
'$education' => array('education', t('School/education'), $r[0]['education']),
'$contact' => array('contact', t('Contact information and Social Networks'), $r[0]['contact']),

View File

@ -282,7 +282,7 @@ function register_content(App $a) {
'$passwords' => $passwords,
'$password1' => array('password1', t('New Password:'), '', t('Leave empty for an auto generated password.')),
'$password2' => array('confirm', t('Confirm:'), '', ''),
'$nickdesc' => str_replace('$sitename',$a->get_hostname(),t('Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be \'<strong>nickname@$sitename</strong>\'.')),
'$nickdesc' => str_replace('$sitename',$a->get_hostname(), t('Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be \'<strong>nickname@$sitename</strong>\'.')),
'$nicklabel' => t('Choose a nickname: '),
'$photo' => $photo,
'$publish' => $profile_publish,

View File

@ -79,7 +79,7 @@ function salmon_post(App $a) {
$signed_data = $data . '.' . base64url_encode($type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($alg);
$compliant_format = str_replace('=','',$signed_data);
$compliant_format = str_replace('=', '', $signed_data);
// decode the data
@ -115,24 +115,28 @@ function salmon_post(App $a) {
// We should have everything we need now. Let's see if it verifies.
$verify = rsa_verify($compliant_format,$signature,$pubkey);
// Try GNU Social format
$verify = rsa_verify($signed_data, $signature, $pubkey);
$mode = 1;
if(! $verify) {
logger('mod-salmon: message did not verify using protocol. Trying padding hack.');
$verify = rsa_verify($signed_data,$signature,$pubkey);
if (! $verify) {
logger('mod-salmon: message did not verify using protocol. Trying compliant format.');
$verify = rsa_verify($compliant_format, $signature, $pubkey);
$mode = 2;
}
if(! $verify) {
logger('mod-salmon: message did not verify using padding. Trying old statusnet hack.');
$verify = rsa_verify($stnet_signed_data,$signature,$pubkey);
if (! $verify) {
logger('mod-salmon: message did not verify using padding. Trying old statusnet format.');
$verify = rsa_verify($stnet_signed_data, $signature, $pubkey);
$mode = 3;
}
if(! $verify) {
if (! $verify) {
logger('mod-salmon: Message did not verify. Discarding.');
http_status_exit(400);
}
logger('mod-salmon: Message verified.');
logger('mod-salmon: Message verified with mode '.$mode);
/*

View File

@ -203,18 +203,13 @@ function search_content(App $a) {
} else {
logger("Start fulltext search for '".$search."'", LOGGER_DEBUG);
// Disabled until finally is decided how to proceed with this
//if (get_config('system','use_fulltext_engine')) {
// $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search)));
//} else {
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
//}
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
$r = q("SELECT %s
FROM `item` %s
WHERE %s AND (`item`.`uid` = 0 OR (`item`.`uid` = %s AND NOT `item`.`global`))
$sql_extra
GROUP BY `item`.`uri` ORDER BY `item`.`id` DESC LIMIT %d , %d",
GROUP BY `item`.`uri`, `item`.`id` ORDER BY `item`.`id` DESC LIMIT %d , %d",
item_fieldlists(), item_joins(), item_condition(),
intval(local_user()),
intval($a->pager['start']), intval($a->pager['itemspage']));

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