diff --git a/boot.php b/boot.php index 56279f4ec8..6f036d846e 100644 --- a/boot.php +++ b/boot.php @@ -32,7 +32,6 @@ require_once('include/cache.php'); require_once('library/Mobile_Detect/Mobile_Detect.php'); require_once('include/features.php'); require_once('include/identity.php'); -require_once('include/pidfile.php'); require_once('update.php'); require_once('include/dbstructure.php'); @@ -40,7 +39,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', 1215 ); +define ( 'DB_UPDATE_VERSION', 1216 ); /** * @brief Constant with a HTML line break. @@ -442,10 +441,17 @@ define('SR_SCOPE_ALL', 'all'); define('SR_SCOPE_TAGS', 'tags'); /* @}*/ -// Normally this constant is defined - but not if "pcntl" isn't installed -if (!defined("SIGTERM")) - define("SIGTERM", 15); +/** + * Lowest possible date time value + */ +define ('NULL_DATE', '0001-01-01 00:00:00'); + + +// Normally this constant is defined - but not if "pcntl" isn't installed +if (!defined("SIGTERM")) { + define("SIGTERM", 15); +} /** * * Reverse the effect of magic_quotes_gpc if it is enabled. @@ -1346,60 +1352,25 @@ class App { return false; } - /** - * @brief Checks if the process is already running - * - * @param string $taskname The name of the task that will be used for the name of the lockfile - * @param string $task The path and name of the php script - * @param int $timeout The timeout after which a task should be killed - * - * @return bool Is the process running? - */ - function is_already_running($taskname, $task = "", $timeout = 540) { - - $lockpath = get_lockpath(); - if ($lockpath != '') { - $pidfile = new pidfile($lockpath, $taskname); - if ($pidfile->is_already_running()) { - logger("Already running"); - if ($pidfile->running_time() > $timeout) { - $pidfile->kill(); - logger("killed stale process"); - // Calling a new instance - if ($task != "") - proc_run(PRIORITY_MEDIUM, $task); - } - return true; - } - } - return false; - } - function proc_run($args) { if (!function_exists("proc_open")) { return; } - // Add the php path if it is a php call - if (count($args) && ($args[0] === 'php' OR !is_string($args[0]))) { - - // If the last worker fork was less than 10 seconds before then don't fork another one. - // This should prevent the forking of masses of workers. - if (get_config("system", "worker")) { - $cachekey = "app:proc_run:started"; - $result = Cache::get($cachekey); - if (!is_null($result)) { - if ((time() - $result) < 10) { - return; - } - } - // Set the timestamp of the last proc_run - Cache::set($cachekey, time(), CACHE_MINUTE); + // If the last worker fork was less than 10 seconds before then don't fork another one. + // This should prevent the forking of masses of workers. + $cachekey = "app:proc_run:started"; + $result = Cache::get($cachekey); + if (!is_null($result)) { + if ((time() - $result) < 10) { + return; } - - $args[0] = ((x($this->config,'php_path')) && (strlen($this->config['php_path'])) ? $this->config['php_path'] : 'php'); } + // Set the timestamp of the last proc_run + Cache::set($cachekey, time(), CACHE_MINUTE); + + array_unshift($args, ((x($this->config,'php_path')) && (strlen($this->config['php_path'])) ? $this->config['php_path'] : 'php')); // add baseurl to args. cli scripts can't construct it $args[] = $this->get_baseurl(); @@ -1976,10 +1947,9 @@ function get_max_import_size() { * @brief Wrap calls to proc_close(proc_open()) and call hook * so plugins can take part in process :) * - * @param (string|integer|array) $cmd program to run, priority or parameter array + * @param (integer|array) priority or parameter array, $cmd atrings are deprecated and are ignored * * next args are passed as $cmd command line - * e.g.: proc_run("ls","-la","/tmp"); * or: proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $drop_id); * or: proc_run(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), "include/create_shadowentry.php", $post_id); * @@ -2024,11 +1994,6 @@ function proc_run($cmd){ if (!$arr['run_cmd'] OR !count($args)) return; - if (!get_config("system", "worker") OR (is_string($run_parameter) AND ($run_parameter != 'php'))) { - $a->proc_run($args); - return; - } - $priority = PRIORITY_MEDIUM; $dont_fork = get_config("system", "worker_dont_fork"); @@ -2063,7 +2028,7 @@ function proc_run($cmd){ } // Checking number of workers - $workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'"); + $workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` > '%s'", dbesc(NULL_DATE)); // Get number of allowed number of worker threads $queues = intval(get_config("system", "worker_queues")); @@ -2076,7 +2041,7 @@ function proc_run($cmd){ return; // Now call the poller to execute the jobs that we just added to the queue - $args = array("php", "include/poller.php", "no_cron"); + $args = array("include/poller.php", "no_cron"); $a->proc_run($args); } @@ -2410,38 +2375,6 @@ function get_itemcachepath() { return ""; } -function get_lockpath() { - $lockpath = get_config('system','lockpath'); - if (($lockpath != "") AND App::directory_usable($lockpath)) { - // We have a lock path and it is usable - return $lockpath; - } - - // We don't have a working preconfigured lock path, so we take the temp path. - $temppath = get_temppath(); - - if ($temppath != "") { - // To avoid any interferences with other systems we create our own directory - $lockpath = $temppath."/lock"; - if (!is_dir($lockpath)) { - mkdir($lockpath); - } - - if (App::directory_usable($lockpath)) { - // The new path is usable, we are happy - set_config("system", "lockpath", $lockpath); - return $lockpath; - } else { - // We can't create a subdirectory, strange. - // But the directory seems to work, so we use it but don't store it. - return $temppath; - } - } - - // Reaching this point means that the operating system is configured badly. - return ""; -} - /** * @brief Returns the path where spool files are stored * diff --git a/database.sql b/database.sql index b133489e4e..7ed19f439c 100644 --- a/database.sql +++ b/database.sql @@ -1,5 +1,5 @@ -- ------------------------------------------ --- Friendica 3.5.1-rc (Asparagus) +-- Friendica 3.5.2-dev (Asparagus) -- DB_UPDATE_VERSION 1215 -- ------------------------------------------ @@ -30,8 +30,8 @@ CREATE TABLE IF NOT EXISTS `attach` ( `filetype` varchar(64) NOT NULL DEFAULT '', `filesize` int(11) NOT NULL DEFAULT 0, `data` longblob NOT NULL, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `allow_cid` mediumtext, `allow_gid` mediumtext, `deny_cid` mediumtext, @@ -58,7 +58,7 @@ CREATE TABLE IF NOT EXISTS `cache` ( `k` varbinary(255) NOT NULL, `v` mediumtext, `expire_mode` int(11) NOT NULL DEFAULT 0, - `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`k`), INDEX `expire_mode_updated` (`expire_mode`,`updated`) ) DEFAULT CHARSET=utf8mb4; @@ -107,7 +107,7 @@ CREATE TABLE IF NOT EXISTS `config` ( CREATE TABLE IF NOT EXISTS `contact` ( `id` int(11) NOT NULL auto_increment, `uid` int(11) NOT NULL DEFAULT 0, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `self` tinyint(1) NOT NULL DEFAULT 0, `remote_self` tinyint(1) NOT NULL DEFAULT 0, `rel` tinyint(1) NOT NULL DEFAULT 0, @@ -145,14 +145,14 @@ CREATE TABLE IF NOT EXISTS `contact` ( `usehub` tinyint(1) NOT NULL DEFAULT 0, `subhub` tinyint(1) NOT NULL DEFAULT 0, `hub-verify` varchar(255) NOT NULL DEFAULT '', - `last-update` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `success_update` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `failure_update` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `name-date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `uri-date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `avatar-date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `term-date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `last-item` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `last-update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `success_update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `failure_update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `name-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `uri-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `avatar-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `term-date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `last-item` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `priority` tinyint(3) NOT NULL DEFAULT 0, `blocked` tinyint(1) NOT NULL DEFAULT 1, `readonly` tinyint(1) NOT NULL DEFAULT 0, @@ -197,25 +197,13 @@ CREATE TABLE IF NOT EXISTS `conv` ( `recips` text, `uid` int(11) NOT NULL DEFAULT 0, `creator` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `subject` text, PRIMARY KEY(`id`), INDEX `uid` (`uid`) ) DEFAULT CHARSET=utf8mb4; --- --- TABLE deliverq --- -CREATE TABLE IF NOT EXISTS `deliverq` ( - `id` int(10) unsigned NOT NULL auto_increment, - `cmd` varbinary(32) NOT NULL DEFAULT '', - `item` int(11) NOT NULL DEFAULT 0, - `contact` int(11) NOT NULL DEFAULT 0, - PRIMARY KEY(`id`), - UNIQUE INDEX `cmd_item_contact` (`cmd`,`item`,`contact`) -) DEFAULT CHARSET=utf8mb4; - -- -- TABLE event -- @@ -225,10 +213,10 @@ CREATE TABLE IF NOT EXISTS `event` ( `uid` int(11) NOT NULL DEFAULT 0, `cid` int(11) NOT NULL DEFAULT 0, `uri` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `start` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `finish` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `start` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `finish` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `summary` text, `desc` text, `location` text, @@ -264,7 +252,7 @@ CREATE TABLE IF NOT EXISTS `fcontact` ( `network` varchar(32) NOT NULL DEFAULT '', `alias` varchar(255) NOT NULL DEFAULT '', `pubkey` text, - `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`), INDEX `addr` (`addr`(32)), INDEX `url` (`url`) @@ -305,7 +293,7 @@ CREATE TABLE IF NOT EXISTS `fsuggest` ( `request` varchar(255) NOT NULL DEFAULT '', `photo` varchar(255) NOT NULL DEFAULT '', `note` text, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`) ) DEFAULT CHARSET=utf8mb4; @@ -332,10 +320,10 @@ CREATE TABLE IF NOT EXISTS `gcontact` ( `nurl` varchar(255) NOT NULL DEFAULT '', `photo` varchar(255) NOT NULL DEFAULT '', `connect` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `updated` datetime DEFAULT '0000-00-00 00:00:00', - `last_contact` datetime DEFAULT '0000-00-00 00:00:00', - `last_failure` datetime DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `updated` datetime DEFAULT '0001-01-01 00:00:00', + `last_contact` datetime DEFAULT '0001-01-01 00:00:00', + `last_failure` datetime DEFAULT '0001-01-01 00:00:00', `location` varchar(255) NOT NULL DEFAULT '', `about` text, `keywords` text, @@ -369,7 +357,7 @@ CREATE TABLE IF NOT EXISTS `glink` ( `uid` int(11) NOT NULL DEFAULT 0, `gcid` int(11) NOT NULL DEFAULT 0, `zcid` int(11) NOT NULL DEFAULT 0, - `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`), UNIQUE INDEX `cid_uid_gcid_zcid` (`cid`,`uid`,`gcid`,`zcid`), INDEX `gcid` (`gcid`) @@ -417,10 +405,10 @@ CREATE TABLE IF NOT EXISTS `gserver` ( `noscrape` varchar(255) NOT NULL DEFAULT '', `network` varchar(32) NOT NULL DEFAULT '', `platform` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `last_poco_query` datetime DEFAULT '0000-00-00 00:00:00', - `last_contact` datetime DEFAULT '0000-00-00 00:00:00', - `last_failure` datetime DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `last_poco_query` datetime DEFAULT '0001-01-01 00:00:00', + `last_contact` datetime DEFAULT '0001-01-01 00:00:00', + `last_failure` datetime DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`), INDEX `nurl` (`nurl`(32)) ) DEFAULT CHARSET=utf8mb4; @@ -450,7 +438,7 @@ CREATE TABLE IF NOT EXISTS `intro` ( `duplex` tinyint(1) NOT NULL DEFAULT 0, `note` text, `hash` varchar(255) NOT NULL DEFAULT '', - `datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `datetime` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `blocked` tinyint(1) NOT NULL DEFAULT 1, `ignore` tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY(`id`) @@ -473,11 +461,11 @@ CREATE TABLE IF NOT EXISTS `item` ( `parent-uri` varchar(255) NOT NULL DEFAULT '', `extid` varchar(255) NOT NULL DEFAULT '', `thr-parent` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `commented` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `received` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `changed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `commented` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `received` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `changed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `owner-id` int(11) NOT NULL DEFAULT 0, `owner-name` varchar(255) NOT NULL DEFAULT '', `owner-link` varchar(255) NOT NULL DEFAULT '', @@ -576,7 +564,7 @@ CREATE TABLE IF NOT EXISTS `locks` ( `id` int(11) NOT NULL auto_increment, `name` varchar(128) NOT NULL DEFAULT '', `locked` tinyint(1) NOT NULL DEFAULT 0, - `created` datetime DEFAULT '0000-00-00 00:00:00', + `created` datetime DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`) ) DEFAULT CHARSET=utf8mb4; @@ -600,7 +588,7 @@ CREATE TABLE IF NOT EXISTS `mail` ( `unknown` tinyint(1) NOT NULL DEFAULT 0, `uri` varchar(255) NOT NULL DEFAULT '', `parent-uri` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`), INDEX `uid_seen` (`uid`,`seen`), INDEX `convid` (`convid`), @@ -624,7 +612,7 @@ CREATE TABLE IF NOT EXISTS `mailacct` ( `action` int(11) NOT NULL DEFAULT 0, `movetofolder` varchar(255) NOT NULL DEFAULT '', `pubmail` tinyint(1) NOT NULL DEFAULT 0, - `last_check` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `last_check` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`) ) DEFAULT CHARSET=utf8mb4; @@ -649,7 +637,7 @@ CREATE TABLE IF NOT EXISTS `notify` ( `name` varchar(255) NOT NULL DEFAULT '', `url` varchar(255) NOT NULL DEFAULT '', `photo` varchar(255) NOT NULL DEFAULT '', - `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `msg` mediumtext, `uid` int(11) NOT NULL DEFAULT 0, `link` varchar(255) NOT NULL DEFAULT '', @@ -685,7 +673,7 @@ CREATE TABLE IF NOT EXISTS `notify-threads` ( CREATE TABLE IF NOT EXISTS `oembed` ( `url` varbinary(255) NOT NULL, `content` mediumtext, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`url`), INDEX `created` (`created`) ) DEFAULT CHARSET=utf8mb4; @@ -698,7 +686,7 @@ CREATE TABLE IF NOT EXISTS `parsed_url` ( `guessing` tinyint(1) NOT NULL DEFAULT 0, `oembed` tinyint(1) NOT NULL DEFAULT 0, `content` mediumtext, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`url`,`guessing`,`oembed`), INDEX `created` (`created`) ) DEFAULT CHARSET=utf8mb4; @@ -725,8 +713,8 @@ CREATE TABLE IF NOT EXISTS `photo` ( `contact-id` int(10) unsigned NOT NULL DEFAULT 0, `guid` varchar(64) NOT NULL DEFAULT '', `resource-id` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `title` varchar(255) NOT NULL DEFAULT '', `desc` text, `album` varchar(255) NOT NULL DEFAULT '', @@ -788,7 +776,7 @@ CREATE TABLE IF NOT EXISTS `poll_result` ( CREATE TABLE IF NOT EXISTS `process` ( `pid` int(10) unsigned NOT NULL, `command` varbinary(32) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`pid`), INDEX `command` (`command`) ) DEFAULT CHARSET=utf8mb4; @@ -814,7 +802,7 @@ CREATE TABLE IF NOT EXISTS `profile` ( `gender` varchar(32) NOT NULL DEFAULT '', `marital` varchar(255) NOT NULL DEFAULT '', `with` text, - `howlong` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `howlong` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `sexual` varchar(255) NOT NULL DEFAULT '', `politic` varchar(255) NOT NULL DEFAULT '', `religion` varchar(255) NOT NULL DEFAULT '', @@ -866,7 +854,7 @@ CREATE TABLE IF NOT EXISTS `push_subscriber` ( `topic` varchar(255) NOT NULL DEFAULT '', `nickname` varchar(255) NOT NULL DEFAULT '', `push` int(11) NOT NULL DEFAULT 0, - `last_update` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `last_update` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `secret` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY(`id`) ) DEFAULT CHARSET=utf8mb4; @@ -878,8 +866,8 @@ CREATE TABLE IF NOT EXISTS `queue` ( `id` int(11) NOT NULL auto_increment, `cid` int(11) NOT NULL DEFAULT 0, `network` varchar(32) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `last` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `last` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `content` mediumtext, `batch` tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY(`id`), @@ -896,7 +884,7 @@ CREATE TABLE IF NOT EXISTS `queue` ( CREATE TABLE IF NOT EXISTS `register` ( `id` int(11) unsigned NOT NULL auto_increment, `hash` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `uid` int(11) unsigned NOT NULL DEFAULT 0, `password` varchar(255) NOT NULL DEFAULT '', `language` varchar(16) NOT NULL DEFAULT '', @@ -950,7 +938,7 @@ CREATE TABLE IF NOT EXISTS `spam` ( `spam` int(11) NOT NULL DEFAULT 0, `ham` int(11) NOT NULL DEFAULT 0, `term` varchar(255) NOT NULL DEFAULT '', - `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`), INDEX `uid` (`uid`), INDEX `spam` (`spam`), @@ -969,8 +957,8 @@ CREATE TABLE IF NOT EXISTS `term` ( `term` varchar(255) NOT NULL DEFAULT '', `url` varchar(255) NOT NULL DEFAULT '', `guid` varchar(255) NOT NULL DEFAULT '', - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `received` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `received` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `global` tinyint(1) NOT NULL DEFAULT 0, `aid` int(10) unsigned NOT NULL DEFAULT 0, `uid` int(10) unsigned NOT NULL DEFAULT 0, @@ -991,11 +979,11 @@ CREATE TABLE IF NOT EXISTS `thread` ( `gcontact-id` int(11) unsigned NOT NULL DEFAULT 0, `owner-id` int(11) unsigned NOT NULL DEFAULT 0, `author-id` int(11) unsigned NOT NULL DEFAULT 0, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `commented` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `received` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `changed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `commented` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `received` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `changed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `wall` tinyint(1) NOT NULL DEFAULT 0, `private` tinyint(1) NOT NULL DEFAULT 0, `pubmail` tinyint(1) NOT NULL DEFAULT 0, @@ -1047,8 +1035,8 @@ CREATE TABLE IF NOT EXISTS `user` ( `openid` varchar(255) NOT NULL DEFAULT '', `timezone` varchar(128) NOT NULL DEFAULT '', `language` varchar(32) NOT NULL DEFAULT 'en', - `register_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `login_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `register_date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `login_date` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `default-location` varchar(255) NOT NULL DEFAULT '', `allow_location` tinyint(1) NOT NULL DEFAULT 0, `theme` varchar(255) NOT NULL DEFAULT '', @@ -1072,8 +1060,8 @@ CREATE TABLE IF NOT EXISTS `user` ( `expire` int(11) unsigned NOT NULL DEFAULT 0, `account_removed` tinyint(1) NOT NULL DEFAULT 0, `account_expired` tinyint(1) NOT NULL DEFAULT 0, - `account_expires_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `expire_notification_sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `account_expires_on` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', + `expire_notification_sent` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `service_class` varchar(32) NOT NULL DEFAULT '', `def_gid` int(11) NOT NULL DEFAULT 0, `allow_cid` mediumtext, @@ -1102,9 +1090,9 @@ CREATE TABLE IF NOT EXISTS `workerqueue` ( `id` int(11) NOT NULL auto_increment, `parameter` text, `priority` tinyint(3) unsigned NOT NULL DEFAULT 0, - `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', `pid` int(11) NOT NULL DEFAULT 0, - `executed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `executed` datetime NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY(`id`) ) DEFAULT CHARSET=utf8mb4; diff --git a/doc/Settings.md b/doc/Settings.md index 9590ad42d6..5055ed7d23 100644 --- a/doc/Settings.md +++ b/doc/Settings.md @@ -152,13 +152,6 @@ Value is in seconds. Default is 60 seconds. Set to 0 for unlimited (not recommended). -#### UTF-8 Regular Expressions - -During registrations, full names are checked using UTF-8 regular expressions. -This requires PHP to have been compiled with a special setting to allow UTF-8 expressions. -If you are completely unable to register accounts, set no_utf to true. -The default is set to false (meaning UTF8 regular expressions are supported and working). - #### Verify SSL Certitificates By default Friendica allows SSL communication between websites that have "self-signed" SSL certificates. diff --git a/include/Contact.php b/include/Contact.php index 9fd61f8d5e..fc9f660f13 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -127,7 +127,7 @@ function mark_for_death($contact) { if($contact['archive']) return; - if($contact['term-date'] == '0000-00-00 00:00:00') { + if ($contact['term-date'] <= NULL_DATE) { q("UPDATE `contact` SET `term-date` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($contact['id']) @@ -185,13 +185,13 @@ function unmark_for_death($contact) { // It's a miracle. Our dead contact has inexplicably come back to life. q("UPDATE `contact` SET `term-date` = '%s' WHERE `id` = %d", - dbesc('0000-00-00 00:00:00'), + dbesc(NULL_DATE), intval($contact['id']) ); if ($contact['url'] != '') { q("UPDATE `contact` SET `term-date` = '%s' WHERE `nurl` = '%s'", - dbesc('0000-00-00 00:00:00'), + dbesc(NULL_DATE), dbesc(normalise_link($contact['url'])) ); } diff --git a/include/create_shadowentry.php b/include/create_shadowentry.php index 005295c978..98db23f9ef 100644 --- a/include/create_shadowentry.php +++ b/include/create_shadowentry.php @@ -6,26 +6,9 @@ * This script is started from mod/item.php to save some time when doing a post. */ -use \Friendica\Core\Config; - -require_once("boot.php"); require_once("include/threads.php"); function create_shadowentry_run($argv, $argc) { - global $a, $db; - - if (is_null($a)) - $a = new App; - - if (is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - } - - Config::load(); - if ($argc != 2) { return; } @@ -34,9 +17,4 @@ function create_shadowentry_run($argv, $argc) { add_shadow_entry($message_id); } - -if (array_search(__file__,get_included_files())===0){ - create_shadowentry_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} ?> diff --git a/include/cron.php b/include/cron.php index 2fc8de51c5..58a3fcf9ce 100644 --- a/include/cron.php +++ b/include/cron.php @@ -1,62 +1,24 @@ maxload_reached()) - return; - if (App::is_already_running('cron', 'include/cron.php', 540)) - return; + // Poll contacts with specific parameters + if ($argc > 1) { + cron_poll_contacts($argc, $argv); + return; } $last = get_config('system','last_cron'); $poll_interval = intval(get_config('system','cron_interval')); - if(! $poll_interval) + if (! $poll_interval) { $poll_interval = 10; - - if($last) { + } + if ($last) { $next = $last + ($poll_interval * 60); if($next > time()) { logger('cron intervall not reached'); @@ -64,64 +26,50 @@ function cron_run(&$argv, &$argc){ } } - $a->set_baseurl(get_config('system','url')); - - load_hooks(); - logger('cron: start'); // run queue delivery process in the background - proc_run(PRIORITY_NEGLIGIBLE, "include/queue.php"); // run the process to discover global contacts in the background - proc_run(PRIORITY_LOW, "include/discover_poco.php"); // run the process to update locally stored global contacts in the background - proc_run(PRIORITY_LOW, "include/discover_poco.php", "checkcontact"); // Expire and remove user entries - cron_expire_and_remove_users(); + proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "expire_and_remove_users"); - // If the worker is active, split the jobs in several sub processes - if (get_config("system", "worker")) { - // Check OStatus conversations - proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_mentions"); + // Check OStatus conversations + proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_mentions"); - // Check every conversation - proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_conversations"); + // Check every conversation + proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_conversations"); - // Call possible post update functions - proc_run(PRIORITY_LOW, "include/cronjobs.php", "post_update"); + // Call possible post update functions + proc_run(PRIORITY_LOW, "include/cronjobs.php", "post_update"); - // update nodeinfo data - proc_run(PRIORITY_LOW, "include/cronjobs.php", "nodeinfo"); - } else { - // Check OStatus conversations - // Check only conversations with mentions (for a longer time) - ostatus::check_conversations(true); + // update nodeinfo data + proc_run(PRIORITY_LOW, "include/cronjobs.php", "nodeinfo"); - // Check every conversation - ostatus::check_conversations(false); + // Clear cache entries + proc_run(PRIORITY_LOW, "include/cronjobs.php", "clear_cache"); - // Call possible post update functions - // see include/post_update.php for more details - post_update(); + // Repair missing Diaspora values in contacts + proc_run(PRIORITY_LOW, "include/cronjobs.php", "repair_diaspora"); - // update nodeinfo data - nodeinfo_cron(); - } + // Repair entries in the database + 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')); if($d2 != intval($d1)) { - update_contact_birthdays(); + proc_run(PRIORITY_LOW, "include/cronjobs.php", "update_contact_birthdays"); + + proc_run(PRIORITY_LOW, "include/discover_poco.php", "update_server"); proc_run(PRIORITY_LOW, "include/discover_poco.php", "suggestions"); @@ -131,18 +79,9 @@ function cron_run(&$argv, &$argc){ proc_run(PRIORITY_MEDIUM, 'include/dbclean.php'); - cron_update_photo_albums(); + proc_run(PRIORITY_LOW, "include/cronjobs.php", "update_photo_albums"); } - // Clear cache entries - cron_clear_cache($a); - - // Repair missing Diaspora values in contacts - cron_repair_diaspora($a); - - // Repair entries in the database - cron_repair_database(); - // Poll contacts cron_poll_contacts($argc, $argv); @@ -153,39 +92,6 @@ function cron_run(&$argv, &$argc){ return; } -/** - * @brief Update the cached values for the number of photo albums per user - */ -function cron_update_photo_albums() { - $r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`"); - if (!dbm::is_result($r)) { - return; - } - - foreach ($r AS $user) { - photo_albums($user['uid'], true); - } -} - -/** - * @brief Expire and remove user entries - */ -function cron_expire_and_remove_users() { - // expire any expired accounts - q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0 - AND `account_expires_on` != '0000-00-00 00:00:00' - AND `account_expires_on` < UTC_TIMESTAMP() "); - - // delete user and contact records for recently removed accounts - $r = q("SELECT * FROM `user` WHERE `account_removed` AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); - if ($r) { - foreach($r as $user) { - q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid'])); - q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid'])); - } - } -} - /** * @brief Poll contacts for unreceived messages * @@ -198,14 +104,15 @@ function cron_poll_contacts($argc, $argv) { $force = false; $restart = false; - if (($argc > 1) && ($argv[1] == 'force')) + if (($argc > 1) && ($argv[1] == 'force')) { $force = true; - + } if (($argc > 1) && ($argv[1] == 'restart')) { $restart = true; $generation = intval($argv[2]); - if (!$generation) + if (!$generation) { killme(); + } } if (($argc > 1) && intval($argv[1])) { @@ -213,14 +120,6 @@ function cron_poll_contacts($argc, $argv) { $force = true; } - $interval = intval(get_config('system','poll_interval')); - if (!$interval) - $interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval'))); - - // If we are using the worker we don't need a delivery interval - if (get_config("system", "worker")) - $interval = false; - $sql_extra = (($manual_id) ? " AND `id` = $manual_id " : ""); reload_plugins(); @@ -232,9 +131,9 @@ function cron_poll_contacts($argc, $argv) { // we are unable to match those posts with a Diaspora GUID and prevent duplicates. $abandon_days = intval(get_config('system','account_abandon_days')); - if($abandon_days < 1) + if ($abandon_days < 1) { $abandon_days = 0; - + } $abandon_sql = (($abandon_days) ? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days)) : '' @@ -275,13 +174,15 @@ function cron_poll_contacts($argc, $argv) { $xml = false; - if($manual_id) - $contact['last-update'] = '0000-00-00 00:00:00'; + if ($manual_id) { + $contact['last-update'] = NULL_DATE; + } - if(in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) + if (in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) { $contact['priority'] = 2; + } - if($contact['subhub'] AND in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) { + 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 @@ -303,193 +204,44 @@ function cron_poll_contacts($argc, $argv) { 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; } - if (!$update) + if (!$update) { continue; + } } 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', $contact['id']); + proc_run(PRIORITY_MEDIUM, 'include/onepoll.php', intval($contact['id'])); } else { - proc_run(PRIORITY_LOW, 'include/onepoll.php', $contact['id']); - } - - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } -} - -/** - * @brief Clear cache entries - * - * @param App $a - */ -function cron_clear_cache(App $a) { - - $last = get_config('system','cache_last_cleared'); - - if($last) { - $next = $last + (3600); // Once per hour - $clear_cache = ($next <= time()); - } else - $clear_cache = true; - - if (!$clear_cache) - return; - - // clear old cache - Cache::clear(); - - // clear old item cache files - clear_cache(); - - // clear cache for photos - clear_cache($a->get_basepath(), $a->get_basepath()."/photo"); - - // clear smarty cache - clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled"); - - // clear cache for image proxy - if (!get_config("system", "proxy_disabled")) { - clear_cache($a->get_basepath(), $a->get_basepath()."/proxy"); - - $cachetime = get_config('system','proxy_cache_time'); - if (!$cachetime) $cachetime = PROXY_DEFAULT_TIME; - - q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime); - } - - // Delete the cached OEmbed entries that are older than one year - q("DELETE FROM `oembed` WHERE `created` < NOW() - INTERVAL 3 MONTH"); - - // Delete the cached "parse_url" entries that are older than one year - q("DELETE FROM `parsed_url` WHERE `created` < NOW() - INTERVAL 3 MONTH"); - - // Maximum table size in megabyte - $max_tablesize = intval(get_config('system','optimize_max_tablesize')) * 1000000; - if ($max_tablesize == 0) - $max_tablesize = 100 * 1000000; // Default are 100 MB - - if ($max_tablesize > 0) { - // Minimum fragmentation level in percent - $fragmentation_level = intval(get_config('system','optimize_fragmentation')) / 100; - if ($fragmentation_level == 0) - $fragmentation_level = 0.3; // Default value is 30% - - // Optimize some tables that need to be optimized - $r = q("SHOW TABLE STATUS"); - foreach($r as $table) { - - // Don't optimize tables that are too large - if ($table["Data_length"] > $max_tablesize) - continue; - - // Don't optimize empty tables - if ($table["Data_length"] == 0) - continue; - - // Calculate fragmentation - $fragmentation = $table["Data_free"] / ($table["Data_length"] + $table["Index_length"]); - - logger("Table ".$table["Name"]." - Fragmentation level: ".round($fragmentation * 100, 2), LOGGER_DEBUG); - - // Don't optimize tables that needn't to be optimized - if ($fragmentation < $fragmentation_level) - continue; - - // So optimize it - logger("Optimize Table ".$table["Name"], LOGGER_DEBUG); - q("OPTIMIZE TABLE `%s`", dbesc($table["Name"])); - } - } - - set_config('system','cache_last_cleared', time()); -} - -/** - * @brief Repair missing values in Diaspora contacts - * - * @param App $a - */ -function cron_repair_diaspora(App $a) { - $r = q("SELECT `id`, `url` FROM `contact` - WHERE `network` = '%s' AND (`batch` = '' OR `notify` = '' OR `poll` = '' OR pubkey = '') - ORDER BY RAND() LIMIT 50", dbesc(NETWORK_DIASPORA)); - if (dbm::is_result($r)) { - foreach ($r AS $contact) { - if (poco_reachable($contact["url"])) { - $data = probe_url($contact["url"]); - if ($data["network"] == NETWORK_DIASPORA) { - logger("Repair contact ".$contact["id"]." ".$contact["url"], LOGGER_DEBUG); - q("UPDATE `contact` SET `batch` = '%s', `notify` = '%s', `poll` = '%s', pubkey = '%s' WHERE `id` = %d", - dbesc($data["batch"]), dbesc($data["notify"]), dbesc($data["poll"]), dbesc($data["pubkey"]), - intval($contact["id"])); - } + proc_run(PRIORITY_LOW, 'include/onepoll.php', intval($contact['id'])); } } } } - -/** - * @brief Do some repairs in database entries - * - */ -function cron_repair_database() { - - // Sometimes there seem to be issues where the "self" contact vanishes. - // We haven't found the origin of the problem by now. - $r = q("SELECT `uid` FROM `user` WHERE NOT EXISTS (SELECT `uid` FROM `contact` WHERE `contact`.`uid` = `user`.`uid` AND `contact`.`self`)"); - if (dbm::is_result($r)) { - foreach ($r AS $user) { - logger('Create missing self contact for user '.$user['uid']); - user_create_self_contact($user['uid']); - } - } - - // Set the parent if it wasn't set. (Shouldn't happen - but does sometimes) - // This call is very "cheap" so we can do it at any time without a problem - q("UPDATE `item` INNER JOIN `item` AS `parent` ON `parent`.`uri` = `item`.`parent-uri` AND `parent`.`uid` = `item`.`uid` SET `item`.`parent` = `parent`.`id` WHERE `item`.`parent` = 0"); - - // There was an issue where the nick vanishes from the contact table - q("UPDATE `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` SET `nick` = `nickname` WHERE `self` AND `nick`=''"); - - // Update the global contacts for local users - $r = q("SELECT `uid` FROM `user` WHERE `verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired`"); - if (dbm::is_result($r)) - foreach ($r AS $user) - update_gcontact_for_user($user["uid"]); - - /// @todo - /// - remove thread entries without item - /// - remove sign entries without item - /// - remove children when parent got lost - /// - set contact-id in item when not present -} - -if (array_search(__file__,get_included_files())===0){ - cron_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/cronhooks.php b/include/cronhooks.php index 72b86be427..bea0f6a198 100644 --- a/include/cronhooks.php +++ b/include/cronhooks.php @@ -2,37 +2,11 @@ use \Friendica\Core\Config; -require_once("boot.php"); - function cronhooks_run(&$argv, &$argc){ - global $a, $db; + global $a; - if(is_null($a)) { - $a = new App; - } - - if(is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; - - require_once('include/session.php'); require_once('include/datetime.php'); - Config::load(); - - // Don't check this stuff if the function is called by the poller - if (App::callstack() != "poller_run") { - if ($a->maxload_reached()) - return; - if (App::is_already_running('cronhooks', 'include/cronhooks.php', 1140)) - return; - } - - load_hooks(); - if (($argc == 2) AND is_array($a->hooks) AND array_key_exists("cron", $a->hooks)) { foreach ($a->hooks["cron"] as $hook) if ($hook[1] == $argv[1]) { @@ -42,7 +16,7 @@ function cronhooks_run(&$argv, &$argc){ return; } - $last = get_config('system','last_cronhook'); + $last = get_config('system', 'last_cronhook'); $poll_interval = intval(get_config('system','cronhook_interval')); if(! $poll_interval) @@ -62,22 +36,16 @@ function cronhooks_run(&$argv, &$argc){ $d = datetime_convert(); - if (get_config("system", "worker") AND is_array($a->hooks) AND array_key_exists("cron", $a->hooks)) { + 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); proc_run(PRIORITY_MEDIUM, "include/cronhooks.php", $hook[1]); } - } else - call_hooks('cron', $d); + } logger('cronhooks: end'); - set_config('system','last_cronhook', time()); + set_config('system', 'last_cronhook', time()); return; } - -if (array_search(__file__,get_included_files())===0){ - cronhooks_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/cronjobs.php b/include/cronjobs.php index f0a56370b8..79ee32bb37 100644 --- a/include/cronjobs.php +++ b/include/cronjobs.php @@ -1,47 +1,24 @@ set_baseurl(get_config('system','url')); + require_once('include/photos.php'); + require_once('include/user.php'); + require_once('include/socgraph.php'); + require_once('include/Probe.php'); // No parameter set? So return - if ($argc <= 1) + if ($argc <= 1) { return; + } + + logger("Starting cronjob ".$argv[1], LOGGER_DEBUG); // Check OStatus conversations // Check only conversations with mentions (for a longer time) @@ -69,10 +46,244 @@ function cronjobs_run(&$argv, &$argc){ return; } + // Expire and remove user entries + if ($argv[1] == 'expire_and_remove_users') { + cron_expire_and_remove_users(); + return; + } + + if ($argv[1] == 'update_contact_birthdays') { + update_contact_birthdays(); + return; + } + + if ($argv[1] == 'update_photo_albums') { + cron_update_photo_albums(); + return; + } + + // Clear cache entries + if ($argv[1] == 'clear_cache') { + cron_clear_cache($a); + return; + } + + // Repair missing Diaspora values in contacts + if ($argv[1] == 'repair_diaspora') { + cron_repair_diaspora($a); + return; + } + + // Repair entries in the database + if ($argv[1] == 'repair_database') { + cron_repair_database(); + return; + } + + logger("Xronjob ".$argv[1]." is unknown.", LOGGER_DEBUG); + return; } -if (array_search(__file__,get_included_files())===0){ - cronjobs_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); +/** + * @brief Update the cached values for the number of photo albums per user + */ +function cron_update_photo_albums() { + $r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`"); + if (!dbm::is_result($r)) { + return; + } + + foreach ($r AS $user) { + photo_albums($user['uid'], true); + } +} + +/** + * @brief Expire and remove user entries + */ +function cron_expire_and_remove_users() { + // expire any expired accounts + q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0 + AND `account_expires_on` > '%s' + AND `account_expires_on` < UTC_TIMESTAMP()", dbesc(NULL_DATE)); + + // delete user and contact records for recently removed accounts + $r = q("SELECT * FROM `user` WHERE `account_removed` AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); + if (dbm::is_result($r)) { + foreach ($r as $user) { + q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid'])); + q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid'])); + } + } +} + +/** + * @brief Clear cache entries + * + * @param App $a + */ +function cron_clear_cache(App $a) { + + $last = get_config('system','cache_last_cleared'); + + if ($last) { + $next = $last + (3600); // Once per hour + $clear_cache = ($next <= time()); + } else { + $clear_cache = true; + } + + if (!$clear_cache) { + return; + } + + // clear old cache + Cache::clear(); + + // clear old item cache files + clear_cache(); + + // clear cache for photos + clear_cache($a->get_basepath(), $a->get_basepath()."/photo"); + + // clear smarty cache + clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled"); + + // clear cache for image proxy + if (!get_config("system", "proxy_disabled")) { + clear_cache($a->get_basepath(), $a->get_basepath()."/proxy"); + + $cachetime = get_config('system','proxy_cache_time'); + if (!$cachetime) { + $cachetime = PROXY_DEFAULT_TIME; + } + q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime); + } + + // Delete the cached OEmbed entries that are older than one year + q("DELETE FROM `oembed` WHERE `created` < NOW() - INTERVAL 3 MONTH"); + + // Delete the cached "parse_url" entries that are older than one year + q("DELETE FROM `parsed_url` WHERE `created` < NOW() - INTERVAL 3 MONTH"); + + // Maximum table size in megabyte + $max_tablesize = intval(get_config('system','optimize_max_tablesize')) * 1000000; + if ($max_tablesize == 0) { + $max_tablesize = 100 * 1000000; // Default are 100 MB + } + if ($max_tablesize > 0) { + // Minimum fragmentation level in percent + $fragmentation_level = intval(get_config('system','optimize_fragmentation')) / 100; + if ($fragmentation_level == 0) { + $fragmentation_level = 0.3; // Default value is 30% + } + + // Optimize some tables that need to be optimized + $r = q("SHOW TABLE STATUS"); + foreach ($r as $table) { + + // Don't optimize tables that are too large + if ($table["Data_length"] > $max_tablesize) { + continue; + } + + // Don't optimize empty tables + if ($table["Data_length"] == 0) { + continue; + } + + // Calculate fragmentation + $fragmentation = $table["Data_free"] / ($table["Data_length"] + $table["Index_length"]); + + logger("Table ".$table["Name"]." - Fragmentation level: ".round($fragmentation * 100, 2), LOGGER_DEBUG); + + // Don't optimize tables that needn't to be optimized + if ($fragmentation < $fragmentation_level) { + continue; + } + + // So optimize it + logger("Optimize Table ".$table["Name"], LOGGER_DEBUG); + q("OPTIMIZE TABLE `%s`", dbesc($table["Name"])); + } + } + + set_config('system','cache_last_cleared', time()); +} + +/** + * @brief Repair missing values in Diaspora contacts + * + * @param App $a + */ +function cron_repair_diaspora(App $a) { + + $starttime = time(); + + $r = q("SELECT `id`, `url` FROM `contact` + WHERE `network` = '%s' AND (`batch` = '' OR `notify` = '' OR `poll` = '' OR pubkey = '') + ORDER BY RAND() LIMIT 50", dbesc(NETWORK_DIASPORA)); + if (!dbm::is_result($r)) { + return; + } + + foreach ($r AS $contact) { + // Quit the loop after 3 minutes + if (time() > ($starttime + 180)) { + return; + } + + if (!poco_reachable($contact["url"])) { + continue; + } + + $data = Probe::uri($contact["url"]); + if ($data["network"] != NETWORK_DIASPORA) { + continue; + } + + logger("Repair contact ".$contact["id"]." ".$contact["url"], LOGGER_DEBUG); + q("UPDATE `contact` SET `batch` = '%s', `notify` = '%s', `poll` = '%s', pubkey = '%s' WHERE `id` = %d", + dbesc($data["batch"]), dbesc($data["notify"]), dbesc($data["poll"]), dbesc($data["pubkey"]), + intval($contact["id"])); + } +} + +/** + * @brief Do some repairs in database entries + * + */ +function cron_repair_database() { + + // Sometimes there seem to be issues where the "self" contact vanishes. + // We haven't found the origin of the problem by now. + $r = q("SELECT `uid` FROM `user` WHERE NOT EXISTS (SELECT `uid` FROM `contact` WHERE `contact`.`uid` = `user`.`uid` AND `contact`.`self`)"); + if (dbm::is_result($r)) { + foreach ($r AS $user) { + logger('Create missing self contact for user '.$user['uid']); + user_create_self_contact($user['uid']); + } + } + + // Set the parent if it wasn't set. (Shouldn't happen - but does sometimes) + // This call is very "cheap" so we can do it at any time without a problem + q("UPDATE `item` INNER JOIN `item` AS `parent` ON `parent`.`uri` = `item`.`parent-uri` AND `parent`.`uid` = `item`.`uid` SET `item`.`parent` = `parent`.`id` WHERE `item`.`parent` = 0"); + + // There was an issue where the nick vanishes from the contact table + q("UPDATE `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` SET `nick` = `nickname` WHERE `self` AND `nick`=''"); + + // Update the global contacts for local users + $r = q("SELECT `uid` FROM `user` WHERE `verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired`"); + if (dbm::is_result($r)) { + foreach ($r AS $user) { + update_gcontact_for_user($user["uid"]); + } + } + + /// @todo + /// - remove thread entries without item + /// - remove sign entries without item + /// - remove children when parent got lost + /// - set contact-id in item when not present } diff --git a/include/datetime.php b/include/datetime.php index 8d4961cd7c..9e1d4b55c9 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -339,7 +339,7 @@ function relative_date($posted_date, $format = null) { $abs = strtotime($localtime); - if (is_null($posted_date) || $posted_date === '0000-00-00 00:00:00' || $abs === False) { + if (is_null($posted_date) || $posted_date <= NULL_DATE || $abs === False) { return t('never'); } diff --git a/include/dba.php b/include/dba.php index 8e2d18db60..62728acaed 100644 --- a/include/dba.php +++ b/include/dba.php @@ -1,17 +1,5 @@ error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server); + $this->error = sprintf(t('Cannot locate DNS info for database server \'%s\''), $server); $this->connected = false; $this->db = null; return; @@ -61,37 +48,52 @@ class dba { } } - if (class_exists('mysqli')) { - $this->db = @new mysqli($server,$user,$pass,$db); - if (! mysqli_connect_errno()) { + if (class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) { + $this->driver = 'pdo'; + $connect = "mysql:host=".$server.";dbname=".$db; + if (isset($a->config["system"]["db_charset"])) { + $connect .= ";charset=".$a->config["system"]["db_charset"]; + } + $this->db = @new PDO($connect, $user, $pass); + if (!$this->db->errorCode()) { $this->connected = true; } - if (isset($a->config["system"]["db_charset"])) { - $this->db->set_charset($a->config["system"]["db_charset"]); + } elseif (class_exists('mysqli')) { + $this->driver = 'mysqli'; + $this->db = @new mysqli($server,$user,$pass,$db); + if (!mysqli_connect_errno()) { + $this->connected = true; + + if (isset($a->config["system"]["db_charset"])) { + $this->db->set_charset($a->config["system"]["db_charset"]); + } } - } else { - $this->mysqli = false; + } elseif (function_exists('mysql_connect')) { + $this->driver = 'mysql'; $this->db = mysql_connect($server,$user,$pass); if ($this->db && mysql_select_db($db,$this->db)) { $this->connected = true; + + if (isset($a->config["system"]["db_charset"])) { + mysql_set_charset($a->config["system"]["db_charset"], $this->db); + } + } + } else { + // No suitable SQL driver was found. + if (!$install) { + system_unavailable(); } - if (isset($a->config["system"]["db_charset"])) - mysql_set_charset($a->config["system"]["db_charset"], $this->db); } + if (!$this->connected) { $this->db = null; if (!$install) { system_unavailable(); } } - $a->save_timestamp($stamp1, "network"); } - public function getdb() { - return $this->db; - } - /** * @brief Returns the MySQL server version string * @@ -101,12 +103,18 @@ class dba { * @return string */ public function server_info() { - if ($this->mysqli) { - $return = $this->db->server_info; - } else { - $return = mysql_get_server_info($this->db); + 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; } - return $return; + return $version; } /** @@ -130,12 +138,18 @@ class dba { return 0; } - if ($this->mysqli) { - $return = $this->result->num_rows; - } else { - $return = mysql_num_rows($this->result); + switch ($this->driver) { + case 'pdo': + $rows = $this->result->rowCount(); + break; + case 'mysqli': + $rows = $this->result->num_rows; + break; + case 'mysql': + $rows = mysql_num_rows($this->result); + break; } - return $return; + return $rows; } /** @@ -172,8 +186,9 @@ class dba { if ((intval($a->config["system"]["db_loglimit_index"]) > 0)) { $log = (in_array($row['key'], $watchlist) AND ($row['rows'] >= intval($a->config["system"]["db_loglimit_index"]))); - } else + } else { $log = false; + } if ((intval($a->config["system"]["db_loglimit_index_high"]) > 0) AND ($row['rows'] >= intval($a->config["system"]["db_loglimit_index_high"]))) { $log = true; @@ -203,13 +218,7 @@ class dba { $this->error = ''; - // Check the connection (This can reconnect the connection - if configured) - if ($this->mysqli) { - $connected = $this->db->ping(); - } else { - $connected = mysql_ping($this->db); - } - $connstr = ($connected ? "Connected" : "Disonnected"); + $connstr = ($this->connected() ? "Connected" : "Disonnected"); $stamp1 = microtime(true); @@ -219,10 +228,22 @@ class dba { $sql = "/*".$a->callstack()." */ ".$sql; } - if ($this->mysqli) { - $result = @$this->db->query($sql); - } else { - $result = @mysql_query($sql,$this->db); + $columns = 0; + + switch ($this->driver) { + case 'pdo': + $result = @$this->db->query($sql); + // Is used to separate between queries that returning data - or not + if (!is_bool($result)) { + $columns = $result->columnCount(); + } + break; + case 'mysqli': + $result = @$this->db->query($sql); + break; + case 'mysql': + $result = @mysql_query($sql,$this->db); + break; } $stamp2 = microtime(true); $duration = (float)($stamp2-$stamp1); @@ -243,16 +264,27 @@ class dba { } } - if ($this->mysqli) { - if ($this->db->errno) { - $this->error = $this->db->error; - $this->errorno = $this->db->errno; - } - } elseif (mysql_errno($this->db)) { - $this->error = mysql_error($this->db); - $this->errorno = mysql_errno($this->db); + switch ($this->driver) { + case 'pdo': + $errorInfo = $this->db->errorInfo(); + if ($errorInfo) { + $this->error = $errorInfo[2]; + $this->errorno = $errorInfo[1]; + } + break; + case 'mysqli': + if ($this->db->errno) { + $this->error = $this->db->error; + $this->errorno = $this->db->errno; + } + break; + case 'mysql': + if (mysql_errno($this->db)) { + $this->error = mysql_error($this->db); + $this->errorno = mysql_errno($this->db); + } + break; } - if (strlen($this->error)) { logger('DB Error ('.$connstr.') '.$this->errorno.': '.$this->error); } @@ -266,10 +298,16 @@ class dba { } elseif ($result === true) { $mesg = 'true'; } else { - if ($this->mysqli) { - $mesg = $result->num_rows . ' results' . EOL; - } else { - $mesg = mysql_num_rows($result) . ' results' . EOL; + switch ($this->driver) { + case 'pdo': + $mesg = $result->rowCount().' results'.EOL; + break; + case 'mysqli': + $mesg = $result->num_rows.' results'.EOL; + break; + case 'mysql': + $mesg = mysql_num_rows($result).' results'.EOL; + break; } } @@ -293,7 +331,7 @@ class dba { } } - if (($result === true) || ($result === false)) { + if (is_bool($result)) { return $result; } if ($onlyquery) { @@ -302,18 +340,32 @@ class dba { } $r = array(); - if ($this->mysqli) { - if ($result->num_rows) { - while($x = $result->fetch_array(MYSQLI_ASSOC)) + switch ($this->driver) { + case 'pdo': + while ($x = $result->fetch(PDO::FETCH_ASSOC)) { $r[] = $x; + } + $result->closeCursor(); + break; + case 'mysqli': + while ($x = $result->fetch_array(MYSQLI_ASSOC)) { + $r[] = $x; + } $result->free_result(); - } - } else { - if (mysql_num_rows($result)) { - while($x = mysql_fetch_array($result, MYSQL_ASSOC)) + break; + case 'mysql': + while ($x = mysql_fetch_array($result, MYSQL_ASSOC)) { $r[] = $x; + } mysql_free_result($result); - } + break; + } + + // PDO doesn't return "true" on successful operations - like mysqli does + // Emulate this behaviour by checking if the query returned data and had columns + // This should be reliable enough + if (($this->driver == 'pdo') AND (count($r) == 0) AND ($columns == 0)) { + return true; } //$a->save_timestamp($stamp1, "database"); @@ -328,12 +380,16 @@ class dba { $x = false; if ($this->result) { - if ($this->mysqli) { - if ($this->result->num_rows) + switch ($this->driver) { + case 'pdo': + $x = $this->result->fetch(PDO::FETCH_ASSOC); + break; + case 'mysqli': $x = $this->result->fetch_array(MYSQLI_ASSOC); - } else { - if (mysql_num_rows($this->result)) + break; + case 'mysql': $x = mysql_fetch_array($this->result, MYSQL_ASSOC); + break; } } return($x); @@ -341,10 +397,16 @@ class dba { public function qclose() { if ($this->result) { - if ($this->mysqli) { - $this->result->free_result(); - } else { - mysql_free_result($this->result); + switch ($this->driver) { + case 'pdo': + $this->result->closeCursor(); + break; + case 'mysqli': + $this->result->free_result(); + break; + case 'mysql': + mysql_free_result($this->result); + break; } } } @@ -355,35 +417,65 @@ class dba { public function escape($str) { if ($this->db && $this->connected) { - if ($this->mysqli) { - return @$this->db->real_escape_string($str); - } else { - return @mysql_real_escape_string($str,$this->db); + switch ($this->driver) { + case 'pdo': + return substr(@$this->db->quote($str, PDO::PARAM_STR), 1, -1); + case 'mysqli': + return @$this->db->real_escape_string($str); + case 'mysql': + return @mysql_real_escape_string($str,$this->db); } } } function connected() { - if ($this->mysqli) { - $connected = $this->db->ping(); - } else { - $connected = mysql_ping($this->db); + switch ($this->driver) { + case 'pdo': + // Not sure if this really is working like expected + $connected = ($this->db->getAttribute(PDO::ATTR_CONNECTION_STATUS) != ""); + break; + case 'mysqli': + $connected = $this->db->ping(); + break; + case 'mysql': + $connected = mysql_ping($this->db); + break; } return $connected; } + function insert_id() { + switch ($this->driver) { + case 'pdo': + $id = $this->db->lastInsertId(); + break; + case 'mysqli': + $id = $this->db->insert_id; + break; + case 'mysql': + $id = mysql_insert_id($this->db); + break; + } + return $id; + } + function __destruct() { if ($this->db) { - if ($this->mysqli) { - $this->db->close(); - } else { - mysql_close($this->db); + switch ($this->driver) { + case 'pdo': + $this->db = null; + break; + case 'mysqli': + $this->db->close(); + break; + case 'mysql': + mysql_close($this->db); + break; } } } -}} +} -if (! function_exists('printable')) { function printable($s) { $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s); $s = str_replace("\x00",'.',$s); @@ -391,37 +483,32 @@ function printable($s) { $s = escape_tags($s); } return $s; -}} +} // Procedural functions -if (! function_exists('dbg')) { function dbg($state) { global $db; + if ($db) { $db->dbg($state); } -}} +} -if (! function_exists('dbesc')) { function dbesc($str) { global $db; + if ($db && $db->connected) { return($db->escape($str)); } else { return(str_replace("'","\\'",$str)); } -}} - - +} // Function: q($sql,$args); // Description: execute SQL query with printf style args. // Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d", // 'user', 1); - -if (! function_exists('q')) { function q($sql) { - global $db; $args = func_get_args(); unset($args[0]); @@ -445,8 +532,7 @@ function q($sql) { */ logger('dba: no database: ' . print_r($args,true)); return false; - -}} +} /** * @brief Performs a query with "dirty reads" @@ -458,8 +544,8 @@ function q($sql) { * @return array Query array */ function qu($sql) { - global $db; + $args = func_get_args(); unset($args[0]); @@ -484,7 +570,6 @@ function qu($sql) { */ logger('dba: no database: ' . print_r($args,true)); return false; - } /** @@ -492,40 +577,31 @@ function qu($sql) { * Raw db query, no arguments * */ - -if (! function_exists('dbq')) { function dbq($sql) { - global $db; + if ($db && $db->connected) { $ret = $db->q($sql); } else { $ret = false; } return $ret; -}} - +} // Caller is responsible for ensuring that any integer arguments to // dbesc_array are actually integers and not malformed strings containing // SQL injection vectors. All integer array elements should be specifically // cast to int to avoid trouble. - - -if (! function_exists('dbesc_array_cb')) { function dbesc_array_cb(&$item, $key) { if (is_string($item)) $item = dbesc($item); -}} +} - -if (! function_exists('dbesc_array')) { function dbesc_array(&$arr) { if (is_array($arr) && count($arr)) { array_walk($arr,'dbesc_array_cb'); } -}} - +} function dba_timer() { return microtime(true); diff --git a/include/dbclean.php b/include/dbclean.php index 8408ad1882..bff4ff2a24 100644 --- a/include/dbclean.php +++ b/include/dbclean.php @@ -5,26 +5,8 @@ */ use \Friendica\Core\Config; -use \Friendica\Core\PConfig; - -require_once("boot.php"); function dbclean_run(&$argv, &$argc) { - global $a, $db; - - if (is_null($a)) { - $a = new App; - } - - if (is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - } - - Config::load(); - if (!Config::get('system', 'dbclean', false)) { return; } @@ -35,7 +17,7 @@ function dbclean_run(&$argv, &$argc) { $stage = 0; } - if (Config::get("system", "worker") AND ($stage == 0)) { + if ($stage == 0) { proc_run(PRIORITY_LOW, 'include/dbclean.php', 1); proc_run(PRIORITY_LOW, 'include/dbclean.php', 2); proc_run(PRIORITY_LOW, 'include/dbclean.php', 3); @@ -56,12 +38,8 @@ function remove_orphans($stage = 0) { $count = 0; - // With activated worker we split the deletion in many small tasks - if (Config::get("system", "worker")) { - $limit = 1000; - } else { - $limit = 10000; - } + // We split the deletion in many small tasks + $limit = 1000; if (($stage == 1) OR ($stage == 0)) { logger("Deleting old global item entries from item table without user copy"); @@ -159,14 +137,9 @@ function remove_orphans($stage = 0) { } // Call it again if not all entries were purged - if (($stage != 0) AND ($count > 0) AND Config::get("system", "worker")) { + if (($stage != 0) AND ($count > 0)) { proc_run(PRIORITY_MEDIUM, 'include/dbclean.php'); } } - -if (array_search(__file__,get_included_files())===0){ - dbclean_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} ?> diff --git a/include/dbm.php b/include/dbm.php index fedc2e4fdb..d28d49d63b 100644 --- a/include/dbm.php +++ b/include/dbm.php @@ -96,17 +96,10 @@ class dbm { public static function date($date = 'now') { $timestamp = strtotime($date); - // Workaround for 3.5.1 - if ($timestamp < -62135596800) { - return '0000-00-00 00:00:00'; - } - - // The above will be removed in 3.5.2 - // The following will then be enabled // Don't allow lower date strings as '0001-01-01 00:00:00' - //if ($timestamp < -62135596800) { - // $timestamp = -62135596800; - //} + if ($timestamp < -62135596800) { + $timestamp = -62135596800; + } return date('Y-m-d H:i:s', $timestamp); } diff --git a/include/dbstructure.php b/include/dbstructure.php index 4ad54e6ba2..48cc02d2d1 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -1,4 +1,7 @@ config["system"]["db_charset"])) { @@ -361,8 +365,10 @@ function update_structure($verbose, $action, $tables=null, $definition=null) { } } - if ($action) - set_config('system', 'maintenance', 0); + if ($action) { + Config::set('system', 'maintenance', 0); + Config::set('system', 'maintenance_reason', ''); + } return $errors; } @@ -536,8 +542,8 @@ function db_definition($charset) { "filetype" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), "filesize" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "data" => array("type" => "longblob", "not null" => "1"), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "allow_cid" => array("type" => "mediumtext"), "allow_gid" => array("type" => "mediumtext"), "deny_cid" => array("type" => "mediumtext"), @@ -564,7 +570,7 @@ function db_definition($charset) { "k" => array("type" => "varbinary(255)", "not null" => "1", "primary" => "1"), "v" => array("type" => "mediumtext"), "expire_mode" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("k"), @@ -613,7 +619,7 @@ function db_definition($charset) { "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "self" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "remote_self" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "rel" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), @@ -651,14 +657,14 @@ function db_definition($charset) { "usehub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "subhub" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "hub-verify" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "last-update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "success_update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "failure_update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "name-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "uri-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "avatar-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "term-date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "last-item" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "last-update" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "success_update" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "failure_update" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "name-date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "uri-date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "avatar-date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "term-date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "last-item" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "priority" => array("type" => "tinyint(3)", "not null" => "1", "default" => "0"), "blocked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"), "readonly" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), @@ -703,8 +709,8 @@ function db_definition($charset) { "recips" => array("type" => "text"), "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "creator" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "subject" => array("type" => "text"), ), "indexes" => array( @@ -712,18 +718,6 @@ function db_definition($charset) { "uid" => array("uid"), ) ); - $database["deliverq"] = array( - "fields" => array( - "id" => array("type" => "int(10) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), - "cmd" => array("type" => "varbinary(32)", "not null" => "1", "default" => ""), - "item" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "contact" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - ), - "indexes" => array( - "PRIMARY" => array("id"), - "cmd_item_contact" => array("UNIQUE", "cmd", "item", "contact"), - ) - ); $database["event"] = array( "fields" => array( "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), @@ -731,10 +725,10 @@ function db_definition($charset) { "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "start" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "finish" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "start" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "finish" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "summary" => array("type" => "text"), "desc" => array("type" => "text"), "location" => array("type" => "text"), @@ -770,7 +764,7 @@ function db_definition($charset) { "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""), "alias" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "pubkey" => array("type" => "text"), - "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), @@ -811,7 +805,7 @@ function db_definition($charset) { "request" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "note" => array("type" => "text"), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), @@ -838,10 +832,10 @@ function db_definition($charset) { "nurl" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "connect" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "updated" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"), - "last_contact" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"), - "last_failure" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "updated" => array("type" => "datetime", "default" => NULL_DATE), + "last_contact" => array("type" => "datetime", "default" => NULL_DATE), + "last_failure" => array("type" => "datetime", "default" => NULL_DATE), "location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "about" => array("type" => "text"), "keywords" => array("type" => "text"), @@ -875,7 +869,7 @@ function db_definition($charset) { "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "gcid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "zcid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "updated" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "updated" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), @@ -923,10 +917,10 @@ function db_definition($charset) { "noscrape" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""), "platform" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "last_poco_query" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"), - "last_contact" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"), - "last_failure" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "last_poco_query" => array("type" => "datetime", "default" => NULL_DATE), + "last_contact" => array("type" => "datetime", "default" => NULL_DATE), + "last_failure" => array("type" => "datetime", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), @@ -956,7 +950,7 @@ function db_definition($charset) { "duplex" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "note" => array("type" => "text"), "hash" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "datetime" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "datetime" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "blocked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "1"), "ignore" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), ), @@ -979,11 +973,11 @@ function db_definition($charset) { "parent-uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "extid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "thr-parent" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "commented" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "received" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "changed" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "commented" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "received" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "changed" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "owner-id" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "owner-name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "owner-link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1082,7 +1076,7 @@ function db_definition($charset) { "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "name" => array("type" => "varchar(128)", "not null" => "1", "default" => ""), "locked" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), - "created" => array("type" => "datetime", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), @@ -1106,7 +1100,7 @@ function db_definition($charset) { "unknown" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "parent-uri" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), @@ -1130,7 +1124,7 @@ function db_definition($charset) { "action" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "movetofolder" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "pubmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), - "last_check" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "last_check" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), @@ -1155,7 +1149,7 @@ function db_definition($charset) { "name" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "photo" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "msg" => array("type" => "mediumtext"), "uid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "link" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1191,7 +1185,7 @@ function db_definition($charset) { "fields" => array( "url" => array("type" => "varbinary(255)", "not null" => "1", "primary" => "1"), "content" => array("type" => "mediumtext"), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("url"), @@ -1204,7 +1198,7 @@ function db_definition($charset) { "guessing" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0", "primary" => "1"), "oembed" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0", "primary" => "1"), "content" => array("type" => "mediumtext"), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("url", "guessing", "oembed"), @@ -1231,8 +1225,8 @@ function db_definition($charset) { "contact-id" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), "guid" => array("type" => "varchar(64)", "not null" => "1", "default" => ""), "resource-id" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "title" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "desc" => array("type" => "text"), "album" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1294,7 +1288,7 @@ function db_definition($charset) { "fields" => array( "pid" => array("type" => "int(10) unsigned", "not null" => "1", "primary" => "1"), "command" => array("type" => "varbinary(32)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("pid"), @@ -1320,7 +1314,7 @@ function db_definition($charset) { "gender" => array("type" => "varchar(32)", "not null" => "1", "default" => ""), "marital" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "with" => array("type" => "text"), - "howlong" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "howlong" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "sexual" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "politic" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "religion" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1372,7 +1366,7 @@ function db_definition($charset) { "topic" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "nickname" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "push" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "last_update" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "last_update" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "secret" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), ), "indexes" => array( @@ -1384,8 +1378,8 @@ function db_definition($charset) { "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "cid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "network" => array("type" => "varchar(32)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "last" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "last" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "content" => array("type" => "mediumtext"), "batch" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), ), @@ -1402,7 +1396,7 @@ function db_definition($charset) { "fields" => array( "id" => array("type" => "int(11) unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "hash" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "uid" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), "password" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "language" => array("type" => "varchar(16)", "not null" => "1", "default" => ""), @@ -1456,7 +1450,7 @@ function db_definition($charset) { "spam" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "ham" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "term" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), @@ -1475,8 +1469,8 @@ function db_definition($charset) { "term" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "url" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "guid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "received" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "received" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "global" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "aid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), "uid" => array("type" => "int(10) unsigned", "not null" => "1", "default" => "0"), @@ -1497,11 +1491,11 @@ function db_definition($charset) { "gcontact-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), "owner-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), "author-id" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "edited" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "commented" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "received" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "changed" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "edited" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "commented" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "received" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "changed" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "wall" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "private" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "pubmail" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), @@ -1553,8 +1547,8 @@ function db_definition($charset) { "openid" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "timezone" => array("type" => "varchar(128)", "not null" => "1", "default" => ""), "language" => array("type" => "varchar(32)", "not null" => "1", "default" => "en"), - "register_date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "login_date" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "register_date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "login_date" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "default-location" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), "allow_location" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "theme" => array("type" => "varchar(255)", "not null" => "1", "default" => ""), @@ -1578,8 +1572,8 @@ function db_definition($charset) { "expire" => array("type" => "int(11) unsigned", "not null" => "1", "default" => "0"), "account_removed" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), "account_expired" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"), - "account_expires_on" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), - "expire_notification_sent" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "account_expires_on" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), + "expire_notification_sent" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "service_class" => array("type" => "varchar(32)", "not null" => "1", "default" => ""), "def_gid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), "allow_cid" => array("type" => "mediumtext"), @@ -1608,9 +1602,9 @@ function db_definition($charset) { "id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"), "parameter" => array("type" => "text"), "priority" => array("type" => "tinyint(3) unsigned", "not null" => "1", "default" => "0"), - "created" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "created" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), "pid" => array("type" => "int(11)", "not null" => "1", "default" => "0"), - "executed" => array("type" => "datetime", "not null" => "1", "default" => "0000-00-00 00:00:00"), + "executed" => array("type" => "datetime", "not null" => "1", "default" => NULL_DATE), ), "indexes" => array( "PRIMARY" => array("id"), diff --git a/include/dbupdate.php b/include/dbupdate.php index 14709208fa..725eca7370 100644 --- a/include/dbupdate.php +++ b/include/dbupdate.php @@ -2,32 +2,12 @@ use \Friendica\Core\Config; -require_once("boot.php"); - function dbupdate_run(&$argv, &$argc) { - global $a, $db; - - if(is_null($a)){ - $a = new App; - } - - if(is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - } - - Config::load(); + global $a; // We are deleting the latest dbupdate entry. // This is done to avoid endless loops because the update was interupted. - Config::delete('database','dbupdate_'.DB_UPDATE_VERSION); + Config::delete('database', 'dbupdate_'.DB_UPDATE_VERSION); update_db($a); } - -if (array_search(__file__,get_included_files())===0){ - dbupdate_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/delivery.php b/include/delivery.php index 8ccb19cedc..faa1cad674 100644 --- a/include/delivery.php +++ b/include/delivery.php @@ -2,44 +2,25 @@ use \Friendica\Core\Config; -require_once("boot.php"); require_once('include/queue_fn.php'); require_once('include/html2plain.php'); -require_once("include/Scrape.php"); +require_once('include/Scrape.php'); require_once('include/diaspora.php'); -require_once("include/ostatus.php"); -require_once("include/dfrn.php"); +require_once('include/ostatus.php'); +require_once('include/dfrn.php'); function delivery_run(&$argv, &$argc){ - global $a, $db; + global $a; - if (is_null($a)) { - $a = new App; - } - - if (is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - } - - require_once("include/session.php"); - require_once("include/datetime.php"); + require_once('include/datetime.php'); require_once('include/items.php'); require_once('include/bbcode.php'); require_once('include/email.php'); - Config::load(); - - load_hooks(); - if ($argc < 3) { return; } - $a->set_baseurl(get_config('system','url')); - logger('delivery: invoked: '. print_r($argv,true), LOGGER_DEBUG); $cmd = $argv[1]; @@ -49,30 +30,6 @@ function delivery_run(&$argv, &$argc){ $contact_id = intval($argv[$x]); - /// @todo When switching completely to the worker we won't need this anymore - // Some other process may have delivered this item already. - - $r = q("SELECT * FROM `deliverq` WHERE `cmd` = '%s' AND `item` = %d AND `contact` = %d LIMIT 1", - dbesc($cmd), - dbesc($item_id), - dbesc($contact_id) - ); - if (!dbm::is_result($r)) { - continue; - } - - if ($a->maxload_reached()) { - return; - } - - // It's ours to deliver. Remove it from the queue. - - q("DELETE FROM `deliverq` WHERE `cmd` = '%s' AND `item` = %d AND `contact` = %d", - dbesc($cmd), - dbesc($item_id), - dbesc($contact_id) - ); - if (!$item_id || !$contact_id) { continue; } @@ -577,8 +534,3 @@ function delivery_run(&$argv, &$argc){ return; } - -if (array_search(__file__,get_included_files())===0){ - delivery_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/dfrn.php b/include/dfrn.php index 39372aef14..25f8c9358e 100644 --- a/include/dfrn.php +++ b/include/dfrn.php @@ -1094,7 +1094,7 @@ class dfrn { return 3; } - if($contact['term-date'] != '0000-00-00 00:00:00') { + if ($contact['term-date'] > NULL_DATE) { logger("dfrn_deliver: $url back from the dead - removing mark for death"); require_once('include/Contact.php'); unmark_for_death($contact); diff --git a/include/directory.php b/include/directory.php index 2ca367d369..088adbe789 100644 --- a/include/directory.php +++ b/include/directory.php @@ -1,36 +1,16 @@ set_baseurl(get_config('system','url')); - - $dir = get_config('system','directory'); - - if(! strlen($dir)) + if (!strlen($dir)) { return; + } $dir .= "/submit"; @@ -39,13 +19,8 @@ function directory_run(&$argv, &$argc){ call_hooks('globaldir_update', $arr); logger('Updating directory: ' . $arr['url'], LOGGER_DEBUG); - if(strlen($arr['url'])) + if (strlen($arr['url'])) { fetch_url($dir . '?url=' . bin2hex($arr['url'])); - + } return; } - -if (array_search(__file__,get_included_files())===0){ - directory_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/discover_poco.php b/include/discover_poco.php index 10c741ae5f..d203cfd6b4 100644 --- a/include/discover_poco.php +++ b/include/discover_poco.php @@ -2,62 +2,87 @@ use \Friendica\Core\Config; -require_once("boot.php"); -require_once("include/socgraph.php"); +require_once('include/socgraph.php'); +require_once('include/datetime.php'); -function discover_poco_run(&$argv, &$argc){ - global $a, $db; +function discover_poco_run(&$argv, &$argc) { - if(is_null($a)) { - $a = new App; - } + /* + This function can be called in these ways: + - dirsearch : Searches for "search pattern" in the directory. "search pattern" is url encoded. + - checkcontact: Updates gcontact entries + - suggestions: Discover other servers for their contacts. + - server : Searches for the poco server list. "poco url" is base64 encoded. + - update_server: Frequently check the first 250 servers for vitality. + - update_server_directory: Discover the given server id for their contacts + - poco_load: Load POCO data from a given POCO address + - check_profile: Update remote profile data + */ - if(is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; - - require_once('include/session.php'); - require_once('include/datetime.php'); - - Config::load(); - - // Don't check this stuff if the function is called by the poller - if (App::callstack() != "poller_run") - if ($a->maxload_reached()) - return; - - if(($argc > 2) && ($argv[1] == "dirsearch")) { + if (($argc > 2) && ($argv[1] == "dirsearch")) { $search = urldecode($argv[2]); $mode = 1; - } elseif(($argc == 2) && ($argv[1] == "checkcontact")) { + } elseif (($argc == 2) && ($argv[1] == "checkcontact")) { $mode = 2; - } elseif(($argc == 2) && ($argv[1] == "suggestions")) { + } elseif (($argc == 2) && ($argv[1] == "suggestions")) { $mode = 3; + } elseif (($argc == 3) && ($argv[1] == "server")) { + $mode = 4; + } elseif (($argc == 2) && ($argv[1] == "update_server")) { + $mode = 5; + } elseif (($argc == 3) && ($argv[1] == "update_server_directory")) { + $mode = 6; + } elseif (($argc > 5) && ($argv[1] == "poco_load")) { + $mode = 7; + } elseif (($argc == 3) && ($argv[1] == "check_profile")) { + $mode = 8; } elseif ($argc == 1) { $search = ""; $mode = 0; - } else + } else { die("Unknown or missing parameter ".$argv[1]."\n"); - - // Don't check this stuff if the function is called by the poller - if (App::callstack() != "poller_run") - if (App::is_already_running('discover_poco'.$mode.urlencode($search), 'include/discover_poco.php', 1140)) - return; - - $a->set_baseurl(get_config('system','url')); - - load_hooks(); + } logger('start '.$search); - if ($mode==3) + if ($mode == 8) { + $profile_url = base64_decode($argv[2]); + if ($profile_url != "") { + poco_last_updated($profile_url, true); + } + } elseif ($mode == 7) { + if ($argc == 6) { + $url = base64_decode($argv[5]); + } else { + $url = ''; + } + poco_load_worker(intval($argv[2]), intval($argv[3]), intval($argv[4]), $url); + } elseif ($mode == 6) { + poco_discover_single_server(intval($argv[2])); + } elseif ($mode == 5) { + update_server(); + } elseif ($mode == 4) { + $server_url = base64_decode($argv[2]); + if ($server_url == "") { + return; + } + $server_url = filter_var($server_url, FILTER_SANITIZE_URL); + if (substr(normalise_link($server_url), 0, 7) != "http://") { + return; + } + $result = "Checking server ".$server_url." - "; + $ret = poco_check_server($server_url); + if ($ret) { + $result .= "success"; + } else { + $result .= "failed"; + } + logger($result, LOGGER_DEBUG); + } elseif ($mode == 3) { update_suggestions(); - elseif (($mode == 2) AND get_config('system','poco_completion')) + } elseif (($mode == 2) AND get_config('system','poco_completion')) { discover_users(); - elseif (($mode == 1) AND ($search != "") and get_config('system','poco_local_search')) { + } elseif (($mode == 1) AND ($search != "") and get_config('system','poco_local_search')) { discover_directory($search); gs_search_user($search); } elseif (($mode == 0) AND ($search == "") and (get_config('system','poco_discovery') > 0)) { @@ -74,19 +99,48 @@ function discover_poco_run(&$argv, &$argc){ return; } +/** + * @brief Updates the first 250 servers + * + */ +function update_server() { + $r = q("SELECT `url`, `created`, `last_failure`, `last_contact` FROM `gserver` ORDER BY rand()"); + + if (!dbm::is_result($r)) { + return; + } + + $updated = 0; + + foreach ($r AS $server) { + if (!poco_do_update($server["created"], "", $server["last_failure"], $server["last_contact"])) { + continue; + } + logger('Update server status for server '.$server["url"], LOGGER_DEBUG); + + proc_run(PRIORITY_LOW, "include/discover_poco.php", "server", base64_encode($server["url"])); + + if (++$updated > 250) { + return; + } + } +} + function discover_users() { logger("Discover users", LOGGER_DEBUG); - $users = q("SELECT `url`, `created`, `updated`, `last_failure`, `last_contact`, `server_url` FROM `gcontact` + $starttime = time(); + + $users = q("SELECT `url`, `created`, `updated`, `last_failure`, `last_contact`, `server_url`, `network` FROM `gcontact` WHERE `last_contact` < UTC_TIMESTAMP - INTERVAL 1 MONTH AND `last_failure` < UTC_TIMESTAMP - INTERVAL 1 MONTH AND `network` IN ('%s', '%s', '%s', '%s', '') ORDER BY rand()", dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS), dbesc(NETWORK_FEED)); - if (!$users) + if (!$users) { return; - + } $checked = 0; foreach ($users AS $user) { @@ -111,27 +165,34 @@ function discover_users() { continue; } - if ($user["server_url"] != "") + if ($user["server_url"] != "") { $server_url = $user["server_url"]; - else + } else { $server_url = poco_detect_server($user["url"]); + } + if ((($server_url == "") AND ($user["network"] == NETWORK_FEED)) OR poco_check_server($server_url, $user["network"])) { + logger('Check profile '.$user["url"]); + proc_run(PRIORITY_LOW, "include/discover_poco.php", "check_profile", base64_encode($user["url"])); - if (($server_url == "") OR poco_check_server($server_url, $gcontacts[0]["network"])) { - logger('Check user '.$user["url"]); - poco_last_updated($user["url"], true); - - if (++$checked > 100) + if (++$checked > 100) { return; - } else + } + } else { q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc(normalise_link($user["url"]))); + } + + // Quit the loop after 3 minutes + if (time() > ($starttime + 180)) { + return; + } } } function discover_directory($search) { $data = Cache::get("dirsearch:".$search); - if (!is_null($data)){ + if (!is_null($data)) { // Only search for the same item every 24 hours if (time() < $data + (60 * 60 * 24)) { logger("Already searched for ".$search." in the last 24 hours", LOGGER_DEBUG); @@ -142,7 +203,7 @@ function discover_directory($search) { $x = fetch_url(get_server()."/lsearch?p=1&n=500&search=".urlencode($search)); $j = json_decode($x); - if(count($j->results)) + if (count($j->results)) { 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)); @@ -150,32 +211,33 @@ function discover_directory($search) { logger("Profile ".$jj->url." already exists (".$search.")", LOGGER_DEBUG); if (($exists[0]["last_contact"] < $exists[0]["last_failure"]) AND - ($exists[0]["updated"] < $exists[0]["last_failure"])) + ($exists[0]["updated"] < $exists[0]["last_failure"])) { continue; - + } // Update the contact poco_last_updated($jj->url); continue; } - // Harcoded paths aren't so good. But in this case it is okay. - // First: We only will get Friendica contacts (which always are using this url schema) - // Second: There will be no further problems if we are doing a mistake - $server_url = preg_replace("=(https?://)(.*)/profile/(.*)=ism", "$1$2", $jj->url); - if ($server_url != $jj->url) + $server_url = poco_detect_server($jj->url); + if ($server_url != '') { if (!poco_check_server($server_url)) { logger("Friendica server ".$server_url." doesn't answer.", LOGGER_DEBUG); continue; } - logger("Friendica server ".$server_url." seems to be okay.", LOGGER_DEBUG); + logger("Friendica server ".$server_url." seems to be okay.", LOGGER_DEBUG); + } - logger("Check if profile ".$jj->url." is reachable (".$search.")", LOGGER_DEBUG); $data = probe_url($jj->url); if ($data["network"] == NETWORK_DFRN) { + logger("Profile ".$jj->url." is reachable (".$search.")", LOGGER_DEBUG); logger("Add profile ".$jj->url." to local directory (".$search.")", LOGGER_DEBUG); poco_check($data["url"], $data["name"], $data["network"], $data["photo"], "", "", "", $jj->tags, $data["addr"], "", 0); + } else { + logger("Profile ".$jj->url." is not responding or no Friendica contact - but network ".$data["network"], LOGGER_DEBUG); } } + } Cache::set("dirsearch:".$search, time(), CACHE_DAY); } @@ -195,14 +257,14 @@ function gs_search_user($search) { $url = "http://gstools.org/api/users_search/".urlencode($search); $result = z_fetch_url($url); - if (!$result["success"]) + if (!$result["success"]) { return false; - + } $contacts = json_decode($result["body"]); - if ($contacts->status == 'ERROR') + if ($contacts->status == 'ERROR') { return false; - + } foreach($contacts->data AS $user) { $contact = probe_url($user->site_address."/".$user->name); if ($contact["network"] != NETWORK_PHANTOM) { @@ -211,9 +273,3 @@ function gs_search_user($search) { } } } - - -if (array_search(__file__,get_included_files())===0){ - discover_poco_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/event.php b/include/event.php index 9e5bafbdb0..ebd4885c91 100644 --- a/include/event.php +++ b/include/event.php @@ -4,39 +4,42 @@ * @brief functions specific to event handling */ -require_once('include/bbcode.php'); -require_once('include/map.php'); -require_once('include/datetime.php'); +require_once 'include/bbcode.php'; +require_once 'include/map.php'; +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 ''; + } $bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM $event_start = (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $ev['start'] , $bd_format )) - : day_translate(datetime_convert('UTC', 'UTC', + : day_translate(datetime_convert('UTC', 'UTC', $ev['start'] , $bd_format))); $event_end = (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $ev['finish'] , $bd_format )) - : day_translate(datetime_convert('UTC', 'UTC', + : day_translate(datetime_convert('UTC', 'UTC', $ev['finish'] , $bd_format ))); if ($simple) { - $o = "

".bbcode($ev['summary'])."

"; + $o = "

" . bbcode($ev['summary']) . "

"; - $o .= "

".bbcode($ev['desc'])."

"; + $o .= "

" . bbcode($ev['desc']) . "

"; - $o .= "

".t('Starts:')."

".$event_start."

"; + $o .= "

" . t('Starts:') . "

" . $event_start . "

"; - if(! $ev['nofinish']) - $o .= "

".t('Finishes:')."

".$event_end."

"; + if (! $ev['nofinish']) { + $o .= "

" . t('Finishes:') . "

" . $event_end ."

"; + } - if(strlen($ev['location'])) - $o .= "

".t('Location:')."

".$ev['location']."

"; + if (strlen($ev['location'])) { + $o .= "

" . t('Location:') . "

" . $ev['location'] . "

"; + } return $o; } @@ -44,31 +47,34 @@ function format_event_html($ev, $simple = false) { $o = '
' . "\r\n"; - $o .= '

' . bbcode($ev['summary']) . '

' . "\r\n"; + $o .= '

' . bbcode($ev['summary']) . '

' . "\r\n"; - $o .= '

' . bbcode($ev['desc']) . '

' . "\r\n"; + $o .= '

' . bbcode($ev['desc']) . '

' . "\r\n"; $o .= '

' . t('Starts:') . ' '.$event_start . '

' . "\r\n"; - if(! $ev['nofinish']) + if (! $ev['nofinish']) { $o .= '

' . t('Finishes:') . ' '.$event_end - . '

' . "\r\n"; + . '

' . "\r\n"; + } - if(strlen($ev['location'])){ + if (strlen($ev['location'])) { $o .= '

' . t('Location:') . ' ' . bbcode($ev['location']) . '

' . "\r\n"; - if (strpos($ev['location'], "[map") !== False) { + // Include a map of the location if the [map] BBCode is used + if (strpos($ev['location'], "[map") !== false) { $map = generate_named_map($ev['location']); - if ($map!==$ev['location']) $o.=$map; + if ($map !== $ev['location']) { + $o.= $map; + } } - } $o .= '
' . "\r\n"; @@ -146,63 +152,81 @@ function format_event_bbcode($ev) { $o = ''; - if($ev['summary']) + if ($ev['summary']) { $o .= '[event-summary]' . $ev['summary'] . '[/event-summary]'; + } - if($ev['desc']) + if ($ev['desc']) { $o .= '[event-description]' . $ev['desc'] . '[/event-description]'; + } - if($ev['start']) + if ($ev['start']) { $o .= '[event-start]' . $ev['start'] . '[/event-start]'; + } - if(($ev['finish']) && (! $ev['nofinish'])) + if (($ev['finish']) && (! $ev['nofinish'])) { $o .= '[event-finish]' . $ev['finish'] . '[/event-finish]'; + } - if($ev['location']) + if ($ev['location']) { $o .= '[event-location]' . $ev['location'] . '[/event-location]'; + } - if($ev['adjust']) + if ($ev['adjust']) { $o .= '[event-adjust]' . $ev['adjust'] . '[/event-adjust]'; - + } return $o; - } function bbtovcal($s) { $o = ''; $ev = bbtoevent($s); - if($ev['desc']) + + if ($ev['desc']) { $o = format_event_html($ev); + } + return $o; } - function bbtoevent($s) { $ev = array(); $match = ''; - if(preg_match("/\[event\-summary\](.*?)\[\/event\-summary\]/is",$s,$match)) + if (preg_match("/\[event\-summary\](.*?)\[\/event\-summary\]/is", $s, $match)) { $ev['summary'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-description\](.*?)\[\/event\-description\]/is",$s,$match)) - $ev['desc'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-start\](.*?)\[\/event\-start\]/is",$s,$match)) - $ev['start'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-finish\](.*?)\[\/event\-finish\]/is",$s,$match)) - $ev['finish'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-location\](.*?)\[\/event\-location\]/is",$s,$match)) - $ev['location'] = $match[1]; - $match = ''; - if(preg_match("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",$s,$match)) - $ev['adjust'] = $match[1]; - $ev['nofinish'] = (((x($ev, 'start') && $ev['start']) && (!x($ev, 'finish') || !$ev['finish'])) ? 1 : 0); - return $ev; + } + $match = ''; + if (preg_match("/\[event\-description\](.*?)\[\/event\-description\]/is", $s, $match)) { + $ev['desc'] = $match[1]; + } + + $match = ''; + if (preg_match("/\[event\-start\](.*?)\[\/event\-start\]/is", $s, $match)) { + $ev['start'] = $match[1]; + } + + $match = ''; + if (preg_match("/\[event\-finish\](.*?)\[\/event\-finish\]/is", $s, $match)) { + $ev['finish'] = $match[1]; + } + + $match = ''; + if (preg_match("/\[event\-location\](.*?)\[\/event\-location\]/is", $s, $match)) { + $ev['location'] = $match[1]; + } + + $match = ''; + if (preg_match("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is", $s, $match)) { + $ev['adjust'] = $match[1]; + } + + $ev['nofinish'] = (((x($ev, 'start') && $ev['start']) && (!x($ev, 'finish') || !$ev['finish'])) ? 1 : 0); + + return $ev; } @@ -212,21 +236,22 @@ function sort_by_date($a) { return $a; } - function ev_compare($a,$b) { - $date_a = (($a['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$a['start']) : $a['start']); - $date_b = (($b['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$b['start']) : $b['start']); + $date_a = (($a['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $a['start']) : $a['start']); + $date_b = (($b['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $b['start']) : $b['start']); - if($date_a === $date_b) - return strcasecmp($a['desc'],$b['desc']); + if ($date_a === $date_b) { + return strcasecmp($a['desc'], $b['desc']); + } - return strcmp($date_a,$date_b); + return strcmp($date_a, $date_b); } function event_delete($event_id) { - if ($event_id == 0) + if ($event_id == 0) { return; + } q("DELETE FROM `event` WHERE `id` = %d", intval($event_id)); logger("Deleted event ".$event_id, LOGGER_DEBUG); @@ -234,37 +259,39 @@ function event_delete($event_id) { function event_store($arr) { - require_once('include/datetime.php'); - require_once('include/items.php'); - require_once('include/bbcode.php'); + require_once 'include/datetime.php'; + require_once 'include/items.php'; + require_once 'include/bbcode.php'; $a = get_app(); - $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert()); - $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert()); - $arr['type'] = (($arr['type']) ? $arr['type'] : 'event' ); - $arr['cid'] = ((intval($arr['cid'])) ? intval($arr['cid']) : 0); - $arr['uri'] = (x($arr,'uri') ? $arr['uri'] : item_new_uri($a->get_hostname(),$arr['uid'])); - $arr['private'] = ((x($arr,'private')) ? intval($arr['private']) : 0); + $arr['created'] = (($arr['created']) ? $arr['created'] : datetime_convert()); + $arr['edited'] = (($arr['edited']) ? $arr['edited'] : datetime_convert()); + $arr['type'] = (($arr['type']) ? $arr['type'] : 'event' ); + $arr['cid'] = ((intval($arr['cid'])) ? intval($arr['cid']) : 0); + $arr['uri'] = (x($arr, 'uri') ? $arr['uri'] : item_new_uri($a->get_hostname(), $arr['uid'])); + $arr['private'] = ((x($arr, 'private')) ? intval($arr['private']) : 0); $arr['guid'] = get_guid(32); - if($arr['cid']) + if ($arr['cid']) { $c = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($arr['cid']), intval($arr['uid']) ); - else + } else { $c = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1", intval($arr['uid']) ); + } - if(count($c)) + if (dbm::is_result($c)) { $contact = $c[0]; + } // Existing event being modified - if($arr['id']) { + if ($arr['id']) { // has the event actually changed? @@ -272,7 +299,7 @@ function event_store($arr) { intval($arr['id']), intval($arr['uid']) ); - if((! dbm::is_result($r)) || ($r[0]['edited'] === $arr['edited'])) { + if ((! dbm::is_result($r)) || ($r[0]['edited'] === $arr['edited'])) { // Nothing has changed. Grab the item id to return. @@ -280,7 +307,7 @@ function event_store($arr) { intval($arr['id']), intval($arr['uid']) ); - return((dbm::is_result($r)) ? $r[0]['id'] : 0); + return ((dbm::is_result($r)) ? $r[0]['id'] : 0); } // The event changed. Update it. @@ -318,7 +345,6 @@ function event_store($arr) { $object .= '' . xmlify(format_event_bbcode($arr)) . ''; $object .= '' . "\n"; - q("UPDATE `item` SET `body` = '%s', `object` = '%s', `edited` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc(format_event_bbcode($arr)), dbesc($object), @@ -328,8 +354,9 @@ function event_store($arr) { ); $item_id = $r[0]['id']; - } else + } else { $item_id = 0; + } call_hooks("event_updated", $arr['id']); @@ -366,8 +393,9 @@ function event_store($arr) { dbesc($arr['uri']), intval($arr['uid']) ); - if (dbm::is_result($r)) + if (dbm::is_result($r)) { $event = $r[0]; + } $item_arr = array(); @@ -399,7 +427,7 @@ function event_store($arr) { $item_arr['body'] = format_event_bbcode($event); - $item_arr['object'] = '' . xmlify(ACTIVITY_OBJ_EVENT) . '' . xmlify($arr['uri']) . ''; + $item_arr['object'] = '' . xmlify(ACTIVITY_OBJ_EVENT) . '' . xmlify($arr['uri']) . ''; $item_arr['object'] .= '' . xmlify(format_event_bbcode($event)) . ''; $item_arr['object'] .= '' . "\n"; @@ -412,7 +440,7 @@ function event_store($arr) { // $plink = App::get_baseurl() . '/display/' . $r[0]['nickname'] . '/' . $item_id; - if($item_id) { + if ($item_id) { //q("UPDATE `item` SET `plink` = '%s', `event-id` = %d WHERE `uid` = %d AND `id` = %d", // dbesc($plink), // intval($event['id']), @@ -433,12 +461,17 @@ function event_store($arr) { } function get_event_strings() { + // First day of the week (0 = Sunday) - $firstDay = get_pconfig(local_user(),'system','first_day_of_week'); - if ($firstDay === false) $firstDay=0; + $firstDay = get_pconfig(local_user(), 'system', 'first_day_of_week'); + if ($firstDay === false) { + $firstDay = 0; + } $i18n = array( "firstDay" => $firstDay, + "allday" => t("all-day"), + "Sun" => t("Sun"), "Mon" => t("Mon"), "Tue" => t("Tue"), @@ -446,13 +479,15 @@ function get_event_strings() { "Thu" => t("Thu"), "Fri" => t("Fri"), "Sat" => t("Sat"), - "Sunday" => t("Sunday"), - "Monday" => t("Monday"), - "Tuesday" => t("Tuesday"), + + "Sunday" => t("Sunday"), + "Monday" => t("Monday"), + "Tuesday" => t("Tuesday"), "Wednesday" => t("Wednesday"), - "Thursday" => t("Thursday"), - "Friday" => t("Friday"), - "Saturday" => t("Saturday"), + "Thursday" => t("Thursday"), + "Friday" => t("Friday"), + "Saturday" => t("Saturday"), + "Jan" => t("Jan"), "Feb" => t("Feb"), "Mar" => t("Mar"), @@ -465,47 +500,49 @@ function get_event_strings() { "Oct" => t("Oct"), "Nov" => t("Nov"), "Dec" => t("Dec"), - "January" => t("January"), - "February" => t("February"), - "March" => t("March"), - "April" => t("April"), - "May" => t("May"), - "June" => t("June"), - "July" => t("July"), - "August" => t("August"), + + "January" => t("January"), + "February" => t("February"), + "March" => t("March"), + "April" => t("April"), + "May" => t("May"), + "June" => t("June"), + "July" => t("July"), + "August" => t("August"), "September" => t("September"), - "October" => t("October"), - "November" => t("November"), - "December" => t("December"), + "October" => t("October"), + "November" => t("November"), + "December" => t("December"), + "today" => t("today"), "month" => t("month"), - "week" => t("week"), - "day" => t("day"), - "allday" => t("all-day"), + "week" => t("week"), + "day" => t("day"), "noevent" => t("No events to display"), - "dtstart_label" => t("Starts:"), - "dtend_label" => t("Finishes:"), + "dtstart_label" => t("Starts:"), + "dtend_label" => t("Finishes:"), "location_label" => t("Location:") ); return $i18n; } -/// @todo We should replace this with a separate update function if there is some time left /** * @brief Removes duplicated birthday events * * @param array $dates Array of possibly duplicated events * @return array Cleaned events + * + * @todo We should replace this with a separate update function if there is some time left */ function event_remove_duplicates($dates) { $dates2 = array(); foreach ($dates AS $date) { if ($date['type'] == 'birthday') { - $dates2[$date['uid']."-".$date['cid']."-".$date['start']] = $date; + $dates2[$date['uid'] . "-" . $date['cid'] . "-" . $date['start']] = $date; } else { $dates2[] = $date; } @@ -524,10 +561,11 @@ function event_remove_duplicates($dates) { */ function event_by_id($owner_uid = 0, $event_params, $sql_extra = '') { // ownly allow events if there is a valid owner_id - if($owner_uid == 0) + if ($owner_uid == 0) { return; + } - // query for the event by event id + // Query for the event by event id $r = q("SELECT `event`.*, `item`.`id` AS `itemid`,`item`.`plink`, `item`.`author-name`, `item`.`author-avatar`, `item`.`author-link` FROM `event` LEFT JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid` @@ -556,11 +594,12 @@ function event_by_id($owner_uid = 0, $event_params, $sql_extra = '') { * @return array Query results */ function events_by_date($owner_uid = 0, $event_params, $sql_extra = '') { - // ownly allow events if there is a valid owner_id - if($owner_uid == 0) + // Only allow events if there is a valid owner_id + if($owner_uid == 0) { return; + } - // query for the event by date + // Query for the event by date $r = q("SELECT `event`.*, `item`.`id` AS `itemid`,`item`.`plink`, `item`.`author-name`, `item`.`author-avatar`, `item`.`author-link` FROM `event` LEFT JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid` @@ -595,46 +634,54 @@ function process_events($arr) { $last_date = ''; $fmt = t('l, F j'); if (count($arr)) { - foreach($arr as $rr) { + foreach ($arr as $rr) { - $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); - $d = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], $fmt) : datetime_convert('UTC','UTC',$rr['start'],$fmt)); + $j = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['start'], 'j') : datetime_convert('UTC', 'UTC', $rr['start'], 'j')); + $d = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['start'], $fmt) : datetime_convert('UTC', 'UTC', $rr['start'], $fmt)); $d = day_translate($d); - $start = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'c') : datetime_convert('UTC','UTC',$rr['start'],'c')); - if ($rr['nofinish']){ + $start = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['start'], 'c') : datetime_convert('UTC', 'UTC', $rr['start'], 'c')); + if ($rr['nofinish']) { $end = null; } else { - $end = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['finish'], 'c') : datetime_convert('UTC','UTC',$rr['finish'],'c')); + $end = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['finish'], 'c') : datetime_convert('UTC', 'UTC', $rr['finish'], 'c')); } - $is_first = ($d !== $last_date); $last_date = $d; - $edit = ((! $rr['cid']) ? array(App::get_baseurl().'/events/event/'.$rr['id'],t('Edit event'),'','') : null); - $title = strip_tags(html_entity_decode(bbcode($rr['summary']),ENT_QUOTES,'UTF-8')); - if(! $title) { - list($title, $_trash) = explode("$rr['id'], - 'start'=> $start, - 'end' => $end, + 'id' => $rr['id'], + 'start' => $start, + 'end' => $end, 'allDay' => false, - 'title' => $title, + 'title' => $title, - 'j' => $j, - 'd' => $d, - 'is_first'=>$is_first, - 'item'=>$rr, - 'html'=>$html, - 'plink' => array($rr['plink'],t('link to source'),'',''), + 'j' => $j, + 'd' => $d, + 'edit' => $edit, + 'drop' => $drop, + 'is_first' => $is_first, + 'item' => $rr, + 'html' => $html, + 'plink' => array($rr['plink'], t('link to source'), '', ''), ); } } @@ -652,34 +699,36 @@ function process_events($arr) { * @return string Content according to selected export format */ function event_format_export ($events, $format = 'ical', $timezone) { - if(! ((is_array($events)) && count($events))) + if (! ((is_array($events)) && count($events))) { return; + } switch ($format) { - // format the exported data as a CSV file + // Format the exported data as a CSV file case "csv": header("Content-type: text/csv"); $o = '"Subject", "Start Date", "Start Time", "Description", "End Date", "End Time", "Location"' . PHP_EOL; foreach ($events as $event) { - /// @todo the time / date entries don't include any information about the - // timezone the event is scheduled in :-/ + /// @todo The time / date entries don't include any information about the + /// timezone the event is scheduled in :-/ $tmp1 = strtotime($event['start']); $tmp2 = strtotime($event['finish']); $time_format = "%H:%M:%S"; $date_format = "%Y-%m-%d"; - $o .= '"'.$event['summary'].'", "'.strftime($date_format, $tmp1) . - '", "'.strftime($time_format, $tmp1).'", "'.$event['desc'] . - '", "'.strftime($date_format, $tmp2) . - '", "'.strftime($time_format, $tmp2) . - '", "'.$event['location'].'"' . PHP_EOL; + + $o .= '"' . $event['summary'] . '", "' . strftime($date_format, $tmp1) . + '", "' . strftime($time_format, $tmp1) . '", "' . $event['desc'] . + '", "' . strftime($date_format, $tmp2) . + '", "' . strftime($time_format, $tmp2) . + '", "' . $event['location'] . '"' . PHP_EOL; } break; - // format the exported data as a ics file + // Format the exported data as a ics file case "ical": header("Content-type: text/ics"); - $o = 'BEGIN:VCALENDAR'. PHP_EOL + $o = 'BEGIN:VCALENDAR' . PHP_EOL . 'VERSION:2.0' . PHP_EOL . 'PRODID:-//friendica calendar export//0.1//EN' . PHP_EOL; /// @todo include timezone informations in cases were the time is not in UTC @@ -691,35 +740,43 @@ function event_format_export ($events, $format = 'ical', $timezone) { // but test your solution against http://icalvalid.cloudapp.net/ // also long lines SHOULD be split at 75 characters length foreach ($events as $event) { + if ($event['adjust'] == 1) { $UTC = 'Z'; } else { $UTC = ''; } $o .= 'BEGIN:VEVENT' . PHP_EOL; - if ($event[start]) { + + if ($event['start']) { $tmp = strtotime($event['start']); - $dtformat = "%Y%m%dT%H%M%S".$UTC; - $o .= 'DTSTART:'.strftime($dtformat, $tmp).PHP_EOL; + $dtformat = "%Y%m%dT%H%M%S" . $UTC; + $o .= 'DTSTART:' . strftime($dtformat, $tmp) . PHP_EOL; } + if (!$event['nofinish']) { $tmp = strtotime($event['finish']); - $dtformat = "%Y%m%dT%H%M%S".$UTC; - $o .= 'DTEND:'.strftime($dtformat, $tmp).PHP_EOL; + $dtformat = "%Y%m%dT%H%M%S" . $UTC; + $o .= 'DTEND:' . strftime($dtformat, $tmp) . PHP_EOL; } - if ($event['summary']) + + if ($event['summary']) { $tmp = $event['summary']; - $tmp = str_replace(PHP_EOL, PHP_EOL.' ',$tmp); + $tmp = str_replace(PHP_EOL, PHP_EOL . ' ', $tmp); $tmp = addcslashes($tmp, ',;'); $o .= 'SUMMARY:' . $tmp . PHP_EOL; - if ($event['desc']) + } + + if ($event['desc']) { $tmp = $event['desc']; - $tmp = str_replace(PHP_EOL, PHP_EOL.' ',$tmp); + $tmp = str_replace(PHP_EOL, PHP_EOL . ' ', $tmp); $tmp = addcslashes($tmp, ',;'); $o .= 'DESCRIPTION:' . $tmp . PHP_EOL; + } + if ($event['location']) { $tmp = $event['location']; - $tmp = str_replace(PHP_EOL, PHP_EOL.' ',$tmp); + $tmp = str_replace(PHP_EOL, PHP_EOL . ' ', $tmp); $tmp = addcslashes($tmp, ',;'); $o .= 'LOCATION:' . $tmp . PHP_EOL; } @@ -750,16 +807,18 @@ function event_format_export ($events, $format = 'ical', $timezone) { * @return array Query results */ function events_by_uid($uid = 0, $sql_extra = '') { - if($uid == 0) + if ($uid == 0) { return; + } // The permission condition if no condition was transmitted - if($sql_extra == '') + if ($sql_extra == '') { $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' "; + } - // does the user who requests happen to be the owner of the events - // requested? then show all of your events, otherwise only those that - // don't have limitations set in allow_cid and allow_gid + // Does the user who requests happen to be the owner of the events + // requested? then show all of your events, otherwise only those that + // don't have limitations set in allow_cid and allow_gid if (local_user() == $uid) { $r = q("SELECT `start`, `finish`, `adjust`, `summary`, `desc`, `location`, `nofinish` FROM `event` WHERE `uid`= %d AND `cid` = 0 ", @@ -772,8 +831,9 @@ function events_by_uid($uid = 0, $sql_extra = '') { ); } - if (dbm::is_result($r)) + if (dbm::is_result($r)) { return $r; + } } /** @@ -792,25 +852,28 @@ function event_export($uid, $format = 'ical') { $process = false; - // we are allowed to show events + // We are allowed to show events // get the timezone the user is in $r = q("SELECT `timezone` FROM `user` WHERE `uid` = %d LIMIT 1", intval($uid)); - if (dbm::is_result($r)) + if (dbm::is_result($r)) { $timezone = $r[0]['timezone']; + } - // get all events which are owned by a uid (respects permissions); + // Get all events which are owned by a uid (respects permissions); $events = events_by_uid($uid); - // we have the events that are available for the requestor - // now format the output according to the requested format - if(count($events)) + // We have the events that are available for the requestor + // now format the output according to the requested format + if (count($events)) { $res = event_format_export($events, $format, $timezone); + } // If there are results the precess was successfull - if(x($res)) + if (x($res)) { $process = true; + } - // get the file extension for the format + // Get the file extension for the format switch ($format) { case "ical": $file_ext = "ics"; @@ -825,10 +888,10 @@ function event_export($uid, $format = 'ical') { } $arr = array( - 'success' => $process, - 'format' => $format, + 'success' => $process, + 'format' => $format, 'extension' => $file_ext, - 'content' => $res, + 'content' => $res, ); return $arr; @@ -851,8 +914,9 @@ function widget_events() { // The permission testing is a little bit tricky because we have to respect many cases // It's not the private events page (we don't get the $owner_uid for /events) - if(! local_user() && ! $owner_uid) + if (! local_user() && ! $owner_uid) { return; + } // Cal logged in user (test permission at foreign profile page) // If the $owner uid is available we know it is part of one of the profile pages (like /cal) @@ -860,13 +924,15 @@ function widget_events() { // or a foreign one. For foreign profile pages we need to check if the feature // for exporting the cal is enabled (otherwise the widget would appear for logged in users // on foreigen profile pages even if the widget is disabled) - if(intval($owner_uid) && local_user() !== $owner_uid && ! feature_enabled($owner_uid, "export_calendar")) + if (intval($owner_uid) && local_user() !== $owner_uid && ! feature_enabled($owner_uid, "export_calendar")) { return; + } // If it's a kind of profile page (intval($owner_uid)) return if the user not logged in and // export feature isn't enabled - if(intval($owner_uid) && ! local_user() && ! feature_enabled($owner_uid, "export_calendar")) + if (intval($owner_uid) && ! local_user() && ! feature_enabled($owner_uid, "export_calendar")) { return; + } return replace_macros(get_markup_template("events_aside.tpl"), array( '$etitle' => t("Export"), @@ -874,5 +940,4 @@ function widget_events() { '$export_csv' => t("Export calendar as csv"), '$user' => $user )); - } diff --git a/include/expire.php b/include/expire.php index 855d7fb5e4..35b109a50a 100644 --- a/include/expire.php +++ b/include/expire.php @@ -2,32 +2,13 @@ use \Friendica\Core\Config; -require_once("boot.php"); - function expire_run(&$argv, &$argc){ - global $a, $db; + global $a; - if(is_null($a)) { - $a = new App; - } - - if(is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; - - require_once('include/session.php'); require_once('include/datetime.php'); require_once('include/items.php'); require_once('include/Contact.php'); - Config::load(); - - $a->set_baseurl(get_config('system','url')); - - // 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"); @@ -53,8 +34,3 @@ function expire_run(&$argv, &$argc){ return; } - -if (array_search(__file__,get_included_files())===0){ - expire_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/gprobe.php b/include/gprobe.php index 4407fa6d6c..719cfce486 100644 --- a/include/gprobe.php +++ b/include/gprobe.php @@ -2,36 +2,14 @@ use \Friendica\Core\Config; -require_once("boot.php"); require_once('include/Scrape.php'); require_once('include/socgraph.php'); +require_once('include/datetime.php'); function gprobe_run(&$argv, &$argc){ - global $a, $db; - - if(is_null($a)) { - $a = new App; - } - - if(is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; - - require_once('include/session.php'); - require_once('include/datetime.php'); - - Config::load(); - - $a->set_baseurl(get_config('system','url')); - - load_hooks(); - - if($argc != 2) + if ($argc != 2) { return; - + } $url = hex2bin($argv[1]); $r = q("SELECT `id`, `url`, `network` FROM `gcontact` WHERE `nurl` = '%s' ORDER BY `id` LIMIT 1", @@ -74,8 +52,3 @@ function gprobe_run(&$argv, &$argc){ logger("gprobe end for ".normalise_link($url), LOGGER_DEBUG); return; } - -if (array_search(__file__,get_included_files())===0){ - gprobe_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/identity.php b/include/identity.php index ab80c71cea..8138e9b046 100644 --- a/include/identity.php +++ b/include/identity.php @@ -652,7 +652,7 @@ function advanced_profile(App $a) { $profile['marital']['with'] = $a->profile['with']; } - if (strlen($a->profile['howlong']) && $a->profile['howlong'] !== '0000-00-00 00:00:00') { + if (strlen($a->profile['howlong']) && $a->profile['howlong'] >= NULL_DATE) { $profile['howlong'] = relative_date($a->profile['howlong'], t('for %1$d %2$s')); } diff --git a/include/lock.php b/include/lock.php index b3d488a357..a48b0ad342 100644 --- a/include/lock.php +++ b/include/lock.php @@ -68,7 +68,8 @@ function block_on_function_lock($fn_name, $wait_sec = 2, $timeout = 30) { if(! function_exists('unlock_function')) { function unlock_function($fn_name) { - $r = q("UPDATE `locks` SET `locked` = 0, `created` = '0000-00-00 00:00:00' WHERE `name` = '%s'", + $r = q("UPDATE `locks` SET `locked` = 0, `created` = '%s' WHERE `name` = '%s'", + dbesc(NULL_DATE), dbesc($fn_name) ); diff --git a/include/network.php b/include/network.php index b0e71fab7f..f9d35c52c3 100644 --- a/include/network.php +++ b/include/network.php @@ -72,8 +72,9 @@ function z_fetch_url($url,$binary = false, &$redirects = 0, $opts=array()) { $a = get_app(); $ch = @curl_init($url); - if(($redirects > 8) || (! $ch)) - return false; + if(($redirects > 8) || (! $ch)) { + return $ret; + } @curl_setopt($ch, CURLOPT_HEADER, true); diff --git a/include/notifier.php b/include/notifier.php index 24830a11ab..e3d7d10d6b 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -2,12 +2,11 @@ use \Friendica\Core\Config; -require_once("boot.php"); require_once('include/queue_fn.php'); require_once('include/html2plain.php'); -require_once("include/Scrape.php"); +require_once('include/Scrape.php'); require_once('include/diaspora.php'); -require_once("include/ostatus.php"); +require_once('include/ostatus.php'); require_once('include/salmon.php'); /* @@ -44,35 +43,17 @@ require_once('include/salmon.php'); function notifier_run(&$argv, &$argc){ - global $a, $db; + global $a; - if (is_null($a)) { - $a = new App; - } - - if (is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - } - - require_once("include/session.php"); - require_once("include/datetime.php"); + require_once('include/datetime.php'); require_once('include/items.php'); require_once('include/bbcode.php'); require_once('include/email.php'); - Config::load(); - - load_hooks(); - if ($argc < 3) { return; } - $a->set_baseurl(get_config('system','url')); - logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG); $cmd = $argv[1]; @@ -490,79 +471,22 @@ function notifier_run(&$argv, &$argc){ if ($relocate) { $r = $recipients_relocate; } else { - $r = q("SELECT * FROM `contact` WHERE `id` IN (%s) AND NOT `blocked` AND NOT `pending` AND NOT `archive`".$sql_extra, + $r = q("SELECT `id`, `url`, `network`, `self` FROM `contact` + WHERE `id` IN (%s) AND NOT `blocked` AND NOT `pending` AND NOT `archive`".$sql_extra, dbesc($recip_str) ); } - $interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval'))); - - // If we are using the worker we don't need a delivery interval - if (get_config("system", "worker")) { - $interval = false; - } // delivery loop if (dbm::is_result($r)) { foreach ($r as $contact) { - if (!$contact['self']) { - if (($contact['network'] === NETWORK_DIASPORA) && ($public_message)) { - continue; - } - q("INSERT INTO `deliverq` (`cmd`,`item`,`contact`) VALUES ('%s', %d, %d)", - dbesc($cmd), - intval($item_id), - intval($contact['id']) - ); - } - } - - - // This controls the number of deliveries to execute with each separate delivery process. - // By default we'll perform one delivery per process. Assuming a hostile shared hosting - // provider, this provides the greatest chance of deliveries if processes start getting - // killed. We can also space them out with the delivery_interval to also help avoid them - // getting whacked. - - // If $deliveries_per_process > 1, we will chain this number of multiple deliveries - // together into a single process. This will reduce the overall number of processes - // spawned for each delivery, but they will run longer. - - // When using the workerqueue, we don't need this functionality. - - $deliveries_per_process = intval(get_config('system','delivery_batch_count')); - if (($deliveries_per_process <= 0) OR get_config("system", "worker")) { - $deliveries_per_process = 1; - } - - $this_batch = array(); - - for ($x = 0; $x < count($r); $x ++) { - $contact = $r[$x]; - if ($contact['self']) { continue; } logger("Deliver ".$target_item["guid"]." to ".$contact['url']." via network ".$contact['network'], LOGGER_DEBUG); - // potentially more than one recipient. Start a new process and space them out a bit. - // we will deliver single recipient types of message and email recipients here. - - $this_batch[] = $contact['id']; - - if (count($this_batch) >= $deliveries_per_process) { - proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$this_batch); - $this_batch = array(); - if ($interval) { - @time_sleep_until(microtime(true) + (float) $interval); - } - } - continue; - } - - // be sure to pick up any stragglers - if (count($this_batch)) { - proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$this_batch); + proc_run(PRIORITY_HIGH,'include/delivery.php', $cmd, $item_id, $contact['id']); } } @@ -614,18 +538,6 @@ function notifier_run(&$argv, &$argc){ if (dbm::is_result($r)) { logger('pubdeliver '.$target_item["guid"].': '.print_r($r,true), LOGGER_DEBUG); - // throw everything into the queue in case we get killed - - foreach ($r as $rr) { - if ((! $mail) && (! $fsuggest) && (! $followup)) { - q("INSERT INTO `deliverq` (`cmd`,`item`,`contact`) VALUES ('%s', %d, %d) - ON DUPLICATE KEY UPDATE `cmd` = '%s', `item` = %d, `contact` = %d", - dbesc($cmd), intval($item_id), intval($rr['id']), - dbesc($cmd), intval($item_id), intval($rr['id']) - ); - } - } - foreach ($r as $rr) { // except for Diaspora batch jobs @@ -639,9 +551,6 @@ function notifier_run(&$argv, &$argc){ if ((! $mail) && (! $fsuggest) && (! $followup)) { logger('notifier: delivery agent: '.$rr['name'].' '.$rr['id'].' '.$rr['network'].' '.$target_item["guid"]); proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$rr['id']); - if ($interval) { - @time_sleep_until(microtime(true) + (float) $interval); - } } } } @@ -694,9 +603,3 @@ function notifier_run(&$argv, &$argc){ return; } - - -if (array_search(__file__,get_included_files())===0){ - notifier_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/oembed.php b/include/oembed.php index a1945894fc..0b8b713667 100755 --- a/include/oembed.php +++ b/include/oembed.php @@ -17,10 +17,10 @@ function oembed_replacecb($matches){ /** * @brief Get data from an URL to embed its content. - * + * * @param string $embedurl The URL from which the data should be fetched. * @param bool $no_rich_type If set to true rich type content won't be fetched. - * + * * @return bool|object Returns object with embed content or false if no embedable * content exists */ @@ -41,8 +41,8 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){ // These media files should now be caught in bbcode.php // left here as a fallback in case this is called from another source - $noexts = array("mp3","mp4","ogg","ogv","oga","ogm","webm"); - $ext = pathinfo(strtolower($embedurl),PATHINFO_EXTENSION); + $noexts = array("mp3", "mp4", "ogg", "ogv", "oga", "ogm", "webm"); + $ext = pathinfo(strtolower($embedurl), PATHINFO_EXTENSION); if (is_null($txt)) { @@ -74,21 +74,10 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){ } } - if ($txt==false || $txt=="") { - $embedly = Config::get("system", "embedly"); - if ($embedly != "") { - // try embedly service - $ourl = "https://api.embed.ly/1/oembed?key=".$embedly."&url=".urlencode($embedurl); - $txt = fetch_url($ourl); + $txt = trim($txt); - logger("oembed_fetch_url: ".$txt, LOGGER_DEBUG); - } - } - - $txt=trim($txt); - - if ($txt[0]!="{") { - $txt='{"type":"error"}'; + if ($txt[0] != "{") { + $txt = '{"type":"error"}'; } else { //save in cache $j = json_decode($txt); if ($j->type != "error") { diff --git a/include/onepoll.php b/include/onepoll.php index 552fea36fa..5227b61a1a 100644 --- a/include/onepoll.php +++ b/include/onepoll.php @@ -2,8 +2,7 @@ use \Friendica\Core\Config; -require_once("boot.php"); -require_once("include/follow.php"); +require_once('include/follow.php'); function RemoveReply($subject) { while (in_array(strtolower(substr($subject, 0, 3)), array("re:", "aw:"))) @@ -13,20 +12,8 @@ function RemoveReply($subject) { } function onepoll_run(&$argv, &$argc){ - global $a, $db; + global $a; - if (is_null($a)) { - $a = new App; - } - - if (is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; - - require_once('include/session.php'); require_once('include/datetime.php'); require_once('include/items.php'); require_once('include/Contact.php'); @@ -34,12 +21,6 @@ function onepoll_run(&$argv, &$argc){ require_once('include/socgraph.php'); require_once('include/queue_fn.php'); - Config::load(); - - $a->set_baseurl(get_config('system','url')); - - load_hooks(); - logger('onepoll: start'); $manual_id = 0; @@ -61,13 +42,6 @@ function onepoll_run(&$argv, &$argc){ return; } - // Don't check this stuff if the function is called by the poller - if (App::callstack() != "poller_run") { - if (App::is_already_running('onepoll'.$contact_id, '', 540)) { - return; - } - } - $d = datetime_convert(); // Only poll from those with suitable relationships, @@ -159,7 +133,7 @@ function onepoll_run(&$argv, &$argc){ logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}"); - $last_update = (($contact['last-update'] === '0000-00-00 00:00:00') + $last_update = (($contact['last-update'] <= NULL_DATE) ? datetime_convert('UTC','UTC','now - 7 days', ATOM_TIME) : datetime_convert('UTC','UTC',$contact['last-update'], ATOM_TIME) ); @@ -265,7 +239,7 @@ function onepoll_run(&$argv, &$argc){ intval($contact['id']) ); mark_for_death($contact); - } elseif ($contact['term-date'] != '0000-00-00 00:00:00') { + } elseif ($contact['term-date'] > NULL_DATE) { logger("poller: $url back from the dead - removing mark for death"); unmark_for_death($contact); } @@ -697,8 +671,3 @@ function onepoll_run(&$argv, &$argc){ return; } - -if (array_search(__file__,get_included_files())===0) { - onepoll_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/poller.php b/include/poller.php index 82befae518..5560b3340e 100644 --- a/include/poller.php +++ b/include/poller.php @@ -35,6 +35,10 @@ function poller_run($argv, $argc){ return; } + $a->set_baseurl(Config::get('system', 'url')); + + load_hooks(); + $a->start_process(); if (poller_max_connections_reached()) { @@ -353,18 +357,18 @@ function poller_max_connections_reached() { * */ function poller_kill_stale_workers() { - $r = q("SELECT `pid`, `executed`, `priority`, `parameter` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'"); + $r = q("SELECT `pid`, `executed`, `priority`, `parameter` FROM `workerqueue` WHERE `executed` > '%s'", dbesc(NULL_DATE)); if (!dbm::is_result($r)) { // No processing here needed return; } - foreach($r AS $pid) - if (!posix_kill($pid["pid"], 0)) - q("UPDATE `workerqueue` SET `executed` = '0000-00-00 00:00:00', `pid` = 0 WHERE `pid` = %d", - intval($pid["pid"])); - else { + foreach ($r AS $pid) { + if (!posix_kill($pid["pid"], 0)) { + q("UPDATE `workerqueue` SET `executed` = '%s', `pid` = 0 WHERE `pid` = %d", + dbesc(NULL_DATE), intval($pid["pid"])); + } else { // Kill long running processes // Check if the priority is in a valid range @@ -387,14 +391,17 @@ function poller_kill_stale_workers() { // We killed the stale process. // To avoid a blocking situation we reschedule the process at the beginning of the queue. // Additionally we are lowering the priority. - q("UPDATE `workerqueue` SET `executed` = '0000-00-00 00:00:00', `created` = '%s', + q("UPDATE `workerqueue` SET `executed` = '%s', `created` = '%s', `priority` = %d, `pid` = 0 WHERE `pid` = %d", + dbesc(NULL_DATE), dbesc(datetime_convert()), intval(PRIORITY_NEGLIGIBLE), intval($pid["pid"])); - } else + } else { logger("Worker process ".$pid["pid"]." (".implode(" ", $argv).") now runs for ".round($duration)." of ".$max_duration." allowed minutes. That's okay.", LOGGER_DEBUG); + } } + } } /** @@ -421,15 +428,15 @@ function poller_too_much_workers() { $slope = $maxworkers / pow($maxsysload, $exponent); $queues = ceil($slope * pow(max(0, $maxsysload - $load), $exponent)); - $s = q("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00'"); + $s = q("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE `executed` <= '%s'", dbesc(NULL_DATE)); $entries = $s[0]["total"]; if (Config::get("system", "worker_fastlane", false) AND ($queues > 0) AND ($entries > 0) AND ($active >= $queues)) { - $s = q("SELECT `priority` FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `priority` LIMIT 1"); + $s = q("SELECT `priority` FROM `workerqueue` WHERE `executed` <= '%s' ORDER BY `priority` LIMIT 1", dbesc(NULL_DATE)); $top_priority = $s[0]["priority"]; - $s = q("SELECT `id` FROM `workerqueue` WHERE `priority` <= %d AND `executed` != '0000-00-00 00:00:00' LIMIT 1", - intval($top_priority)); + $s = q("SELECT `id` FROM `workerqueue` WHERE `priority` <= %d AND `executed` > '%s' LIMIT 1", + intval($top_priority), dbesc(NULL_DATE)); $high_running = dbm::is_result($s); if (!$high_running AND ($top_priority > PRIORITY_UNDEFINED) AND ($top_priority < PRIORITY_NEGLIGIBLE)) { @@ -464,7 +471,7 @@ function poller_too_much_workers() { // Are there fewer workers running as possible? Then fork a new one. if (!Config::get("system", "worker_dont_fork") AND ($queues > ($active + 1)) AND ($entries > 1)) { logger("Active workers: ".$active."/".$queues." Fork a new worker.", LOGGER_DEBUG); - $args = array("php", "include/poller.php", "no_cron"); + $args = array("include/poller.php", "no_cron"); $a = get_app(); $a->proc_run($args); } @@ -549,21 +556,25 @@ function poller_worker_process() { if (poller_passing_slow($highest_priority)) { // Are there waiting processes with a higher priority than the currently highest? $r = q("SELECT * FROM `workerqueue` - WHERE `executed` = '0000-00-00 00:00:00' AND `priority` < %d - ORDER BY `priority`, `created` LIMIT 1", dbesc($highest_priority)); - if (dbm::is_result($r)) + WHERE `executed` <= '%s' AND `priority` < %d + ORDER BY `priority`, `created` LIMIT 1", + dbesc(NULL_DATE), + intval($highest_priority)); + if (dbm::is_result($r)) { return $r; - + } // Give slower processes some processing time $r = q("SELECT * FROM `workerqueue` - WHERE `executed` = '0000-00-00 00:00:00' AND `priority` > %d - ORDER BY `priority`, `created` LIMIT 1", dbesc($highest_priority)); + WHERE `executed` <= '%s' AND `priority` > %d + ORDER BY `priority`, `created` LIMIT 1", + dbesc(NULL_DATE), + intval($highest_priority)); } // If there is no result (or we shouldn't pass lower processes) we check without priority limit - if (($highest_priority == 0) OR !dbm::is_result($r)) - $r = q("SELECT * FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `priority`, `created` LIMIT 1"); - + if (($highest_priority == 0) OR !dbm::is_result($r)) { + $r = q("SELECT * FROM `workerqueue` WHERE `executed` <= '%s' ORDER BY `priority`, `created` LIMIT 1", dbesc(NULL_DATE)); + } return $r; } @@ -571,7 +582,7 @@ function poller_worker_process() { * @brief Call the front end worker */ function call_worker() { - if (!Config::get("system", "frontend_worker") OR !Config::get("system", "worker")) { + if (!Config::get("system", "frontend_worker")) { return; } @@ -583,7 +594,7 @@ function call_worker() { * @brief Call the front end worker if there aren't any active */ function call_worker_if_idle() { - if (!Config::get("system", "frontend_worker") OR !Config::get("system", "worker")) { + if (!Config::get("system", "frontend_worker")) { return; } @@ -610,7 +621,7 @@ function call_worker_if_idle() { logger('Call poller', LOGGER_DEBUG); - $args = array("php", "include/poller.php", "no_cron"); + $args = array("include/poller.php", "no_cron"); $a = get_app(); $a->proc_run($args); return; diff --git a/include/pubsubpublish.php b/include/pubsubpublish.php index 428103a971..3641bbcf74 100644 --- a/include/pubsubpublish.php +++ b/include/pubsubpublish.php @@ -1,12 +1,31 @@ 1) { + $pubsubpublish_id = intval($argv[1]); + } else { + // We'll push to each subscriber that has push > 0, + // i.e. there has been an update (set in notifier.php). + $r = q("SELECT `id`, `callback_url` FROM `push_subscriber` WHERE `push` > 0"); + + foreach ($r as $rr) { + logger("Publish feed to ".$rr["callback_url"], LOGGER_DEBUG); + proc_run(PRIORITY_HIGH, 'include/pubsubpublish.php', $rr["id"]); + } + } + + handle_pubsubhubbub($pubsubpublish_id); + + return; +} function handle_pubsubhubbub($id) { - global $a, $db; + global $a; $r = q("SELECT * FROM `push_subscriber` WHERE `id` = %d", intval($id)); if (!$r) @@ -54,70 +73,3 @@ function handle_pubsubhubbub($id) { intval($rr['id'])); } } - - -function pubsubpublish_run(&$argv, &$argc){ - global $a, $db; - - if(is_null($a)){ - $a = new App; - } - - if(is_null($db)){ - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; - - require_once('include/items.php'); - - Config::load(); - - // Don't check this stuff if the function is called by the poller - if (App::callstack() != "poller_run") { - if (App::is_already_running("pubsubpublish", "include/pubsubpublish.php", 540)) { - return; - } - } - - $a->set_baseurl(get_config('system','url')); - - load_hooks(); - - if ($argc > 1) { - $pubsubpublish_id = intval($argv[1]); - } - else { - // We'll push to each subscriber that has push > 0, - // i.e. there has been an update (set in notifier.php). - $r = q("SELECT `id`, `callback_url` FROM `push_subscriber` WHERE `push` > 0"); - - // Use the delivery interval that is also used for the notifier - $interval = Config::get("system", "delivery_interval", 2); - - // If we are using the worker we don't need a delivery interval - if (get_config("system", "worker")) { - $interval = false; - } - - foreach ($r as $rr) { - logger("Publish feed to ".$rr["callback_url"], LOGGER_DEBUG); - proc_run(PRIORITY_HIGH, 'include/pubsubpublish.php', $rr["id"]); - - if($interval) - @time_sleep_until(microtime(true) + (float) $interval); - } - } - - handle_pubsubhubbub($pubsubpublish_id); - - return; - -} - -if (array_search(__file__,get_included_files())===0){ - pubsubpublish_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} - diff --git a/include/queue.php b/include/queue.php index 7e2657fa54..c0c73cda61 100644 --- a/include/queue.php +++ b/include/queue.php @@ -2,41 +2,16 @@ use \Friendica\Core\Config; -require_once("boot.php"); require_once('include/queue_fn.php'); require_once('include/dfrn.php'); +require_once("include/datetime.php"); +require_once('include/items.php'); +require_once('include/bbcode.php'); +require_once('include/socgraph.php'); require_once('include/cache.php'); function queue_run(&$argv, &$argc){ - global $a, $db; - - if (is_null($a)){ - $a = new App; - } - - if (is_null($db)){ - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; - - require_once("include/session.php"); - require_once("include/datetime.php"); - require_once('include/items.php'); - require_once('include/bbcode.php'); - require_once('include/socgraph.php'); - - Config::load(); - - // Don't check this stuff if the function is called by the poller - if (App::callstack() != "poller_run") - if (App::is_already_running('queue', 'include/queue.php', 540)) - return; - - $a->set_baseurl(get_config('system','url')); - - load_hooks(); + global $a; if ($argc > 1) { $queue_id = intval($argv[1]); @@ -54,30 +29,13 @@ function queue_run(&$argv, &$argc){ // Handling the pubsubhubbub requests proc_run(PRIORITY_HIGH,'include/pubsubpublish.php'); - $interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval'))); - - // If we are using the worker we don't need a delivery interval - if (get_config("system", "worker")) - $interval = false; - - $r = q("select * from deliverq where 1"); - if ($r) { - foreach ($r as $rr) { - logger('queue: deliverq'); - proc_run(PRIORITY_HIGH,'include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']); - if ($interval) { - time_sleep_until(microtime(true) + (float) $interval); - } - } - } - $r = q("SELECT `queue`.*, `contact`.`name`, `contact`.`uid` FROM `queue` INNER JOIN `contact` ON `queue`.`cid` = `contact`.`id` WHERE `queue`.`created` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); if ($r) { foreach ($r as $rr) { logger('Removing expired queue item for ' . $rr['name'] . ', uid=' . $rr['uid']); - logger('Expired queue data :' . $rr['content'], LOGGER_DATA); + logger('Expired queue data: ' . $rr['content'], LOGGER_DATA); } q("DELETE FROM `queue` WHERE `created` < UTC_TIMESTAMP() - INTERVAL 3 DAY"); } @@ -86,158 +44,137 @@ function queue_run(&$argv, &$argc){ // After that, we'll only attempt delivery once per hour. $r = q("SELECT `id` FROM `queue` WHERE ((`created` > UTC_TIMESTAMP() - INTERVAL 12 HOUR && `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE) OR (`last` < UTC_TIMESTAMP() - INTERVAL 1 HOUR)) ORDER BY `cid`, `created`"); - } else { - logger('queue: start for id '.$queue_id); - $r = q("SELECT `id` FROM `queue` WHERE `id` = %d LIMIT 1", - intval($queue_id) - ); - } + call_hooks('queue_predeliver', $a, $r); - if (!$r){ + if (dbm::is_result($r)) { + foreach ($r as $q_item) { + logger('Call queue for id '.$q_item['id']); + proc_run(PRIORITY_LOW, "include/queue.php", $q_item['id']); + } + } return; } - if (!$queue_id) - call_hooks('queue_predeliver', $a, $r); - - // delivery loop + // delivering require_once('include/salmon.php'); require_once('include/diaspora.php'); - foreach($r as $q_item) { + $r = q("SELECT * FROM `queue` WHERE `id` = %d LIMIT 1", + intval($queue_id)); - // queue_predeliver hooks may have changed the queue db details, - // so check again if this entry still needs processing + if (!dbm::is_result($r)) { + return; + } - if ($queue_id) { - $qi = q("SELECT * FROM `queue` WHERE `id` = %d LIMIT 1", - intval($queue_id)); - } elseif (get_config("system", "worker")) { - logger('Call queue for id '.$q_item['id']); - proc_run(PRIORITY_LOW, "include/queue.php", $q_item['id']); - continue; - } else - $qi = q("SELECT * FROM `queue` WHERE `id` = %d AND `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE ", - intval($q_item['id'])); + $q_item = $r[0]; - if (!dbm::is_result($qi)) { - continue; + $c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", + intval($q_item['cid']) + ); + + if (!dbm::is_result($c)) { + remove_queue_item($q_item['id']); + return; + } + + $dead = Cache::get($cachekey_deadguy.$c[0]['notify']); + + if (!is_null($dead) AND $dead) { + logger('queue: skipping known dead url: '.$c[0]['notify']); + update_queue_time($q_item['id']); + return; + } + + $server = poco_detect_server($c[0]['url']); + + if ($server != "") { + $vital = Cache::get($cachekey_server.$server); + + if (is_null($vital)) { + logger("Check server ".$server." (".$c[0]["network"].")"); + + $vital = poco_check_server($server, $c[0]["network"], true); + Cache::set($cachekey_server.$server, $vital, CACHE_QUARTER_HOUR); } - - $c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", - intval($qi[0]['cid']) - ); - if (! dbm::is_result($c)) { - remove_queue_item($q_item['id']); - continue; - } - - $dead = Cache::get($cachekey_deadguy.$c[0]['notify']); - - if (!is_null($dead) AND $dead) { - logger('queue: skipping known dead url: '.$c[0]['notify']); + if (!is_null($vital) AND !$vital) { + logger('queue: skipping dead server: '.$server); update_queue_time($q_item['id']); - continue; + return; } + } - $server = poco_detect_server($c[0]['url']); + $u = q("SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey` + FROM `user` WHERE `uid` = %d LIMIT 1", + intval($c[0]['uid']) + ); + if (!dbm::is_result($u)) { + remove_queue_item($q_item['id']); + return; + } - if ($server != "") { - $vital = Cache::get($cachekey_server.$server); + $data = $q_item['content']; + $public = $q_item['batch']; + $contact = $c[0]; + $owner = $u[0]; - if (is_null($vital)) { - logger("Check server ".$server." (".$c[0]["network"].")"); + $deliver_status = 0; - $vital = poco_check_server($server, $c[0]["network"], true); - Cache::set($cachekey_server.$server, $vital, CACHE_QUARTER_HOUR); - } + switch ($contact['network']) { + case NETWORK_DFRN: + logger('queue: dfrndelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); + $deliver_status = dfrn::deliver($owner, $contact, $data); - if (!is_null($vital) AND !$vital) { - logger('queue: skipping dead server: '.$server); + if ($deliver_status == (-1)) { update_queue_time($q_item['id']); - continue; + Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); + } else { + remove_queue_item($q_item['id']); } - } + break; + case NETWORK_OSTATUS: + if ($contact['notify']) { + logger('queue: slapdelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); + $deliver_status = slapper($owner, $contact['notify'], $data); - $u = q("SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey` - FROM `user` WHERE `uid` = %d LIMIT 1", - intval($c[0]['uid']) - ); - if (! dbm::is_result($u)) { - remove_queue_item($q_item['id']); - continue; - } - - $data = $qi[0]['content']; - $public = $qi[0]['batch']; - $contact = $c[0]; - $owner = $u[0]; - - $deliver_status = 0; - - switch($contact['network']) { - case NETWORK_DFRN: - logger('queue: dfrndelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); - $deliver_status = dfrn::deliver($owner,$contact,$data); - - if ($deliver_status < 0) { + if ($deliver_status == (-1)) { update_queue_time($q_item['id']); Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); } else { remove_queue_item($q_item['id']); } - break; - case NETWORK_OSTATUS: - if ($contact['notify']) { - logger('queue: slapdelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); - $deliver_status = slapper($owner,$contact['notify'],$data); + } + break; + case NETWORK_DIASPORA: + if ($contact['notify']) { + logger('queue: diaspora_delivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); + $deliver_status = Diaspora::transmit($owner, $contact, $data, $public, true); - if ($deliver_status == (-1)) { - update_queue_time($q_item['id']); - Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); - } else { - remove_queue_item($q_item['id']); - } - } - break; - case NETWORK_DIASPORA: - if ($contact['notify']) { - logger('queue: diaspora_delivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>'); - $deliver_status = Diaspora::transmit($owner,$contact,$data,$public,true); - - if ($deliver_status == (-1)) { - update_queue_time($q_item['id']); - Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); - } else { - remove_queue_item($q_item['id']); - } - } - break; - - default: - $params = array('owner' => $owner, 'contact' => $contact, 'queue' => $q_item, 'result' => false); - call_hooks('queue_deliver', $a, $params); - - if ($params['result']) { - remove_queue_item($q_item['id']); - } else { + if ($deliver_status == (-1)) { update_queue_time($q_item['id']); + Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR); + } else { + remove_queue_item($q_item['id']); } - break; + } + break; + + default: + $params = array('owner' => $owner, 'contact' => $contact, 'queue' => $q_item, 'result' => false); + call_hooks('queue_deliver', $a, $params); + + if ($params['result']) { + remove_queue_item($q_item['id']); + } else { + update_queue_time($q_item['id']); + } + break; - } - logger('Deliver status '.(int)$deliver_status.' for item '.$q_item['id'].' to '.$contact['name'].' <'.$contact['url'].'>'); } + logger('Deliver status '.(int)$deliver_status.' for item '.$q_item['id'].' to '.$contact['name'].' <'.$contact['url'].'>'); return; - -} - -if (array_search(__file__,get_included_files())===0){ - queue_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); } diff --git a/include/remove_contact.php b/include/remove_contact.php index aa20621116..68bf2adfea 100644 --- a/include/remove_contact.php +++ b/include/remove_contact.php @@ -6,24 +6,7 @@ use \Friendica\Core\Config; -require_once("boot.php"); - function remove_contact_run($argv, $argc) { - global $a, $db; - - if (is_null($a)) { - $a = new App; - } - - if (is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - } - - Config::load(); - if ($argc != 2) { return; } @@ -46,9 +29,4 @@ function remove_contact_run($argv, $argc) { q("DELETE FROM `queue` WHERE `cid` = %d", intval($id)); } - -if (array_search(__file__, get_included_files()) === 0) { - remove_contact_run($_SERVER["argv"], $_SERVER["argc"]); - killme(); -} ?> diff --git a/include/security.php b/include/security.php index afb37a72d8..05371f71ca 100644 --- a/include/security.php +++ b/include/security.php @@ -55,7 +55,7 @@ function authenticate_success($user_record, $login_initial = false, $interactive $a->user = $user_record; if($interactive) { - if($a->user['login_date'] === '0000-00-00 00:00:00') { + if ($a->user['login_date'] <= NULL_DATE) { $_SESSION['return_url'] = 'profile_photo/new'; $a->module = 'profile_photo'; info( t("Welcome ") . $a->user['username'] . EOL); diff --git a/include/shadowupdate.php b/include/shadowupdate.php index 83a785fe1f..5b0a1b94b0 100644 --- a/include/shadowupdate.php +++ b/include/shadowupdate.php @@ -5,20 +5,26 @@ use \Friendica\Core\Config; require_once("boot.php"); require_once("include/threads.php"); -global $a, $db; +function shadowupdate_run(&$argv, &$argc){ + global $a, $db; -if(is_null($a)) - $a = new App; + if (is_null($a)) { + $a = new App; + } -if(is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); + if (is_null($db)) { + @include(".htconfig.php"); + require_once("include/dba.php"); + $db = new dba($db_host, $db_user, $db_pass, $db_data); + unset($db_host, $db_user, $db_pass, $db_data); + } + + Config::load(); + + update_shadow_copy(); } -Config::load(); - -update_shadow_copy(); -killme(); -?> +if (array_search(__file__,get_included_files())===0){ + shadowupdate_run($_SERVER["argv"],$_SERVER["argc"]); + killme(); +} diff --git a/include/socgraph.php b/include/socgraph.php index 01d2cff019..71771bb95d 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -14,8 +14,13 @@ require_once("include/html2bbcode.php"); require_once("include/Contact.php"); require_once("include/Photo.php"); -/* - * poco_load +/** + * @brief Fetch POCO data + * + * @param integer $cid Contact ID + * @param integer $uid User ID + * @param integer $zcid Global Contact ID + * @param integer $url POCO address that should be polled * * Given a contact-id (minimum), load the PortableContacts friend list for that contact, * and add the entries to the gcontact (Global Contact) table, or update existing entries @@ -27,12 +32,21 @@ require_once("include/Photo.php"); * pointing to the same global contact id. * */ +function poco_load($cid, $uid = 0, $zcid = 0, $url = null) { + // Call the function "poco_load_worker" via the worker + proc_run(PRIORITY_LOW, "include/discover_poco.php", "poco_load", intval($cid), intval($uid), intval($zcid), base64_encode($url)); +} - - - -function poco_load($cid,$uid = 0,$zcid = 0,$url = null) { - +/** + * @brief Fetch POCO data from the worker + * + * @param integer $cid Contact ID + * @param integer $uid User ID + * @param integer $zcid Global Contact ID + * @param integer $url POCO address that should be polled + * + */ +function poco_load_worker($cid, $uid, $zcid, $url) { $a = get_app(); if($cid) { @@ -81,7 +95,7 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) { $connect_url = ''; $name = ''; $network = ''; - $updated = '0000-00-00 00:00:00'; + $updated = NULL_DATE; $location = ''; $about = ''; $keywords = ''; @@ -239,12 +253,12 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca ); if (count($x)) { - if (($network == "") AND ($x[0]["network"] != NETWORK_STATUSNET)) + if (($network == "") AND ($x[0]["network"] != NETWORK_STATUSNET)) { $network = $x[0]["network"]; - - if ($updated == "0000-00-00 00:00:00") + } + if ($updated <= NULL_DATE) { $updated = $x[0]["updated"]; - + } $created = $x[0]["created"]; $server_url = $x[0]["server_url"]; $nick = $x[0]["nick"]; @@ -252,7 +266,7 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca $alias = $x[0]["alias"]; $notify = $x[0]["notify"]; } else { - $created = "0000-00-00 00:00:00"; + $created = NULL_DATE; $server_url = ""; $urlparts = parse_url($profile_url); @@ -309,7 +323,18 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca logger("profile-check generation: ".$generation." Network: ".$network." URL: ".$profile_url." name: ".$name." avatar: ".$profile_photo, LOGGER_DEBUG); - poco_check_server($server_url, $network); + // We check the server url to be sure that it is a real one + $server_url2 = poco_detect_server($profile_url); + + // We are no sure that it is a correct URL. So we use it in the future + if ($server_url2 != "") { + $server_url = $server_url2; + } + + // The server URL doesn't seem to be valid, so we don't store it. + if (!poco_check_server($server_url, $network)) { + $server_url = ""; + } $gcontact = array("url" => $profile_url, "addr" => $addr, @@ -401,13 +426,47 @@ function poco_detect_server($profile) { // Mastodon if ($server_url == "") { - $red = preg_replace("=(https?://)(.*)/users/(.*)=ism", "$1$2", $profile); - if ($red != $profile) { - $server_url = $red; + $mastodon = preg_replace("=(https?://)(.*)/users/(.*)=ism", "$1$2", $profile); + if ($mastodon != $profile) { + $server_url = $mastodon; $network = NETWORK_OSTATUS; } } + // Numeric OStatus variant + if ($server_url == "") { + $ostatus = preg_replace("=(https?://)(.*)/user/(.*)=ism", "$1$2", $profile); + if ($ostatus != $profile) { + $server_url = $ostatus; + $network = NETWORK_OSTATUS; + } + } + + // Wild guess + if ($server_url == "") { + $base = preg_replace("=(https?://)(.*?)/(.*)=ism", "$1$2", $profile); + if ($base != $profile) { + $server_url = $base; + $network = NETWORK_PHANTOM; + } + } + + if ($server_url == "") { + return ""; + } + + $r = q("SELECT `id` FROM `gserver` WHERE `nurl` = '%s' AND `last_contact` > `last_failure`", + dbesc(normalise_link($server_url))); + if (dbm::is_result($r)) { + return $server_url; + } + + // Fetch the host-meta to check if this really is a server + $serverret = z_fetch_url($server_url."/.well-known/host-meta"); + if (!$serverret["success"]) { + return ""; + } + return $server_url; } @@ -420,14 +479,16 @@ function poco_last_updated($profile, $force = false) { $gcontacts = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($profile))); - if ($gcontacts[0]["created"] == "0000-00-00 00:00:00") + if ($gcontacts[0]["created"] <= NULL_DATE) { q("UPDATE `gcontact` SET `created` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc(normalise_link($profile))); - - if ($gcontacts[0]["server_url"] != "") + } + if ($gcontacts[0]["server_url"] != "") { $server_url = $gcontacts[0]["server_url"]; - else + } + if (($server_url == '') OR ($gcontacts[0]["server_url"] == $gcontacts[0]["nurl"])) { $server_url = poco_detect_server($profile); + } if (!in_array($gcontacts[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_FEED, NETWORK_OSTATUS, ""))) { logger("Profile ".$profile.": Network type ".$gcontacts[0]["network"]." can't be checked", LOGGER_DEBUG); @@ -617,10 +678,11 @@ function poco_last_updated($profile, $force = false) { } // Maybe there aren't any entries. Then check if it is a valid feed - if ($last_updated == "") - if ($xpath->query('/atom:feed')->length > 0) - $last_updated = "0000-00-00 00:00:00"; - + if ($last_updated == "") { + if ($xpath->query('/atom:feed')->length > 0) { + $last_updated = NULL_DATE; + } + } q("UPDATE `gcontact` SET `updated` = '%s', `last_contact` = '%s' WHERE `nurl` = '%s'", dbesc(dbm::date($last_updated)), dbesc(dbm::date()), dbesc(normalise_link($profile))); @@ -680,6 +742,213 @@ function poco_to_boolean($val) { return ($val); } +/** + * @brief Detect server type (Hubzilla or Friendica) via the poco data + * + * @param object $data POCO data + * @return array Server data + */ +function poco_detect_poco_data($data) { + $server = false; + + if (!isset($data->entry)) { + return false; + } + + if (count($data->entry) == 0) { + return false; + } + + if (!isset($data->entry[0]->urls)) { + return false; + } + + if (count($data->entry[0]->urls) == 0) { + return false; + } + + foreach ($data->entry[0]->urls AS $url) { + if ($url->type == 'zot') { + $server = array(); + $server["platform"] = 'Hubzilla'; + $server["network"] = NETWORK_DIASPORA; + return $server; + } + } + return false; +} + +/** + * @brief Detect server type by using the nodeinfo data + * + * @param string $server_url address of the server + * @return array Server data + */ +function poco_fetch_nodeinfo($server_url) { + $serverret = z_fetch_url($server_url."/.well-known/nodeinfo"); + if (!$serverret["success"]) { + return false; + } + + $nodeinfo = json_decode($serverret['body']); + + if (!is_object($nodeinfo)) { + return false; + } + + if (!is_array($nodeinfo->links)) { + return false; + } + + $nodeinfo_url = ''; + + foreach ($nodeinfo->links AS $link) { + if ($link->rel == 'http://nodeinfo.diaspora.software/ns/schema/1.0') { + $nodeinfo_url = $link->href; + } + } + + if ($nodeinfo_url == '') { + return false; + } + + $serverret = z_fetch_url($nodeinfo_url); + if (!$serverret["success"]) { + return false; + } + + $nodeinfo = json_decode($serverret['body']); + + if (!is_object($nodeinfo)) { + return false; + } + + $server = array(); + + $server['register_policy'] = REGISTER_CLOSED; + + if (is_bool($nodeinfo->openRegistrations) AND $nodeinfo->openRegistrations) { + $server['register_policy'] = REGISTER_OPEN; + } + + if (is_object($nodeinfo->software)) { + if (isset($nodeinfo->software->name)) { + $server['platform'] = $nodeinfo->software->name; + } + + if (isset($nodeinfo->software->version)) { + $server['version'] = $nodeinfo->software->version; + // Version numbers on Nodeinfo are presented with additional info, e.g.: + // 0.6.3.0-p1702cc1c, 0.6.99.0-p1b9ab160 or 3.4.3-2-1191. + $server['version'] = preg_replace("=(.+)-(.{4,})=ism", "$1", $server['version']); + } + } + + if (is_object($nodeinfo->metadata)) { + if (isset($nodeinfo->metadata->nodeName)) { + $server['site_name'] = $nodeinfo->metadata->nodeName; + } + } + + $diaspora = false; + $friendica = false; + $gnusocial = false; + + if (is_array($nodeinfo->protocols->inbound)) { + foreach ($nodeinfo->protocols->inbound AS $inbound) { + if ($inbound == 'diaspora') { + $diaspora = true; + } + if ($inbound == 'friendica') { + $friendica = true; + } + if ($inbound == 'gnusocial') { + $gnusocial = true; + } + } + } + + if ($gnusocial) { + $server['network'] = NETWORK_OSTATUS; + } + if ($diaspora) { + $server['network'] = NETWORK_DIASPORA; + } + if ($friendica) { + $server['network'] = NETWORK_DFRN; + } + + if (!$server) { + return false; + } + + return $server; +} + +/** + * @brief Detect server type (Hubzilla or Friendica) via the front page body + * + * @param string $body Front page of the server + * @return array Server data + */ +function poco_detect_server_type($body) { + $server = false; + + $doc = new \DOMDocument(); + @$doc->loadHTML($body); + $xpath = new \DomXPath($doc); + + $list = $xpath->query("//meta[@name]"); + + foreach ($list as $node) { + $attr = array(); + if ($node->attributes->length) { + foreach ($node->attributes as $attribute) { + $attr[$attribute->name] = $attribute->value; + } + } + if ($attr['name'] == 'generator') { + $version_part = explode(" ", $attr['content']); + if (count($version_part) == 2) { + if (in_array($version_part[0], array("Friendika", "Friendica"))) { + $server = array(); + $server["platform"] = $version_part[0]; + $server["version"] = $version_part[1]; + $server["network"] = NETWORK_DFRN; + } + } + } + } + + if (!$server) { + $list = $xpath->query("//meta[@property]"); + + foreach ($list as $node) { + $attr = array(); + if ($node->attributes->length) { + foreach ($node->attributes as $attribute) { + $attr[$attribute->name] = $attribute->value; + } + } + if ($attr['property'] == 'generator') { + if (in_array($attr['content'], array("hubzilla", "BlaBlaNet"))) { + $server = array(); + $server["platform"] = $attr['content']; + $server["version"] = ""; + $server["network"] = NETWORK_DIASPORA; + } + } + } + } + + if (!$server) { + return false; + } + + $server["site_name"] = $xpath->evaluate($element."//head/title/text()", $context)->item(0)->nodeValue; + return $server; +} + function poco_check_server($server_url, $network = "", $force = false) { // Unify the server address @@ -692,10 +961,10 @@ function poco_check_server($server_url, $network = "", $force = false) { $servers = q("SELECT * FROM `gserver` WHERE `nurl` = '%s'", dbesc(normalise_link($server_url))); if (dbm::is_result($servers)) { - if ($servers[0]["created"] == "0000-00-00 00:00:00") + if ($servers[0]["created"] <= NULL_DATE) { q("UPDATE `gserver` SET `created` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc(normalise_link($server_url))); - + } $poco = $servers[0]["poco"]; $noscrape = $servers[0]["noscrape"]; @@ -723,13 +992,15 @@ function poco_check_server($server_url, $network = "", $force = false) { $info = ""; $register_policy = -1; - $last_contact = "0000-00-00 00:00:00"; - $last_failure = "0000-00-00 00:00:00"; + $last_contact = NULL_DATE; + $last_failure = NULL_DATE; } logger("Server ".$server_url." is outdated or unknown. Start discovery. Force: ".$force." Created: ".$servers[0]["created"]." Failure: ".$last_failure." Contact: ".$last_contact, LOGGER_DEBUG); $failure = false; + $possible_failure = false; $orig_last_failure = $last_failure; + $orig_last_contact = $last_contact; // Check if the page is accessible via SSL. $orig_server_url = $server_url; @@ -769,18 +1040,58 @@ function poco_check_server($server_url, $network = "", $force = false) { $last_failure = datetime_convert(); $failure = true; } + $possible_failure = true; } elseif ($network == NETWORK_DIASPORA) $last_contact = datetime_convert(); + // If the server has no possible failure we reset the cached data + if (!$possible_failure) { + $version = ""; + $platform = ""; + $site_name = ""; + $info = ""; + $register_policy = -1; + } + + // Look for poco if (!$failure) { - // Test for Diaspora + $serverret = z_fetch_url($server_url."/poco"); + if ($serverret["success"]) { + $data = json_decode($serverret["body"]); + if (isset($data->totalResults)) { + $poco = $server_url."/poco"; + $last_contact = datetime_convert(); + + $server = poco_detect_poco_data($data); + if ($server) { + $platform = $server['platform']; + $network = $server['network']; + $version = ''; + $site_name = ''; + } + } + } + } + + if (!$failure) { + // Test for Diaspora, Hubzilla, Mastodon or older Friendica servers $serverret = z_fetch_url($server_url); - if (!$serverret["success"] OR ($serverret["body"] == "")) + if (!$serverret["success"] OR ($serverret["body"] == "")) { + $last_failure = datetime_convert(); $failure = true; - else { + } else { + $server = poco_detect_server_type($serverret["body"]); + if ($server) { + $platform = $server['platform']; + $network = $server['network']; + $version = $server['version']; + $site_name = $server['site_name']; + $last_contact = datetime_convert(); + } + $lines = explode("\n",$serverret["header"]); - if(count($lines)) + if(count($lines)) { foreach($lines as $line) { $line = trim($line); if(stristr($line,'X-Diaspora-Version:')) { @@ -790,6 +1101,7 @@ function poco_check_server($server_url, $network = "", $force = false) { $network = NETWORK_DIASPORA; $versionparts = explode("-", $version); $version = $versionparts[0]; + $last_contact = datetime_convert(); } if(stristr($line,'Server: Mastodon')) { @@ -797,12 +1109,14 @@ function poco_check_server($server_url, $network = "", $force = false) { $network = NETWORK_OSTATUS; // Mastodon doesn't reveal version numbers $version = ""; + $last_contact = datetime_convert(); } } + } } } - if (!$failure) { + if (!$failure AND ($poco == "")) { // Test for Statusnet // Will also return data for Friendica and GNU Social - but it will be overwritten later // The "not implemented" is a special treatment for really, really old Friendica versions @@ -810,8 +1124,11 @@ function poco_check_server($server_url, $network = "", $force = false) { if ($serverret["success"] AND ($serverret["body"] != '{"error":"not implemented"}') AND ($serverret["body"] != '') AND (strlen($serverret["body"]) < 30)) { $platform = "StatusNet"; - $version = trim($serverret["body"], '"'); + // Remove junk that some GNU Social servers return + $version = str_replace(chr(239).chr(187).chr(191), "", $serverret["body"]); + $version = trim($version, '"'); $network = NETWORK_OSTATUS; + $last_contact = datetime_convert(); } // Test for GNU Social @@ -819,17 +1136,32 @@ function poco_check_server($server_url, $network = "", $force = false) { if ($serverret["success"] AND ($serverret["body"] != '{"error":"not implemented"}') AND ($serverret["body"] != '') AND (strlen($serverret["body"]) < 30)) { $platform = "GNU Social"; - $version = trim($serverret["body"], '"'); + // Remove junk that some GNU Social servers return + $version = str_replace(chr(239).chr(187).chr(191), "", $serverret["body"]); + $version = trim($version, '"'); $network = NETWORK_OSTATUS; + $last_contact = datetime_convert(); } + } + if (!$failure) { + // Test for Hubzilla, Redmatrix or Friendica $serverret = z_fetch_url($server_url."/api/statusnet/config.json"); if ($serverret["success"]) { $data = json_decode($serverret["body"]); - if (isset($data->site->server)) { $last_contact = datetime_convert(); + if (isset($data->site->platform)) { + $platform = $data->site->platform->PLATFORM_NAME; + $version = $data->site->platform->STD_VERSION; + $network = NETWORK_DIASPORA; + } + if (isset($data->site->BlaBlaNet)) { + $platform = $data->site->BlaBlaNet->PLATFORM_NAME; + $version = $data->site->BlaBlaNet->STD_VERSION; + $network = NETWORK_DIASPORA; + } if (isset($data->site->hubzilla)) { $platform = $data->site->hubzilla->PLATFORM_NAME; $version = $data->site->hubzilla->RED_VERSION; @@ -866,32 +1198,66 @@ function poco_check_server($server_url, $network = "", $force = false) { } } + // Query statistics.json. Optional package for Diaspora, Friendica and Redmatrix if (!$failure) { $serverret = z_fetch_url($server_url."/statistics.json"); if ($serverret["success"]) { $data = json_decode($serverret["body"]); - if ($version == "") + if (isset($data->version)) { $version = $data->version; + // Version numbers on statistics.json are presented with additional info, e.g.: + // 0.6.3.0-p1702cc1c, 0.6.99.0-p1b9ab160 or 3.4.3-2-1191. + $version = preg_replace("=(.+)-(.{4,})=ism", "$1", $version); + } $site_name = $data->name; - if (isset($data->network) AND ($platform == "")) + if (isset($data->network)) { $platform = $data->network; + } - if ($platform == "Diaspora") + if ($platform == "Diaspora") { $network = NETWORK_DIASPORA; + } - if ($data->registrations_open) + if ($data->registrations_open) { $register_policy = REGISTER_OPEN; - else + } else { $register_policy = REGISTER_CLOSED; + } if (isset($data->version)) $last_contact = datetime_convert(); } } + // Query nodeinfo. Working for (at least) Diaspora and Friendica. + if (!$failure) { + $server = poco_fetch_nodeinfo($server_url); + if ($server) { + $register_policy = $server['register_policy']; + + if (isset($server['platform'])) { + $platform = $server['platform']; + } + + if (isset($server['network'])) { + $network = $server['network']; + } + + if (isset($server['version'])) { + $version = $server['version']; + } + + if (isset($server['site_name'])) { + $site_name = $server['site_name']; + } + + $last_contact = datetime_convert(); + } + } + // Check for noscrape // Friendica servers could be detected as OStatus servers if (!$failure AND in_array($network, array(NETWORK_DFRN, NETWORK_OSTATUS))) { @@ -929,16 +1295,21 @@ function poco_check_server($server_url, $network = "", $force = false) { } } - // Look for poco - if (!$failure) { - $serverret = z_fetch_url($server_url."/poco"); - if ($serverret["success"]) { - $data = json_decode($serverret["body"]); - if (isset($data->totalResults)) { - $poco = $server_url."/poco"; - $last_contact = datetime_convert(); - } - } + if ($possible_failure AND !$failure) { + $last_failure = datetime_convert(); + $failure = true; + } + + if ($failure) { + $last_contact = $orig_last_contact; + } else { + $last_failure = $orig_last_failure; + } + + if (($last_contact <= $last_failure) AND !$failure) { + logger("Server ".$server_url." seems to be alive, but last contact wasn't set - could be a bug", LOGGER_DEBUG); + } else if (($last_contact >= $last_failure) AND $failure) { + logger("Server ".$server_url." seems to be dead, but last failure wasn't set - could be a bug", LOGGER_DEBUG); } // Check again if the server exists @@ -949,7 +1320,7 @@ function poco_check_server($server_url, $network = "", $force = false) { $info = strip_tags($info); $platform = strip_tags($platform); - if ($servers) + if ($servers) { q("UPDATE `gserver` SET `url` = '%s', `version` = '%s', `site_name` = '%s', `info` = '%s', `register_policy` = %d, `poco` = '%s', `noscrape` = '%s', `network` = '%s', `platform` = '%s', `last_contact` = '%s', `last_failure` = '%s' WHERE `nurl` = '%s'", dbesc($server_url), @@ -965,7 +1336,7 @@ function poco_check_server($server_url, $network = "", $force = false) { dbesc($last_failure), dbesc(normalise_link($server_url)) ); - else + } elseif (!$failure) { q("INSERT INTO `gserver` (`url`, `nurl`, `version`, `site_name`, `info`, `register_policy`, `poco`, `noscrape`, `network`, `platform`, `created`, `last_contact`, `last_failure`) VALUES ('%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s')", dbesc($server_url), @@ -983,7 +1354,7 @@ function poco_check_server($server_url, $network = "", $force = false) { dbesc($last_failure), dbesc(datetime_convert()) ); - + } logger("End discovery for server ".$server_url, LOGGER_DEBUG); return !$failure; @@ -1147,7 +1518,7 @@ function suggestion_query($uid, $start = 0, $limit = 80) { where uid = %d and not gcontact.nurl in ( select nurl from contact where uid = %d ) AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d) AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d) - AND `gcontact`.`updated` != '0000-00-00 00:00:00' + AND `gcontact`.`updated` >= '%s' AND `gcontact`.`last_contact` >= `gcontact`.`last_failure` AND `gcontact`.`network` IN (%s) GROUP BY `glink`.`gcid` ORDER BY `gcontact`.`updated` DESC,`total` DESC LIMIT %d, %d", @@ -1155,6 +1526,7 @@ function suggestion_query($uid, $start = 0, $limit = 80) { intval($uid), intval($uid), intval($uid), + dbesc(NULL_DATE), $sql_network, intval($start), intval($limit) @@ -1173,13 +1545,14 @@ function suggestion_query($uid, $start = 0, $limit = 80) { WHERE `glink`.`uid` = 0 AND `glink`.`cid` = 0 AND `glink`.`zcid` = 0 AND NOT `gcontact`.`nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` = %d) AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d) AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d) - AND `gcontact`.`updated` != '0000-00-00 00:00:00' + AND `gcontact`.`updated` >= '%s' AND `gcontact`.`last_contact` >= `gcontact`.`last_failure` AND `gcontact`.`network` IN (%s) ORDER BY rand() LIMIT %d, %d", intval($uid), intval($uid), intval($uid), + dbesc(NULL_DATE), $sql_network, intval($start), intval($limit) @@ -1244,6 +1617,33 @@ function update_suggestions() { } } +/** + * @brief Fetch server list from remote servers and adds them when they are new. + * + * @param string $poco URL to the POCO endpoint + */ +function poco_fetch_serverlist($poco) { + $serverret = z_fetch_url($poco."/@server"); + if (!$serverret["success"]) { + return; + } + $serverlist = json_decode($serverret['body']); + + if (!is_array($serverlist)) { + return; + } + + foreach ($serverlist AS $server) { + $server_url = str_replace("/index.php", "", $server->url); + + $r = q("SELECT `nurl` FROM `gserver` WHERE `nurl` = '%s'", dbesc(normalise_link($server_url))); + if (!dbm::is_result($r)) { + logger("Call server check for server ".$server_url, LOGGER_DEBUG); + proc_run(PRIORITY_LOW, "include/discover_poco.php", "server", base64_encode($server_url)); + } + } +} + function poco_discover_federation() { $last = get_config('poco','last_federation_discovery'); @@ -1259,8 +1659,9 @@ function poco_discover_federation() { if ($serverdata) { $servers = json_decode($serverdata); - foreach($servers->pods AS $server) - poco_check_server("https://".$server->host); + foreach ($servers->pods AS $server) { + proc_run(PRIORITY_LOW, "include/discover_poco.php", "server", base64_encode("https://".$server->host)); + } } // Currently disabled, since the service isn't available anymore. @@ -1281,6 +1682,68 @@ function poco_discover_federation() { set_config('poco','last_federation_discovery', time()); } +function poco_discover_single_server($id) { + $r = q("SELECT `poco`, `nurl`, `url`, `network` FROM `gserver` WHERE `id` = %d", intval($id)); + if (!dbm::is_result($r)) { + return false; + } + + $server = $r[0]; + + // Discover new servers out there (Works from Friendica version 3.5.2) + poco_fetch_serverlist($server["poco"]); + + // Fetch all users from the other server + $url = $server["poco"]."/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation"; + + logger("Fetch all users from the server ".$server["url"], LOGGER_DEBUG); + + $retdata = z_fetch_url($url); + if ($retdata["success"]) { + $data = json_decode($retdata["body"]); + + poco_discover_server($data, 2); + + if (get_config('system','poco_discovery') > 1) { + + $timeframe = get_config('system','poco_discovery_since'); + if ($timeframe == 0) { + $timeframe = 30; + } + + $updatedSince = date("Y-m-d H:i:s", time() - $timeframe * 86400); + + // Fetch all global contacts from the other server (Not working with Redmatrix and Friendica versions before 3.3) + $url = $server["poco"]."/@global?updatedSince=".$updatedSince."&fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation"; + + $success = false; + + $retdata = z_fetch_url($url); + if ($retdata["success"]) { + logger("Fetch all global contacts from the server ".$server["nurl"], LOGGER_DEBUG); + $success = poco_discover_server(json_decode($retdata["body"])); + } + + if (!$success AND (get_config('system','poco_discovery') > 2)) { + logger("Fetch contacts from users of the server ".$server["nurl"], LOGGER_DEBUG); + poco_discover_server_users($data, $server); + } + } + + q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); + + return true; + } else { + // If the server hadn't replied correctly, then force a sanity check + poco_check_server($server["url"], $server["network"], true); + + // If we couldn't reach the server, we will try it some time later + q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); + + return false; + } +} + function poco_discover($complete = false) { // Update the server list @@ -1290,13 +1753,13 @@ function poco_discover($complete = false) { $requery_days = intval(get_config("system", "poco_requery_days")); - if ($requery_days == 0) + if ($requery_days == 0) { $requery_days = 7; - + } $last_update = date("c", time() - (60 * 60 * 24 * $requery_days)); - $r = q("SELECT `poco`, `nurl`, `url`, `network` FROM `gserver` WHERE `last_contact` >= `last_failure` AND `poco` != '' AND `last_poco_query` < '%s' ORDER BY RAND()", dbesc($last_update)); - if ($r) + $r = q("SELECT `id`, `url`, `network` FROM `gserver` WHERE `last_contact` >= `last_failure` AND `poco` != '' AND `last_poco_query` < '%s' ORDER BY RAND()", dbesc($last_update)); + if (dbm::is_result($r)) { foreach ($r AS $server) { if (!poco_check_server($server["url"], $server["network"])) { @@ -1305,53 +1768,14 @@ function poco_discover($complete = false) { continue; } - // Fetch all users from the other server - $url = $server["poco"]."/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation"; + logger('Update directory from server '.$server['url'].' with ID '.$server['id'], LOGGER_DEBUG); + proc_run(PRIORITY_LOW, "include/discover_poco.php", "update_server_directory", intval($server['id'])); - logger("Fetch all users from the server ".$server["nurl"], LOGGER_DEBUG); - - $retdata = z_fetch_url($url); - if ($retdata["success"]) { - $data = json_decode($retdata["body"]); - - poco_discover_server($data, 2); - - if (get_config('system','poco_discovery') > 1) { - - $timeframe = get_config('system','poco_discovery_since'); - if ($timeframe == 0) - $timeframe = 30; - - $updatedSince = date("Y-m-d H:i:s", time() - $timeframe * 86400); - - // Fetch all global contacts from the other server (Not working with Redmatrix and Friendica versions before 3.3) - $url = $server["poco"]."/@global?updatedSince=".$updatedSince."&fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation"; - - $success = false; - - $retdata = z_fetch_url($url); - if ($retdata["success"]) { - logger("Fetch all global contacts from the server ".$server["nurl"], LOGGER_DEBUG); - $success = poco_discover_server(json_decode($retdata["body"])); - } - - if (!$success AND (get_config('system','poco_discovery') > 2)) { - logger("Fetch contacts from users of the server ".$server["nurl"], LOGGER_DEBUG); - poco_discover_server_users($data, $server); - } - } - - q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); - if (!$complete AND (--$no_of_queries == 0)) - break; - } else { - // If the server hadn't replied correctly, then force a sanity check - poco_check_server($server["url"], $server["network"], true); - - // If we couldn't reach the server, we will try it some time later - q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); + if (!$complete AND (--$no_of_queries == 0)) { + break; } } + } } function poco_discover_server_users($data, $server) { @@ -1395,7 +1819,7 @@ function poco_discover_server($data, $default_generation = 0) { $connect_url = ''; $name = ''; $network = ''; - $updated = '0000-00-00 00:00:00'; + $updated = NULL_DATE; $location = ''; $about = ''; $keywords = ''; @@ -1879,4 +2303,20 @@ function gs_discover() { q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", dbesc(datetime_convert()), dbesc($server["nurl"])); } } + +/** + * @brief Returns a list of all known servers + * @return array List of server urls + */ +function poco_serverlist() { + $r = q("SELECT `url`, `site_name` AS `displayName`, `network`, `platform`, `version` FROM `gserver` + WHERE `network` IN ('%s', '%s', '%s') AND `last_contact` > `last_failure` + ORDER BY `last_contact` + LIMIT 1000", + dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS)); + if (!dbm::is_result($r)) { + return false; + } + return $r; +} ?> diff --git a/include/spool_post.php b/include/spool_post.php index b4cce46b57..f64b39e4b6 100644 --- a/include/spool_post.php +++ b/include/spool_post.php @@ -6,24 +6,10 @@ use \Friendica\Core\Config; -require_once("boot.php"); require_once("include/items.php"); function spool_post_run($argv, $argc) { - global $a, $db; - - if (is_null($a)) { - $a = new App; - } - - if (is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - } - - Config::load(); + global $a; $path = get_spoolpath(); @@ -69,9 +55,4 @@ function spool_post_run($argv, $argc) { } } } - -if (array_search(__file__, get_included_files()) === 0) { - spool_post_run($_SERVER["argv"], $_SERVER["argc"]); - killme(); -} ?> diff --git a/include/tagupdate.php b/include/tagupdate.php index b4de121e9f..1e97135c5b 100644 --- a/include/tagupdate.php +++ b/include/tagupdate.php @@ -1,24 +1,6 @@ diff --git a/include/text.php b/include/text.php index 6619dec93a..4a23b7ac37 100644 --- a/include/text.php +++ b/include/text.php @@ -903,10 +903,10 @@ function contact_block() { intval($shown) ); if (dbm::is_result($r)) { - $contacts = ""; - foreach ($r AS $contact) + $contacts = array(); + foreach ($r AS $contact) { $contacts[] = $contact["id"]; - + } $r = q("SELECT `id`, `uid`, `addr`, `url`, `name`, `thumb`, `network` FROM `contact` WHERE `id` IN (%s)", dbesc(implode(",", $contacts))); diff --git a/include/threadupdate.php b/include/threadupdate.php index dc528c6b87..3a4028603e 100644 --- a/include/threadupdate.php +++ b/include/threadupdate.php @@ -1,25 +1,7 @@ diff --git a/include/uimport.php b/include/uimport.php index b774d78c6d..4cc5b6c04b 100644 --- a/include/uimport.php +++ b/include/uimport.php @@ -11,14 +11,11 @@ define("IMPORT_DEBUG", False); function last_insert_id() { global $db; + if (IMPORT_DEBUG) return 1; - if ($db->mysqli) { - $thedb = $db->getdb(); - return $thedb->insert_id; - } else { - return mysql_insert_id(); - } + + return $db->insert_id(); } function last_error() { @@ -186,8 +183,8 @@ function import_account(App $a, $file) { } } if ($contact['uid'] == $olduid && $contact['self'] == '0') { - // set contacts 'avatar-date' to "0000-00-00 00:00:00" to let poller to update urls - $contact["avatar-date"] = "0000-00-00 00:00:00" ; + // set contacts 'avatar-date' to NULL_DATE to let poller to update urls + $contact["avatar-date"] = NULL_DATE; switch ($contact['network']) { diff --git a/include/update_gcontact.php b/include/update_gcontact.php index 6aa8bcac29..08d4149a71 100644 --- a/include/update_gcontact.php +++ b/include/update_gcontact.php @@ -2,46 +2,23 @@ use \Friendica\Core\Config; -require_once("boot.php"); - function update_gcontact_run(&$argv, &$argc){ - global $a, $db; - - if(is_null($a)) { - $a = new App; - } - - if(is_null($db)) { - @include(".htconfig.php"); - require_once("include/dba.php"); - $db = new dba($db_host, $db_user, $db_pass, $db_data); - unset($db_host, $db_user, $db_pass, $db_data); - }; + global $a; require_once('include/Scrape.php'); - require_once("include/socgraph.php"); - - Config::load(); - - $a->set_baseurl(get_config('system','url')); - - load_hooks(); + require_once('include/socgraph.php'); logger('update_gcontact: start'); - if(($argc > 1) && (intval($argv[1]))) + if (($argc > 1) && (intval($argv[1]))) { $contact_id = intval($argv[1]); + } - if(!$contact_id) { + if (!$contact_id) { logger('update_gcontact: no contact'); return; } - // Don't check this stuff if the function is called by the poller - if (App::callstack() != "poller_run") - if (App::is_already_running('update_gcontact'.$contact_id, '', 540)) - return; - $r = q("SELECT * FROM `gcontact` WHERE `id` = %d", intval($contact_id)); if (!$r) @@ -98,8 +75,3 @@ function update_gcontact_run(&$argv, &$argc){ dbesc(normalise_link($data["url"])) ); } - -if (array_search(__file__,get_included_files())===0){ - update_gcontact_run($_SERVER["argv"],$_SERVER["argc"]); - killme(); -} diff --git a/include/user.php b/include/user.php index df871c5468..cd77707dd0 100644 --- a/include/user.php +++ b/include/user.php @@ -97,13 +97,6 @@ function create_user($arr) { if(mb_strlen($username) < 3) $result['message'] .= t('Name too short.') . EOL; - // I don't really like having this rule, but it cuts down - // on the number of auto-registrations by Russian spammers - - // Using preg_match was completely unreliable, due to mixed UTF-8 regex support - // $no_utf = get_config('system','no_utf'); - // $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' ); - // So now we are just looking for a space in the full name. $loose_reg = get_config('system','no_regfullname'); diff --git a/library/Smarty/libs/plugins/modifier.date_format.php b/library/Smarty/libs/plugins/modifier.date_format.php index 5ad7540b15..c5992991de 100644 --- a/library/Smarty/libs/plugins/modifier.date_format.php +++ b/library/Smarty/libs/plugins/modifier.date_format.php @@ -36,7 +36,7 @@ function smarty_modifier_date_format($string, $format = null, $default_date = '' * Include the {@link shared.make_timestamp.php} plugin */ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); - if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') { + if ($string != '' && $string > '0001-01-01' && $string > NULL_DATE) { $timestamp = smarty_make_timestamp($string); } elseif ($default_date != '') { $timestamp = smarty_make_timestamp($default_date); diff --git a/library/markdown.php b/library/markdown.php index a8152c2ab6..769bdb1219 100644 --- a/library/markdown.php +++ b/library/markdown.php @@ -1,24 +1,17 @@ hard_wrap = true; + $html = $MarkdownParser->transform($text); $a->save_timestamp($stamp1, "parser"); return $html; } -?> diff --git a/library/php-markdown/License.md b/library/php-markdown/License.md index 8a5b85447e..c16197b692 100644 --- a/library/php-markdown/License.md +++ b/library/php-markdown/License.md @@ -1,11 +1,11 @@ PHP Markdown Lib -Copyright (c) 2004-2014 Michel Fortin - +Copyright (c) 2004-2016 Michel Fortin + All rights reserved. Based on Markdown Copyright (c) 2003-2006 John Gruber - + All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/library/php-markdown/Michelf/Markdown.inc.php b/library/php-markdown/Michelf/Markdown.inc.php index 8c281094ce..e2bd3808e8 100644 --- a/library/php-markdown/Michelf/Markdown.inc.php +++ b/library/php-markdown/Michelf/Markdown.inc.php @@ -1,10 +1,10 @@ -# -# Original Markdown -# Copyright (c) 2004-2006 John Gruber -# -# +/** + * Markdown - A text-to-HTML conversion tool for web writers + * + * @package php-markdown + * @author Michel Fortin + * @copyright 2004-2016 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + namespace Michelf; - -# -# Markdown Parser Class -# - +/** + * Markdown Parser Class + */ class Markdown implements MarkdownInterface { + /** + * Define the package version + * @var string + */ + const MARKDOWNLIB_VERSION = "1.7.0"; - ### Version ### - - const MARKDOWNLIB_VERSION = "1.4.1"; - - ### Simple Function Interface ### - + /** + * Simple function interface - Initialize the parser and return the result + * of its transform method. This will work fine for derived classes too. + * + * @api + * + * @param string $text + * @return string + */ public static function defaultTransform($text) { - # - # Initialize the parser and return the result of its transform method. - # This will work fine for derived classes too. - # - # Take parser class on which this function was called. + // Take parser class on which this function was called. $parser_class = \get_called_class(); - # try to take parser from the static parser list + // Try to take parser from the static parser list static $parser_list; $parser =& $parser_list[$parser_class]; - # create the parser it not already set - if (!$parser) + // Create the parser it not already set + if (!$parser) { $parser = new $parser_class; + } - # Transform text using parser. + // Transform text using parser. return $parser->transform($text); } - ### Configuration Variables ### + /** + * Configuration variables + */ - # Change to ">" for HTML output. + /** + * Change to ">" for HTML output. + * @var string + */ public $empty_element_suffix = " />"; + + /** + * The width of indentation of the output markup + * @var int + */ public $tab_width = 4; - - # Change to `true` to disallow markup or entities. - public $no_markup = false; + + /** + * Change to `true` to disallow markup or entities. + * @var boolean + */ + public $no_markup = false; public $no_entities = false; - - # Predefined urls and titles for reference links and images. - public $predef_urls = array(); + + + /** + * Change to `true` to enable line breaks on \n without two trailling spaces + * @var boolean + */ + public $hard_wrap = false; + + /** + * Predefined URLs and titles for reference links and images. + * @var array + */ + public $predef_urls = array(); public $predef_titles = array(); - # Optional filter function for URLs + /** + * Optional filter function for URLs + * @var callable + */ public $url_filter_func = null; + /** + * Optional header id="" generation callback function. + * @var callable + */ + public $header_id_func = null; - ### Parser Implementation ### + /** + * Optional function for converting code block content to HTML + * @var callable + */ + public $code_block_content_func = null; - # Regex to match balanced [brackets]. - # Needed to insert a maximum bracked depth while converting to PHP. + /** + * Optional function for converting code span content to HTML. + * @var callable + */ + public $code_span_content_func = null; + + /** + * Class attribute to toggle "enhanced ordered list" behaviour + * setting this to true will allow ordered lists to start from the index + * number that is defined first. + * + * For example: + * 2. List item two + * 3. List item three + * + * Becomes: + *
    + *
  1. List item two
  2. + *
  3. List item three
  4. + *
+ * + * @var bool + */ + public $enhanced_ordered_list = false; + + /** + * Parser implementation + */ + + /** + * Regex to match balanced [brackets]. + * Needed to insert a maximum bracked depth while converting to PHP. + * @var int + */ protected $nested_brackets_depth = 6; protected $nested_brackets_re; - + protected $nested_url_parenthesis_depth = 4; protected $nested_url_parenthesis_re; - # Table of hash values for escaped characters: + /** + * Table of hash values for escaped characters: + * @var string + */ protected $escape_chars = '\`*_{}[]()>#+-.!'; protected $escape_chars_re; - + /** + * Constructor function. Initialize appropriate member variables. + * @return void + */ public function __construct() { - # - # Constructor function. Initialize appropriate member variables. - # $this->_initDetab(); $this->prepareItalicsAndBold(); - - $this->nested_brackets_re = + + $this->nested_brackets_re = str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). str_repeat('\])*', $this->nested_brackets_depth); - - $this->nested_url_parenthesis_re = + + $this->nested_url_parenthesis_re = str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); - + $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; - - # Sort document, block, and span gamut in ascendent priority order. + + // Sort document, block, and span gamut in ascendent priority order. asort($this->document_gamut); asort($this->block_gamut); asort($this->span_gamut); } - # Internal hashes used during transformation. - protected $urls = array(); - protected $titles = array(); + /** + * Internal hashes used during transformation. + * @var array + */ + protected $urls = array(); + protected $titles = array(); protected $html_hashes = array(); - - # Status flag to avoid invalid nesting. + + /** + * Status flag to avoid invalid nesting. + * @var boolean + */ protected $in_anchor = false; - - + + /** + * Called before the transformation process starts to setup parser states. + * @return void + */ protected function setup() { - # - # Called before the transformation process starts to setup parser - # states. - # - # Clear global hashes. - $this->urls = $this->predef_urls; - $this->titles = $this->predef_titles; + // Clear global hashes. + $this->urls = $this->predef_urls; + $this->titles = $this->predef_titles; $this->html_hashes = array(); - - $this->in_anchor = false; + $this->in_anchor = false; } - + + /** + * Called after the transformation process to clear any variable which may + * be taking up memory unnecessarly. + * @return void + */ protected function teardown() { - # - # Called after the transformation process to clear any variable - # which may be taking up memory unnecessarly. - # - $this->urls = array(); - $this->titles = array(); + $this->urls = array(); + $this->titles = array(); $this->html_hashes = array(); } - + /** + * Main function. Performs some preprocessing on the input text and pass + * it through the document gamut. + * + * @api + * + * @param string $text + * @return string + */ public function transform($text) { - # - # Main function. Performs some preprocessing on the input text - # and pass it through the document gamut. - # $this->setup(); - + # Remove UTF-8 BOM and marker character in input, if present. $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); @@ -168,28 +248,33 @@ class Markdown implements MarkdownInterface { foreach ($this->document_gamut as $method => $priority) { $text = $this->$method($text); } - + $this->teardown(); return $text . "\n"; } - + + /** + * Define the document gamut + * @var array + */ protected $document_gamut = array( - # Strip link definitions, store in hashes. + // Strip link definitions, store in hashes. "stripLinkDefinitions" => 20, - "runBasicBlockGamut" => 30, - ); - + ); + /** + * Strips link definitions from text, stores the URLs and titles in + * hash references + * @param string $text + * @return string + */ protected function stripLinkDefinitions($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # + $less_than_tab = $this->tab_width - 1; - # Link defs are in the form: ^[id]: url "optional title" + // Link defs are in the form: ^[id]: url "optional title" $text = preg_replace_callback('{ ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 [ ]* @@ -213,43 +298,58 @@ class Markdown implements MarkdownInterface { (?:\n+|\Z) }xm', array($this, '_stripLinkDefinitions_callback'), - $text); + $text + ); return $text; } + + /** + * The callback to strip link definitions + * @param array $matches + * @return string + */ protected function _stripLinkDefinitions_callback($matches) { $link_id = strtolower($matches[1]); $url = $matches[2] == '' ? $matches[3] : $matches[2]; $this->urls[$link_id] = $url; $this->titles[$link_id] =& $matches[4]; - return ''; # String that will replace the block + return ''; // String that will replace the block } - + /** + * Hashify HTML blocks + * @param string $text + * @return string + */ protected function hashHTMLBlocks($text) { - if ($this->no_markup) return $text; + if ($this->no_markup) { + return $text; + } $less_than_tab = $this->tab_width - 1; - # Hashify HTML blocks: - # We only want to do this for block-level HTML tags, such as headers, - # lists, and tables. That's because we still want to wrap

s around - # "paragraphs" that are wrapped in non-block-level tags, such as anchors, - # phrase emphasis, and spans. The list of tags we're looking for is - # hard-coded: - # - # * List "a" is made of tags which can be both inline or block-level. - # These will be treated block-level when the start tag is alone on - # its line, otherwise they're not matched here and will be taken as - # inline later. - # * List "b" is made of tags which are always block-level; - # + /** + * Hashify HTML blocks: + * + * We only want to do this for block-level HTML tags, such as headers, + * lists, and tables. That's because we still want to wrap

s around + * "paragraphs" that are wrapped in non-block-level tags, such as + * anchors, phrase emphasis, and spans. The list of tags we're looking + * for is hard-coded: + * + * * List "a" is made of tags which can be both inline or block-level. + * These will be treated block-level when the start tag is alone on + * its line, otherwise they're not matched here and will be taken as + * inline later. + * * List "b" is made of tags which are always block-level; + */ $block_tags_a_re = 'ins|del'; $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. 'script|noscript|style|form|fieldset|iframe|math|svg|'. 'article|section|nav|aside|hgroup|header|footer|'. 'figure'; - # Regular expression for the content of a block tag. + // Regular expression for the content of a block tag. $nested_tags_level = 4; $attr = ' (?> # optional tag attributes @@ -263,7 +363,7 @@ class Markdown implements MarkdownInterface { | \'[^\']*\' # text inside single quotes (tolerate ">") )* - )? + )? '; $content = str_repeat(' @@ -275,29 +375,32 @@ class Markdown implements MarkdownInterface { (?> /> | - >', $nested_tags_level). # end of opening tag - '.*?'. # last level nested tag content + >', $nested_tags_level). // end of opening tag + '.*?'. // last level nested tag content str_repeat(' # closing nested tag ) - | + | <(?!/\2\s*> # other tags with a different name ) )*', $nested_tags_level); $content2 = str_replace('\2', '\3', $content); - # First, look for nested blocks, e.g.: - #

- #
- # tags for inner block must be indented. - #
- #
- # - # The outermost tags must start at the left margin for this to match, and - # the inner nested divs must be indented. - # We need to do this before the next, more liberal match, because the next - # match will start at the first `
` and stop at the first `
`. + /** + * First, look for nested blocks, e.g.: + *
+ *
+ * tags for inner block must be indented. + *
+ *
+ * + * The outermost tags must start at the left margin for this to match, + * and the inner nested divs must be indented. + * We need to do this before the next, more liberal match, because the + * next match will start at the first `
` and stop at the + * first `
`. + */ $text = preg_replace_callback('{(?> (?> (?<=\n) # Starting on its own line @@ -306,9 +409,9 @@ class Markdown implements MarkdownInterface { ) ( # save in $1 - # Match from `\n` to `\n`, handling nested tags + # Match from `\n` to `\n`, handling nested tags # in between. - + [ ]{0,'.$less_than_tab.'} <('.$block_tags_b_re.')# start tag = $2 '.$attr.'> # attributes followed by > and \n @@ -326,28 +429,28 @@ class Markdown implements MarkdownInterface { # the matching end tag [ ]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document - - | # Special case just for
. It was easier to make a special + + | # Special case just for
. It was easier to make a special # case than to make the other regex more complicated. - + [ ]{0,'.$less_than_tab.'} <(hr) # start tag = $2 '.$attr.' # attributes /?> # the matching end tag [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document - + | # Special case for standalone HTML comments: - + [ ]{0,'.$less_than_tab.'} (?s: ) [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document - + | # PHP and ASP-style processor instructions (hashBlock($text); return "\n\n$key\n\n"; } - - + + /** + * Called whenever a tag must be hashed when a function insert an atomic + * element in the text stream. Passing $text to through this function gives + * a unique text-token which will be reverted back when calling unhash. + * + * The $boundary argument specify what character should be used to surround + * the token. By convension, "B" is used for block elements that needs not + * to be wrapped into paragraph tags at the end, ":" is used for elements + * that are word separators and "X" is used in the general case. + * + * @param string $text + * @param string $boundary + * @return string + */ protected function hashPart($text, $boundary = 'X') { - # - # Called whenever a tag must be hashed when a function insert an atomic - # element in the text stream. Passing $text to through this function gives - # a unique text-token which will be reverted back when calling unhash. - # - # The $boundary argument specify what character should be used to surround - # the token. By convension, "B" is used for block elements that needs not - # to be wrapped into paragraph tags at the end, ":" is used for elements - # that are word separators and "X" is used in the general case. - # - # Swap back any tag hash found in $text so we do not have to `unhash` - # multiple times at the end. + // Swap back any tag hash found in $text so we do not have to `unhash` + // multiple times at the end. $text = $this->unhash($text); - - # Then hash the block. + + // Then hash the block. static $i = 0; $key = "$boundary\x1A" . ++$i . $boundary; $this->html_hashes[$key] = $text; - return $key; # String that will replace the tag. + return $key; // String that will replace the tag. } - + /** + * Shortcut function for hashPart with block-level boundaries. + * @param string $text + * @return string + */ protected function hashBlock($text) { - # - # Shortcut function for hashPart with block-level boundaries. - # return $this->hashPart($text, 'B'); } - + /** + * Define the block gamut - these are all the transformations that form + * block-level tags like paragraphs, headers, and list items. + * @var array + */ protected $block_gamut = array( - # - # These are all the transformations that form block-level - # tags like paragraphs, headers, and list items. - # "doHeaders" => 10, "doHorizontalRules" => 20, - "doLists" => 40, "doCodeBlocks" => 50, "doBlockQuotes" => 60, - ); + ); + /** + * Run block gamut tranformations. + * + * We need to escape raw HTML in Markdown source before doing anything + * else. This need to be done for each block, and not only at the + * begining in the Markdown function since hashed blocks can be part of + * list items and could have been indented. Indented blocks would have + * been seen as a code block in a previous pass of hashHTMLBlocks. + * + * @param string $text + * @return string + */ protected function runBlockGamut($text) { - # - # Run block gamut tranformations. - # - # We need to escape raw HTML in Markdown source before doing anything - # else. This need to be done for each block, and not only at the - # begining in the Markdown function since hashed blocks can be part of - # list items and could have been indented. Indented blocks would have - # been seen as a code block in a previous pass of hashHTMLBlocks. $text = $this->hashHTMLBlocks($text); - return $this->runBasicBlockGamut($text); } - + + /** + * Run block gamut tranformations, without hashing HTML blocks. This is + * useful when HTML blocks are known to be already hashed, like in the first + * whole-document pass. + * + * @param string $text + * @return string + */ protected function runBasicBlockGamut($text) { - # - # Run block gamut tranformations, without hashing HTML blocks. This is - # useful when HTML blocks are known to be already hashed, like in the first - # whole-document pass. - # + foreach ($this->block_gamut as $method => $priority) { $text = $this->$method($text); } - - # Finally form paragraph and restore hashed blocks. + + // Finally form paragraph and restore hashed blocks. $text = $this->formParagraphs($text); return $text; } - - + + /** + * Convert horizontal rules + * @param string $text + * @return string + */ protected function doHorizontalRules($text) { - # Do Horizontal Rules: return preg_replace( '{ ^[ ]{0,3} # Leading space @@ -459,67 +582,82 @@ class Markdown implements MarkdownInterface { [ ]* # Tailing spaces $ # End of line. }mx', - "\n".$this->hashBlock("empty_element_suffix")."\n", - $text); + "\n".$this->hashBlock("empty_element_suffix")."\n", + $text + ); } - + /** + * These are all the transformations that occur *within* block-level + * tags like paragraphs, headers, and list items. + * @var array + */ protected $span_gamut = array( - # - # These are all the transformations that occur *within* block-level - # tags like paragraphs, headers, and list items. - # - # Process character escapes, code spans, and inline HTML - # in one shot. + // Process character escapes, code spans, and inline HTML + // in one shot. "parseSpan" => -30, - - # Process anchor and image tags. Images must come first, - # because ![foo][f] looks like an anchor. + // Process anchor and image tags. Images must come first, + // because ![foo][f] looks like an anchor. "doImages" => 10, "doAnchors" => 20, - - # Make links out of things like `` - # Must come after doAnchors, because you can use < and > - # delimiters in inline links like [this](). + // Make links out of things like `` + // Must come after doAnchors, because you can use < and > + // delimiters in inline links like [this](). "doAutoLinks" => 30, "encodeAmpsAndAngles" => 40, - "doItalicsAndBold" => 50, "doHardBreaks" => 60, - ); + ); + /** + * Run span gamut transformations + * @param string $text + * @return string + */ protected function runSpanGamut($text) { - # - # Run span gamut tranformations. - # foreach ($this->span_gamut as $method => $priority) { $text = $this->$method($text); } return $text; } - - + + /** + * Do hard breaks + * @param string $text + * @return string + */ protected function doHardBreaks($text) { - # Do hard breaks: - return preg_replace_callback('/ {2,}\n/', - array($this, '_doHardBreaks_callback'), $text); + if ($this->hard_wrap) { + return preg_replace_callback('/ *\n/', + array($this, '_doHardBreaks_callback'), $text); + } else { + return preg_replace_callback('/ {2,}\n/', + array($this, '_doHardBreaks_callback'), $text); + } } + + /** + * Trigger part hashing for the hard break (callback method) + * @param array $matches + * @return string + */ protected function _doHardBreaks_callback($matches) { return $this->hashPart("empty_element_suffix\n"); } - + /** + * Turn Markdown link shortcuts into XHTML tags. + * @param string $text + * @return string + */ protected function doAnchors($text) { - # - # Turn Markdown link shortcuts into XHTML tags. - # - if ($this->in_anchor) return $text; + if ($this->in_anchor) { + return $text; + } $this->in_anchor = true; - - # - # First, handle reference-style links: [link text] [id] - # + + // First, handle reference-style links: [link text] [id] $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ @@ -536,9 +674,7 @@ class Markdown implements MarkdownInterface { }xs', array($this, '_doAnchors_reference_callback'), $text); - # - # Next, inline-style links: [link text](url "optional title") - # + // Next, inline-style links: [link text](url "optional title") $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ @@ -563,11 +699,9 @@ class Markdown implements MarkdownInterface { }xs', array($this, '_doAnchors_inline_callback'), $text); - # - # Last, handle reference-style shortcuts: [link text] - # These must come last in case you've also got [link text][1] - # or [link text](/foo) - # + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link text][1] + // or [link text](/foo) $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ @@ -580,48 +714,60 @@ class Markdown implements MarkdownInterface { $this->in_anchor = false; return $text; } + + /** + * Callback method to parse referenced anchors + * @param string $matches + * @return string + */ protected function _doAnchors_reference_callback($matches) { $whole_match = $matches[1]; $link_text = $matches[2]; $link_id =& $matches[3]; if ($link_id == "") { - # for shortcut links like [this][] or [this]. + // for shortcut links like [this][] or [this]. $link_id = $link_text; } - - # lower-case and turn embedded newlines into spaces + + // lower-case and turn embedded newlines into spaces $link_id = strtolower($link_id); $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); if (isset($this->urls[$link_id])) { $url = $this->urls[$link_id]; $url = $this->encodeURLAttribute($url); - + $result = "titles[$link_id] ) ) { $title = $this->titles[$link_id]; $title = $this->encodeAttribute($title); $result .= " title=\"$title\""; } - + $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text"; $result = $this->hashPart($result); - } - else { + } else { $result = $whole_match; } return $result; } + + /** + * Callback method to parse inline anchors + * @param string $matches + * @return string + */ protected function _doAnchors_inline_callback($matches) { $whole_match = $matches[1]; $link_text = $this->runSpanGamut($matches[2]); $url = $matches[3] == '' ? $matches[4] : $matches[3]; $title =& $matches[7]; - // if the URL was of the form it got caught by the HTML - // tag parser and hashed. Need to reverse the process before using the URL. + // If the URL was of the form it got caught by the HTML + // tag parser and hashed. Need to reverse the process before using + // the URL. $unhashed = $this->unhash($url); if ($unhashed != $url) $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); @@ -633,21 +779,20 @@ class Markdown implements MarkdownInterface { $title = $this->encodeAttribute($title); $result .= " title=\"$title\""; } - + $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text"; return $this->hashPart($result); } - + /** + * Turn Markdown image shortcuts into tags. + * @param string $text + * @return string + */ protected function doImages($text) { - # - # Turn Markdown image shortcuts into tags. - # - # - # First, handle reference-style labeled images: ![alt text][id] - # + // First, handle reference-style labeled images: ![alt text][id] $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ @@ -662,13 +807,11 @@ class Markdown implements MarkdownInterface { \] ) - }xs', + }xs', array($this, '_doImages_reference_callback'), $text); - # - # Next, handle inline images: ![alt text](url "optional title") - # Don't forget: encode * and _ - # + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ @@ -696,13 +839,19 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * Callback to parse references image tags + * @param array $matches + * @return string + */ protected function _doImages_reference_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; $link_id = strtolower($matches[3]); if ($link_id == "") { - $link_id = strtolower($alt_text); # for shortcut links like ![this][]. + $link_id = strtolower($alt_text); // for shortcut links like ![this][]. } $alt_text = $this->encodeAttribute($alt_text); @@ -716,14 +865,19 @@ class Markdown implements MarkdownInterface { } $result .= $this->empty_element_suffix; $result = $this->hashPart($result); - } - else { - # If there's no such link ID, leave intact: + } else { + // If there's no such link ID, leave intact: $result = $whole_match; } return $result; } + + /** + * Callback to parse inline image tags + * @param array $matches + * @return string + */ protected function _doImages_inline_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; @@ -735,32 +889,38 @@ class Markdown implements MarkdownInterface { $result = "\"$alt_text\"";encodeAttribute($title); - $result .= " title=\"$title\""; # $title already quoted + $result .= " title=\"$title\""; // $title already quoted } $result .= $this->empty_element_suffix; return $this->hashPart($result); } - + /** + * Parse Markdown heading elements to HTML + * @param string $text + * @return string + */ protected function doHeaders($text) { - # Setext-style headers: - # Header 1 - # ======== - # - # Header 2 - # -------- - # + /** + * Setext-style headers: + * Header 1 + * ======== + * + * Header 2 + * -------- + */ $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', array($this, '_doHeaders_callback_setext'), $text); - # atx-style headers: - # # Header 1 - # ## Header 2 - # ## Header 2 with closing hashes ## - # ... - # ###### Header 6 - # + /** + * atx-style headers: + * # Header 1 + * ## Header 2 + * ## Header 2 with closing hashes ## + * ... + * ###### Header 6 + */ $text = preg_replace_callback('{ ^(\#{1,6}) # $1 = string of #\'s [ ]* @@ -773,29 +933,72 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * Setext header parsing callback + * @param array $matches + * @return string + */ protected function _doHeaders_callback_setext($matches) { - # Terrible hack to check we haven't found an empty list item. - if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) + // Terrible hack to check we haven't found an empty list item. + if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) { return $matches[0]; - + } + $level = $matches[2]{0} == '=' ? 1 : 2; - $block = "".$this->runSpanGamut($matches[1]).""; + + // ID attribute generation + $idAtt = $this->_generateIdFromHeaderValue($matches[1]); + + $block = "".$this->runSpanGamut($matches[1]).""; return "\n" . $this->hashBlock($block) . "\n\n"; } + + /** + * ATX header parsing callback + * @param array $matches + * @return string + */ protected function _doHeaders_callback_atx($matches) { + // ID attribute generation + $idAtt = $this->_generateIdFromHeaderValue($matches[2]); + $level = strlen($matches[1]); - $block = "".$this->runSpanGamut($matches[2]).""; + $block = "".$this->runSpanGamut($matches[2]).""; return "\n" . $this->hashBlock($block) . "\n\n"; } + /** + * If a header_id_func property is set, we can use it to automatically + * generate an id attribute. + * + * This method returns a string in the form id="foo", or an empty string + * otherwise. + * @param string $headerValue + * @return string + */ + protected function _generateIdFromHeaderValue($headerValue) { + if (!is_callable($this->header_id_func)) { + return ""; + } + $idValue = call_user_func($this->header_id_func, $headerValue); + if (!$idValue) { + return ""; + } + + return ' id="' . $this->encodeAttribute($idValue) . '"'; + } + + /** + * Form HTML ordered (numbered) and unordered (bulleted) lists. + * @param string $text + * @return string + */ protected function doLists($text) { - # - # Form HTML ordered (numbered) and unordered (bulleted) lists. - # $less_than_tab = $this->tab_width - 1; - # Re-usable patterns to match list item bullets and number markers: + // Re-usable patterns to match list item bullets and number markers: $marker_ul_re = '[*+-]'; $marker_ol_re = '\d+[\.]'; @@ -805,7 +1008,7 @@ class Markdown implements MarkdownInterface { ); foreach ($markers_relist as $marker_re => $other_marker_re) { - # Re-usable pattern to match any entirel ul or ol list: + // Re-usable pattern to match any entirel ul or ol list: $whole_list_re = ' ( # $1 = whole list ( # $2 @@ -832,18 +1035,17 @@ class Markdown implements MarkdownInterface { ) ) '; // mx - - # We use a different prefix before nested lists than top-level lists. - # See extended comment in _ProcessListItems(). - + + // We use a different prefix before nested lists than top-level lists. + //See extended comment in _ProcessListItems(). + if ($this->list_level) { $text = preg_replace_callback('{ ^ '.$whole_list_re.' }mx', array($this, '_doLists_callback'), $text); - } - else { + } else { $text = preg_replace_callback('{ (?:(?<=\n)\n|\A\n?) # Must eat the newline '.$whole_list_re.' @@ -854,55 +1056,86 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * List parsing callback + * @param array $matches + * @return string + */ protected function _doLists_callback($matches) { - # Re-usable patterns to match list item bullets and number markers: + // Re-usable patterns to match list item bullets and number markers: $marker_ul_re = '[*+-]'; $marker_ol_re = '\d+[\.]'; $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; - + $marker_ol_start_re = '[0-9]+'; + $list = $matches[1]; $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol"; - + $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re ); - + $list .= "\n"; $result = $this->processListItems($list, $marker_any_re); - - $result = $this->hashBlock("<$list_type>\n" . $result . ""); + + $ol_start = 1; + if ($this->enhanced_ordered_list) { + // Get the start number for ordered list. + if ($list_type == 'ol') { + $ol_start_array = array(); + $ol_start_check = preg_match("/$marker_ol_start_re/", $matches[4], $ol_start_array); + if ($ol_start_check){ + $ol_start = $ol_start_array[0]; + } + } + } + + if ($ol_start > 1 && $list_type == 'ol'){ + $result = $this->hashBlock("<$list_type start=\"$ol_start\">\n" . $result . ""); + } else { + $result = $this->hashBlock("<$list_type>\n" . $result . ""); + } return "\n". $result ."\n\n"; } + /** + * Nesting tracker for list levels + * @var integer + */ protected $list_level = 0; + /** + * Process the contents of a single ordered or unordered list, splitting it + * into individual list items. + * @param string $list_str + * @param string $marker_any_re + * @return string + */ protected function processListItems($list_str, $marker_any_re) { - # - # Process the contents of a single ordered or unordered list, splitting it - # into individual list items. - # - # The $this->list_level global keeps track of when we're inside a list. - # Each time we enter a list, we increment it; when we leave a list, - # we decrement. If it's zero, we're not in a list anymore. - # - # We do this because when we're not inside a list, we want to treat - # something like this: - # - # I recommend upgrading to version - # 8. Oops, now this line is treated - # as a sub-list. - # - # As a single paragraph, despite the fact that the second line starts - # with a digit-period-space sequence. - # - # Whereas when we're inside a list (or sub-list), that line will be - # treated as the start of a sub-list. What a kludge, huh? This is - # an aspect of Markdown's syntax that's hard to parse perfectly - # without resorting to mind-reading. Perhaps the solution is to - # change the syntax rules such that sub-lists must start with a - # starting cardinal number; e.g. "1." or "a.". - + /** + * The $this->list_level global keeps track of when we're inside a list. + * Each time we enter a list, we increment it; when we leave a list, + * we decrement. If it's zero, we're not in a list anymore. + * + * We do this because when we're not inside a list, we want to treat + * something like this: + * + * I recommend upgrading to version + * 8. Oops, now this line is treated + * as a sub-list. + * + * As a single paragraph, despite the fact that the second line starts + * with a digit-period-space sequence. + * + * Whereas when we're inside a list (or sub-list), that line will be + * treated as the start of a sub-list. What a kludge, huh? This is + * an aspect of Markdown's syntax that's hard to parse perfectly + * without resorting to mind-reading. Perhaps the solution is to + * change the syntax rules such that sub-lists must start with a + * starting cardinal number; e.g. "1." or "a.". + */ $this->list_level++; - # trim trailing blank lines: + // Trim trailing blank lines: $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); $list_str = preg_replace_callback('{ @@ -920,6 +1153,12 @@ class Markdown implements MarkdownInterface { $this->list_level--; return $list_str; } + + /** + * List item parsing callback + * @param array $matches + * @return string + */ protected function _processListItems_callback($matches) { $item = $matches[4]; $leading_line =& $matches[1]; @@ -927,28 +1166,27 @@ class Markdown implements MarkdownInterface { $marker_space = $matches[3]; $tailing_blank_line =& $matches[5]; - if ($leading_line || $tailing_blank_line || + if ($leading_line || $tailing_blank_line || preg_match('/\n{2,}/', $item)) { - # Replace marker with the appropriate whitespace indentation + // Replace marker with the appropriate whitespace indentation $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; $item = $this->runBlockGamut($this->outdent($item)."\n"); - } - else { - # Recursion for sub-lists: + } else { + // Recursion for sub-lists: $item = $this->doLists($this->outdent($item)); - $item = preg_replace('/\n+$/', '', $item); - $item = $this->runSpanGamut($item); + $item = $this->formParagraphs($item, false); } return "
  • " . $item . "
  • \n"; } - + /** + * Process Markdown `
    ` blocks.
    +	 * @param  string $text
    +	 * @return string
    +	 */
     	protected function doCodeBlocks($text) {
    -	#
    -	#	Process Markdown `
    ` blocks.
    -	#
     		$text = preg_replace_callback('{
     				(?:\n\n|\A\n?)
     				(	            # $1 = the code block -- one or more lines, starting with a space/tab
    @@ -963,106 +1201,141 @@ class Markdown implements MarkdownInterface {
     
     		return $text;
     	}
    +
    +	/**
    +	 * Code block parsing callback
    +	 * @param  array $matches
    +	 * @return string
    +	 */
     	protected function _doCodeBlocks_callback($matches) {
     		$codeblock = $matches[1];
     
     		$codeblock = $this->outdent($codeblock);
    -		$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    +		if ($this->code_block_content_func) {
    +			$codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
    +		} else {
    +			$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    +		}
     
     		# trim leading newlines and trailing newlines
     		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
     
     		$codeblock = "
    $codeblock\n
    "; - return "\n\n".$this->hashBlock($codeblock)."\n\n"; + return "\n\n" . $this->hashBlock($codeblock) . "\n\n"; } - + /** + * Create a code span markup for $code. Called from handleSpanToken. + * @param string $code + * @return string + */ protected function makeCodeSpan($code) { - # - # Create a code span markup for $code. Called from handleSpanToken. - # - $code = htmlspecialchars(trim($code), ENT_NOQUOTES); + if ($this->code_span_content_func) { + $code = call_user_func($this->code_span_content_func, $code); + } else { + $code = htmlspecialchars(trim($code), ENT_NOQUOTES); + } return $this->hashPart("$code"); } - + /** + * Define the emphasis operators with their regex matches + * @var array + */ protected $em_relist = array( '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(?em_relist as $em => $em_re) { foreach ($this->strong_relist as $strong => $strong_re) { - # Construct list of allowed token expressions. + // Construct list of allowed token expressions. $token_relist = array(); if (isset($this->em_strong_relist["$em$strong"])) { $token_relist[] = $this->em_strong_relist["$em$strong"]; } $token_relist[] = $em_re; $token_relist[] = $strong_re; - - # Construct master expression from list. - $token_re = '{('. implode('|', $token_relist) .')}'; + + // Construct master expression from list. + $token_re = '{(' . implode('|', $token_relist) . ')}'; $this->em_strong_prepared_relist["$em$strong"] = $token_re; } } } - + + /** + * Convert Markdown italics (emphasis) and bold (strong) to HTML + * @param string $text + * @return string + */ protected function doItalicsAndBold($text) { $token_stack = array(''); $text_stack = array(''); $em = ''; $strong = ''; $tree_char_em = false; - + while (1) { - # - # Get prepared regular expression for seraching emphasis tokens - # in current context. - # + // Get prepared regular expression for seraching emphasis tokens + // in current context. $token_re = $this->em_strong_prepared_relist["$em$strong"]; - - # - # Each loop iteration search for the next emphasis token. - # Each token is then passed to handleSpanToken. - # + + // Each loop iteration search for the next emphasis token. + // Each token is then passed to handleSpanToken. $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); $text_stack[0] .= $parts[0]; $token =& $parts[1]; $text =& $parts[2]; - + if (empty($token)) { - # Reached end of text span: empty stack without emitting. - # any more emphasis. + // Reached end of text span: empty stack without emitting. + // any more emphasis. while ($token_stack[0]) { $text_stack[1] .= array_shift($token_stack); $text_stack[0] .= array_shift($text_stack); } break; } - + $token_len = strlen($token); if ($tree_char_em) { - # Reached closing marker while inside a three-char emphasis. + // Reached closing marker while inside a three-char emphasis. if ($token_len == 3) { - # Three-char closing marker, close em and strong. + // Three-char closing marker, close em and strong. array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); @@ -1071,21 +1344,21 @@ class Markdown implements MarkdownInterface { $em = ''; $strong = ''; } else { - # Other closing marker: close one em or strong and - # change current token state to match the other + // Other closing marker: close one em or strong and + // change current token state to match the other $token_stack[0] = str_repeat($token{0}, 3-$token_len); $tag = $token_len == 2 ? "strong" : "em"; $span = $text_stack[0]; $span = $this->runSpanGamut($span); $span = "<$tag>$span"; $text_stack[0] = $this->hashPart($span); - $$tag = ''; # $$tag stands for $em or $strong + $$tag = ''; // $$tag stands for $em or $strong } $tree_char_em = false; } else if ($token_len == 3) { if ($em) { - # Reached closing marker for both em and strong. - # Closing strong marker: + // Reached closing marker for both em and strong. + // Closing strong marker: for ($i = 0; $i < 2; ++$i) { $shifted_token = array_shift($token_stack); $tag = strlen($shifted_token) == 2 ? "strong" : "em"; @@ -1093,11 +1366,11 @@ class Markdown implements MarkdownInterface { $span = $this->runSpanGamut($span); $span = "<$tag>$span"; $text_stack[0] .= $this->hashPart($span); - $$tag = ''; # $$tag stands for $em or $strong + $$tag = ''; // $$tag stands for $em or $strong } } else { - # Reached opening three-char emphasis marker. Push on token - # stack; will be handled by the special condition above. + // Reached opening three-char emphasis marker. Push on token + // stack; will be handled by the special condition above. $em = $token{0}; $strong = "$em$em"; array_unshift($token_stack, $token); @@ -1106,12 +1379,12 @@ class Markdown implements MarkdownInterface { } } else if ($token_len == 2) { if ($strong) { - # Unwind any dangling emphasis marker: + // Unwind any dangling emphasis marker: if (strlen($token_stack[0]) == 1) { $text_stack[1] .= array_shift($token_stack); $text_stack[0] .= array_shift($text_stack); } - # Closing strong marker: + // Closing strong marker: array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); @@ -1124,10 +1397,10 @@ class Markdown implements MarkdownInterface { $strong = $token; } } else { - # Here $token_len == 1 + // Here $token_len == 1 if ($em) { if (strlen($token_stack[0]) == 1) { - # Closing emphasis marker: + // Closing emphasis marker: array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); @@ -1147,7 +1420,11 @@ class Markdown implements MarkdownInterface { return $text_stack[0]; } - + /** + * Parse Markdown blockquotes to HTML + * @param string $text + * @return string + */ protected function doBlockQuotes($text) { $text = preg_replace_callback('/ ( # Wrap whole match in $1 @@ -1163,51 +1440,64 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * Blockquote parsing callback + * @param array $matches + * @return string + */ protected function _doBlockQuotes_callback($matches) { $bq = $matches[1]; - # trim one level of quoting - trim whitespace-only lines + // trim one level of quoting - trim whitespace-only lines $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); - $bq = $this->runBlockGamut($bq); # recurse + $bq = $this->runBlockGamut($bq); // recurse $bq = preg_replace('/^/m', " ", $bq); - # These leading spaces cause problem with
     content, 
    -		# so we need to fix that:
    -		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', + // These leading spaces cause problem with
     content,
    +		// so we need to fix that:
    +		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', array($this, '_doBlockQuotes_callback2'), $bq); - return "\n". $this->hashBlock("
    \n$bq\n
    ")."\n\n"; + return "\n" . $this->hashBlock("
    \n$bq\n
    ") . "\n\n"; } + + /** + * Blockquote parsing callback + * @param array $matches + * @return string + */ protected function _doBlockQuotes_callback2($matches) { $pre = $matches[1]; $pre = preg_replace('/^ /m', '', $pre); return $pre; } - - protected function formParagraphs($text) { - # - # Params: - # $text - string to process with html

    tags - # - # Strip leading and trailing lines: + /** + * Parse paragraphs + * + * @param string $text String to process in paragraphs + * @param boolean $wrap_in_p Whether paragraphs should be wrapped in

    tags + * @return string + */ + protected function formParagraphs($text, $wrap_in_p = true) { + // Strip leading and trailing lines: $text = preg_replace('/\A\n+|\n+\z/', '', $text); $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); - # - # Wrap

    tags and unhashify HTML blocks - # + // Wrap

    tags and unhashify HTML blocks foreach ($grafs as $key => $value) { if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { - # Is a paragraph. + // Is a paragraph. $value = $this->runSpanGamut($value); - $value = preg_replace('/^([ ]*)/', "

    ", $value); - $value .= "

    "; + if ($wrap_in_p) { + $value = preg_replace('/^([ ]*)/', "

    ", $value); + $value .= "

    "; + } $grafs[$key] = $this->unhash($value); - } - else { - # Is a block. - # Modify elements of @grafs in-place... + } else { + // Is a block. + // Modify elements of @grafs in-place... $graf = $value; $block = $this->html_hashes[$graf]; $graf = $block; @@ -1232,11 +1522,11 @@ class Markdown implements MarkdownInterface { // { // list(, $div_open, , $div_content, $div_close) = $matches; // -// # We can't call Markdown(), because that resets the hash; -// # that initialization code should be pulled into its own sub, though. +// // We can't call Markdown(), because that resets the hash; +// // that initialization code should be pulled into its own sub, though. // $div_content = $this->hashHTMLBlocks($div_content); -// -// # Run document gamut methods on the content. +// +// // Run document gamut methods on the content. // foreach ($this->document_gamut as $method => $priority) { // $div_content = $this->$method($div_content); // } @@ -1253,71 +1543,78 @@ class Markdown implements MarkdownInterface { return implode("\n\n", $grafs); } - + /** + * Encode text for a double-quoted HTML attribute. This function + * is *not* suitable for attributes enclosed in single quotes. + * @param string $text + * @return string + */ protected function encodeAttribute($text) { - # - # Encode text for a double-quoted HTML attribute. This function - # is *not* suitable for attributes enclosed in single quotes. - # $text = $this->encodeAmpsAndAngles($text); $text = str_replace('"', '"', $text); return $text; } - + /** + * Encode text for a double-quoted HTML attribute containing a URL, + * applying the URL filter if set. Also generates the textual + * representation for the URL (removing mailto: or tel:) storing it in $text. + * This function is *not* suitable for attributes enclosed in single quotes. + * + * @param string $url + * @param string &$text Passed by reference + * @return string URL + */ protected function encodeURLAttribute($url, &$text = null) { - # - # Encode text for a double-quoted HTML attribute containing a URL, - # applying the URL filter if set. Also generates the textual - # representation for the URL (removing mailto: or tel:) storing it in $text. - # This function is *not* suitable for attributes enclosed in single quotes. - # - if ($this->url_filter_func) + if ($this->url_filter_func) { $url = call_user_func($this->url_filter_func, $url); + } - if (preg_match('{^mailto:}i', $url)) + if (preg_match('{^mailto:}i', $url)) { $url = $this->encodeEntityObfuscatedAttribute($url, $text, 7); - else if (preg_match('{^tel:}i', $url)) - { + } else if (preg_match('{^tel:}i', $url)) { $url = $this->encodeAttribute($url); $text = substr($url, 4); - } - else - { + } else { $url = $this->encodeAttribute($url); $text = $url; } return $url; } - - + + /** + * Smart processing for ampersands and angle brackets that need to + * be encoded. Valid character entities are left alone unless the + * no-entities mode is set. + * @param string $text + * @return string + */ protected function encodeAmpsAndAngles($text) { - # - # Smart processing for ampersands and angle brackets that need to - # be encoded. Valid character entities are left alone unless the - # no-entities mode is set. - # if ($this->no_entities) { $text = str_replace('&', '&', $text); } else { - # Ampersand-encoding based entirely on Nat Irons's Amputator - # MT plugin: - $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', + // Ampersand-encoding based entirely on Nat Irons's Amputator + // MT plugin: + $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', '&', $text); } - # Encode remaining <'s + // Encode remaining <'s $text = str_replace('<', '<', $text); return $text; } - + /** + * Parse Markdown automatic links to anchor HTML tags + * @param string $text + * @return string + */ protected function doAutoLinks($text) { $text = preg_replace_callback('{<((https?|ftp|dict|tel):[^\'">\s]+)>}i', array($this, '_doAutoLinks_url_callback'), $text); - # Email addresses: + // Email addresses: $text = preg_replace_callback('{ < (?:mailto:)? @@ -1340,11 +1637,23 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * Parse URL callback + * @param array $matches + * @return string + */ protected function _doAutoLinks_url_callback($matches) { $url = $this->encodeURLAttribute($matches[1], $text); $link = "$text"; return $this->hashPart($link); } + + /** + * Parse email address callback + * @param array $matches + * @return string + */ protected function _doAutoLinks_email_callback($matches) { $addr = $matches[1]; $url = $this->encodeURLAttribute("mailto:$addr", $text); @@ -1352,42 +1661,52 @@ class Markdown implements MarkdownInterface { return $this->hashPart($link); } - + /** + * Input: some text to obfuscate, e.g. "mailto:foo@example.com" + * + * Output: the same text but with most characters encoded as either a + * decimal or hex entity, in the hopes of foiling most address + * harvesting spam bots. E.g.: + * + * mailto:foo + * @example.co + * m + * + * Note: the additional output $tail is assigned the same value as the + * ouput, minus the number of characters specified by $head_length. + * + * Based by a filter by Matthew Wickline, posted to BBEdit-Talk. + * With some optimizations by Milian Wolff. Forced encoding of HTML + * attribute special characters by Allan Odgaard. + * + * @param string $text + * @param string &$tail + * @param integer $head_length + * @return string + */ protected function encodeEntityObfuscatedAttribute($text, &$tail = null, $head_length = 0) { - # - # Input: some text to obfuscate, e.g. "mailto:foo@example.com" - # - # Output: the same text but with most characters encoded as either a - # decimal or hex entity, in the hopes of foiling most address - # harvesting spam bots. E.g.: - # - # mailto:foo - # @example.co - # m - # - # Note: the additional output $tail is assigned the same value as the - # ouput, minus the number of characters specified by $head_length. - # - # Based by a filter by Matthew Wickline, posted to BBEdit-Talk. - # With some optimizations by Milian Wolff. Forced encoding of HTML - # attribute special characters by Allan Odgaard. - # - if ($text == "") return $tail = ""; + if ($text == "") { + return $tail = ""; + } $chars = preg_split('/(? $char) { $ord = ord($char); - # Ignore non-ascii chars. + // Ignore non-ascii chars. if ($ord < 128) { - $r = ($seed * (1 + $key)) % 100; # Pseudo-random function. - # roughly 10% raw, 45% hex, 45% dec - # '@' *must* be encoded. I insist. - # '"' and '>' have to be encoded inside the attribute - if ($r > 90 && strpos('@"&>', $char) === false) /* do nothing */; - else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';'; - else $chars[$key] = '&#'.$ord.';'; + $r = ($seed * (1 + $key)) % 100; // Pseudo-random function. + // roughly 10% raw, 45% hex, 45% dec + // '@' *must* be encoded. I insist. + // '"' and '>' have to be encoded inside the attribute + if ($r > 90 && strpos('@"&>', $char) === false) { + /* do nothing */ + } else if ($r < 45) { + $chars[$key] = '&#x'.dechex($ord).';'; + } else { + $chars[$key] = '&#'.$ord.';'; + } } } @@ -1397,14 +1716,15 @@ class Markdown implements MarkdownInterface { return $text; } - + /** + * Take the string $str and parse it into tokens, hashing embeded HTML, + * escaped characters and handling code spans. + * @param string $str + * @return string + */ protected function parseSpan($str) { - # - # Take the string $str and parse it into tokens, hashing embeded HTML, - # escaped characters and handling code spans. - # $output = ''; - + $span_re = '{ ( \\\\'.$this->escape_chars_re.' @@ -1432,1720 +1752,145 @@ class Markdown implements MarkdownInterface { }xs'; while (1) { - # - # Each loop iteration seach for either the next tag, the next - # openning code span marker, or the next escaped character. - # Each token is then passed to handleSpanToken. - # + // Each loop iteration seach for either the next tag, the next + // openning code span marker, or the next escaped character. + // Each token is then passed to handleSpanToken. $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); - - # Create token from text preceding tag. + + // Create token from text preceding tag. if ($parts[0] != "") { $output .= $parts[0]; } - - # Check if we reach the end. + + // Check if we reach the end. if (isset($parts[1])) { $output .= $this->handleSpanToken($parts[1], $parts[2]); $str = $parts[2]; - } - else { + } else { break; } } - + return $output; } - - + + /** + * Handle $token provided by parseSpan by determining its nature and + * returning the corresponding value that should replace it. + * @param string $token + * @param string &$str + * @return string + */ protected function handleSpanToken($token, &$str) { - # - # Handle $token provided by parseSpan by determining its nature and - # returning the corresponding value that should replace it. - # switch ($token{0}) { case "\\": return $this->hashPart("&#". ord($token{1}). ";"); case "`": - # Search for end marker in remaining text. - if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', + // Search for end marker in remaining text. + if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', $str, $matches)) { $str = $matches[2]; $codespan = $this->makeCodeSpan($matches[1]); return $this->hashPart($codespan); } - return $token; // return as text since no ending marker found. + return $token; // Return as text since no ending marker found. default: return $this->hashPart($token); } } - + /** + * Remove one level of line-leading tabs or spaces + * @param string $text + * @return string + */ protected function outdent($text) { - # - # Remove one level of line-leading tabs or spaces - # - return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text); + return preg_replace('/^(\t|[ ]{1,' . $this->tab_width . '})/m', '', $text); } - # String length function for detab. `_initDetab` will create a function to - # hanlde UTF-8 if the default function does not exist. + /** + * String length function for detab. `_initDetab` will create a function to + * handle UTF-8 if the default function does not exist. + * @var string + */ protected $utf8_strlen = 'mb_strlen'; - + + /** + * Replace tabs with the appropriate amount of spaces. + * + * For each line we separate the line in blocks delemited by tab characters. + * Then we reconstruct every line by adding the appropriate number of space + * between each blocks. + * + * @param string $text + * @return string + */ protected function detab($text) { - # - # Replace tabs with the appropriate amount of space. - # - # For each line we separate the line in blocks delemited by - # tab characters. Then we reconstruct every line by adding the - # appropriate number of space between each blocks. - $text = preg_replace_callback('/^.*\t.*$/m', array($this, '_detab_callback'), $text); return $text; } + + /** + * Replace tabs callback + * @param string $matches + * @return string + */ protected function _detab_callback($matches) { $line = $matches[0]; - $strlen = $this->utf8_strlen; # strlen function for UTF-8. - - # Split in blocks. + $strlen = $this->utf8_strlen; // strlen function for UTF-8. + + // Split in blocks. $blocks = explode("\t", $line); - # Add each blocks to the line. + // Add each blocks to the line. $line = $blocks[0]; - unset($blocks[0]); # Do not add first block twice. + unset($blocks[0]); // Do not add first block twice. foreach ($blocks as $block) { - # Calculate amount of space, insert spaces, insert block. - $amount = $this->tab_width - + // Calculate amount of space, insert spaces, insert block. + $amount = $this->tab_width - $strlen($line, 'UTF-8') % $this->tab_width; $line .= str_repeat(" ", $amount) . $block; } return $line; } + + /** + * Check for the availability of the function in the `utf8_strlen` property + * (initially `mb_strlen`). If the function is not available, create a + * function that will loosely count the number of UTF-8 characters with a + * regular expression. + * @return void + */ protected function _initDetab() { - # - # Check for the availability of the function in the `utf8_strlen` property - # (initially `mb_strlen`). If the function is not available, create a - # function that will loosely count the number of UTF-8 characters with a - # regular expression. - # - if (function_exists($this->utf8_strlen)) return; + + if (function_exists($this->utf8_strlen)) { + return; + } + $this->utf8_strlen = create_function('$text', 'return preg_match_all( - "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", + "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", $text, $m);'); } - + /** + * Swap back in all the tags hashed by _HashHTMLBlocks. + * @param string $text + * @return string + */ protected function unhash($text) { - # - # Swap back in all the tags hashed by _HashHTMLBlocks. - # - return preg_replace_callback('/(.)\x1A[0-9]+\1/', + return preg_replace_callback('/(.)\x1A[0-9]+\1/', array($this, '_unhash_callback'), $text); } + + /** + * Unhashing callback + * @param array $matches + * @return string + */ protected function _unhash_callback($matches) { return $this->html_hashes[$matches[0]]; } - -} - - -# -# Temporary Markdown Extra Parser Implementation Class -# -# NOTE: DON'T USE THIS CLASS -# Currently the implementation of of Extra resides here in this temporary class. -# This makes it easier to propagate the changes between the three different -# packaging styles of PHP Markdown. When this issue is resolved, this -# MarkdownExtra_TmpImpl class here will disappear and \Michelf\MarkdownExtra -# will contain the code. So please use \Michelf\MarkdownExtra and ignore this -# one. -# - -abstract class _MarkdownExtra_TmpImpl extends \Michelf\Markdown { - - ### Configuration Variables ### - - # Prefix for footnote ids. - public $fn_id_prefix = ""; - - # Optional title attribute for footnote links and backlinks. - public $fn_link_title = ""; - public $fn_backlink_title = ""; - - # Optional class attribute for footnote links and backlinks. - public $fn_link_class = "footnote-ref"; - public $fn_backlink_class = "footnote-backref"; - - # Class name for table cell alignment (%% replaced left/center/right) - # For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' - # If empty, the align attribute is used instead of a class name. - public $table_align_class_tmpl = ''; - - # Optional class prefix for fenced code block. - public $code_class_prefix = ""; - # Class attribute for code blocks goes on the `code` tag; - # setting this to true will put attributes on the `pre` tag instead. - public $code_attr_on_pre = false; - - # Predefined abbreviations. - public $predef_abbr = array(); - - - ### Parser Implementation ### - - public function __construct() { - # - # Constructor function. Initialize the parser object. - # - # Add extra escapable characters before parent constructor - # initialize the table. - $this->escape_chars .= ':|'; - - # Insert extra document, block, and span transformations. - # Parent constructor will do the sorting. - $this->document_gamut += array( - "doFencedCodeBlocks" => 5, - "stripFootnotes" => 15, - "stripAbbreviations" => 25, - "appendFootnotes" => 50, - ); - $this->block_gamut += array( - "doFencedCodeBlocks" => 5, - "doTables" => 15, - "doDefLists" => 45, - ); - $this->span_gamut += array( - "doFootnotes" => 5, - "doAbbreviations" => 70, - ); - - parent::__construct(); - } - - - # Extra variables used during extra transformations. - protected $footnotes = array(); - protected $footnotes_ordered = array(); - protected $footnotes_ref_count = array(); - protected $footnotes_numbers = array(); - protected $abbr_desciptions = array(); - protected $abbr_word_re = ''; - - # Give the current footnote number. - protected $footnote_counter = 1; - - - protected function setup() { - # - # Setting up Extra-specific variables. - # - parent::setup(); - - $this->footnotes = array(); - $this->footnotes_ordered = array(); - $this->footnotes_ref_count = array(); - $this->footnotes_numbers = array(); - $this->abbr_desciptions = array(); - $this->abbr_word_re = ''; - $this->footnote_counter = 1; - - foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { - if ($this->abbr_word_re) - $this->abbr_word_re .= '|'; - $this->abbr_word_re .= preg_quote($abbr_word); - $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); - } - } - - protected function teardown() { - # - # Clearing Extra-specific variables. - # - $this->footnotes = array(); - $this->footnotes_ordered = array(); - $this->footnotes_ref_count = array(); - $this->footnotes_numbers = array(); - $this->abbr_desciptions = array(); - $this->abbr_word_re = ''; - - parent::teardown(); - } - - - ### Extra Attribute Parser ### - - # Expression to use to catch attributes (includes the braces) - protected $id_class_attr_catch_re = '\{((?:[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}'; - # Expression to use when parsing in a context when no capture is desired - protected $id_class_attr_nocatch_re = '\{(?:[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}'; - - protected function doExtraAttributes($tag_name, $attr) { - # - # Parse attributes caught by the $this->id_class_attr_catch_re expression - # and return the HTML-formatted list of attributes. - # - # Currently supported attributes are .class and #id. - # - if (empty($attr)) return ""; - - # Split on components - preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches); - $elements = $matches[0]; - - # handle classes and ids (only first id taken into account) - $classes = array(); - $attributes = array(); - $id = false; - foreach ($elements as $element) { - if ($element{0} == '.') { - $classes[] = substr($element, 1); - } else if ($element{0} == '#') { - if ($id === false) $id = substr($element, 1); - } else if (strpos($element, '=') > 0) { - $parts = explode('=', $element, 2); - $attributes[] = $parts[0] . '="' . $parts[1] . '"'; - } - } - - # compose attributes as string - $attr_str = ""; - if (!empty($id)) { - $attr_str .= ' id="'.$id.'"'; - } - if (!empty($classes)) { - $attr_str .= ' class="'.implode(" ", $classes).'"'; - } - if (!$this->no_markup && !empty($attributes)) { - $attr_str .= ' '.implode(" ", $attributes); - } - return $attr_str; - } - - - protected function stripLinkDefinitions($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # - $less_than_tab = $this->tab_width - 1; - - # Link defs are in the form: ^[id]: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 - [ ]* - \n? # maybe *one* newline - [ ]* - (?: - <(.+?)> # url = $2 - | - (\S+?) # url = $3 - ) - [ ]* - \n? # maybe one newline - [ ]* - (?: - (?<=\s) # lookbehind for whitespace - ["(] - (.*?) # title = $4 - [")] - [ ]* - )? # title is optional - (?:[ ]* '.$this->id_class_attr_catch_re.' )? # $5 = extra id & class attr - (?:\n+|\Z) - }xm', - array($this, '_stripLinkDefinitions_callback'), - $text); - return $text; - } - protected function _stripLinkDefinitions_callback($matches) { - $link_id = strtolower($matches[1]); - $url = $matches[2] == '' ? $matches[3] : $matches[2]; - $this->urls[$link_id] = $url; - $this->titles[$link_id] =& $matches[4]; - $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]); - return ''; # String that will replace the block - } - - - ### HTML Block Parser ### - - # Tags that are always treated as block tags: - protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure'; - - # Tags treated as block tags only if the opening tag is alone on its line: - protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video'; - - # Tags where markdown="1" default to span mode: - protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; - - # Tags which must not have their contents modified, no matter where - # they appear: - protected $clean_tags_re = 'script|style|math|svg'; - - # Tags that do not need to be closed. - protected $auto_close_tags_re = 'hr|img|param|source|track'; - - - protected function hashHTMLBlocks($text) { - # - # Hashify HTML Blocks and "clean tags". - # - # We only want to do this for block-level HTML tags, such as headers, - # lists, and tables. That's because we still want to wrap

    s around - # "paragraphs" that are wrapped in non-block-level tags, such as anchors, - # phrase emphasis, and spans. The list of tags we're looking for is - # hard-coded. - # - # This works by calling _HashHTMLBlocks_InMarkdown, which then calls - # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" - # attribute is found within a tag, _HashHTMLBlocks_InHTML calls back - # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. - # These two functions are calling each other. It's recursive! - # - if ($this->no_markup) return $text; - - # - # Call the HTML-in-Markdown hasher. - # - list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); - - return $text; - } - protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0, - $enclosing_tag_re = '', $span = false) - { - # - # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. - # - # * $indent is the number of space to be ignored when checking for code - # blocks. This is important because if we don't take the indent into - # account, something like this (which looks right) won't work as expected: - # - #

    - #
    - # Hello World. <-- Is this a Markdown code block or text? - #
    <-- Is this a Markdown code block or a real tag? - #
    - # - # If you don't like this, just don't indent the tag on which - # you apply the markdown="1" attribute. - # - # * If $enclosing_tag_re is not empty, stops at the first unmatched closing - # tag with that name. Nested tags supported. - # - # * If $span is true, text inside must treated as span. So any double - # newline will be replaced by a single newline so that it does not create - # paragraphs. - # - # Returns an array of that form: ( processed text , remaining text ) - # - if ($text === '') return array('', ''); - - # Regex to check for the presense of newlines around a block tag. - $newline_before_re = '/(?:^\n?|\n\n)*$/'; - $newline_after_re = - '{ - ^ # Start of text following the tag. - (?>[ ]*)? # Optional comment. - [ ]*\n # Must be followed by newline. - }xs'; - - # Regex to match any tag. - $block_tag_re = - '{ - ( # $2: Capture whole tag. - # Tag name. - '.$this->block_tags_re.' | - '.$this->context_block_tags_re.' | - '.$this->clean_tags_re.' | - (?!\s)'.$enclosing_tag_re.' - ) - (?: - (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name. - (?> - ".*?" | # Double quotes (can contain `>`) - \'.*?\' | # Single quotes (can contain `>`) - .+? # Anything but quotes and `>`. - )*? - )? - > # End of tag. - | - # HTML Comment - | - <\?.*?\?> | <%.*?%> # Processing instruction - | - # CData Block - '. ( !$span ? ' # If not in span. - | - # Indented code block - (?: ^[ ]*\n | ^ | \n[ ]*\n ) - [ ]{'.($indent+4).'}[^\n]* \n - (?> - (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n - )* - | - # Fenced code block marker - (?<= ^ | \n ) - [ ]{0,'.($indent+3).'}(?:~{3,}|`{3,}) - [ ]* - (?: - \.?[-_:a-zA-Z0-9]+ # standalone class name - | - '.$this->id_class_attr_nocatch_re.' # extra attributes - )? - [ ]* - (?= \n ) - ' : '' ). ' # End (if not is span). - | - # Code span marker - # Note, this regex needs to go after backtick fenced - # code blocks but it should also be kept outside of the - # "if not in span" condition adding backticks to the parser - `+ - ) - }xs'; - - - $depth = 0; # Current depth inside the tag tree. - $parsed = ""; # Parsed text that will be returned. - - # - # Loop through every tag until we find the closing tag of the parent - # or loop until reaching the end of text if no parent tag specified. - # - do { - # - # Split the text using the first $tag_match pattern found. - # Text before pattern will be first in the array, text after - # pattern will be at the end, and between will be any catches made - # by the pattern. - # - $parts = preg_split($block_tag_re, $text, 2, - PREG_SPLIT_DELIM_CAPTURE); - - # If in Markdown span mode, add a empty-string span-level hash - # after each newline to prevent triggering any block element. - if ($span) { - $void = $this->hashPart("", ':'); - $newline = "$void\n"; - $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; - } - - $parsed .= $parts[0]; # Text before current tag. - - # If end of $text has been reached. Stop loop. - if (count($parts) < 3) { - $text = ""; - break; - } - - $tag = $parts[1]; # Tag to handle. - $text = $parts[2]; # Remaining text after current tag. - $tag_re = preg_quote($tag); # For use in a regular expression. - - # - # Check for: Fenced code block marker. - # Note: need to recheck the whole tag to disambiguate backtick - # fences from code spans - # - if (preg_match('{^\n?([ ]{0,'.($indent+3).'})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+|'.$this->id_class_attr_nocatch_re.')?[ ]*\n?$}', $tag, $capture)) { - # Fenced code block marker: find matching end marker. - $fence_indent = strlen($capture[1]); # use captured indent in re - $fence_re = $capture[2]; # use captured fence in re - if (preg_match('{^(?>.*\n)*?[ ]{'.($fence_indent).'}'.$fence_re.'[ ]*(?:\n|$)}', $text, - $matches)) - { - # End marker found: pass text unchanged until marker. - $parsed .= $tag . $matches[0]; - $text = substr($text, strlen($matches[0])); - } - else { - # No end marker: just skip it. - $parsed .= $tag; - } - } - # - # Check for: Indented code block. - # - else if ($tag{0} == "\n" || $tag{0} == " ") { - # Indented code block: pass it unchanged, will be handled - # later. - $parsed .= $tag; - } - # - # Check for: Code span marker - # Note: need to check this after backtick fenced code blocks - # - else if ($tag{0} == "`") { - # Find corresponding end marker. - $tag_re = preg_quote($tag); - if (preg_match('{^(?>.+?|\n(?!\n))*?(?block_tags_re.')\b}', $tag) || - ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) && - preg_match($newline_before_re, $parsed) && - preg_match($newline_after_re, $text) ) - ) - { - # Need to parse tag and following text using the HTML parser. - list($block_text, $text) = - $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); - - # Make sure it stays outside of any paragraph by adding newlines. - $parsed .= "\n\n$block_text\n\n"; - } - # - # Check for: Clean tag (like script, math) - # HTML Comments, processing instructions. - # - else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) || - $tag{1} == '!' || $tag{1} == '?') - { - # Need to parse tag and following text using the HTML parser. - # (don't check for markdown attribute) - list($block_text, $text) = - $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); - - $parsed .= $block_text; - } - # - # Check for: Tag with same name as enclosing tag. - # - else if ($enclosing_tag_re !== '' && - # Same name as enclosing tag. - preg_match('{^= 0); - - return array($parsed, $text); - } - protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { - # - # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. - # - # * Calls $hash_method to convert any blocks. - # * Stops when the first opening tag closes. - # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. - # (it is not inside clean tags) - # - # Returns an array of that form: ( processed text , remaining text ) - # - if ($text === '') return array('', ''); - - # Regex to match `markdown` attribute inside of a tag. - $markdown_attr_re = ' - { - \s* # Eat whitespace before the `markdown` attribute - markdown - \s*=\s* - (?> - (["\']) # $1: quote delimiter - (.*?) # $2: attribute value - \1 # matching delimiter - | - ([^\s>]*) # $3: unquoted attribute value - ) - () # $4: make $3 always defined (avoid warnings) - }xs'; - - # Regex to match any tag. - $tag_re = '{ - ( # $2: Capture whole tag. - - ".*?" | # Double quotes (can contain `>`) - \'.*?\' | # Single quotes (can contain `>`) - .+? # Anything but quotes and `>`. - )*? - )? - > # End of tag. - | - # HTML Comment - | - <\?.*?\?> | <%.*?%> # Processing instruction - | - # CData Block - ) - }xs'; - - $original_text = $text; # Save original text in case of faliure. - - $depth = 0; # Current depth inside the tag tree. - $block_text = ""; # Temporary text holder for current text. - $parsed = ""; # Parsed text that will be returned. - - # - # Get the name of the starting tag. - # (This pattern makes $base_tag_name_re safe without quoting.) - # - if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) - $base_tag_name_re = $matches[1]; - - # - # Loop through every tag until we find the corresponding closing tag. - # - do { - # - # Split the text using the first $tag_match pattern found. - # Text before pattern will be first in the array, text after - # pattern will be at the end, and between will be any catches made - # by the pattern. - # - $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); - - if (count($parts) < 3) { - # - # End of $text reached with unbalenced tag(s). - # In that case, we return original text unchanged and pass the - # first character as filtered to prevent an infinite loop in the - # parent function. - # - return array($original_text{0}, substr($original_text, 1)); - } - - $block_text .= $parts[0]; # Text before current tag. - $tag = $parts[1]; # Tag to handle. - $text = $parts[2]; # Remaining text after current tag. - - # - # Check for: Auto-close tag (like
    ) - # Comments and Processing Instructions. - # - if (preg_match('{^auto_close_tags_re.')\b}', $tag) || - $tag{1} == '!' || $tag{1} == '?') - { - # Just add the tag to the block as if it was text. - $block_text .= $tag; - } - else { - # - # Increase/decrease nested tag count. Only do so if - # the tag's name match base tag's. - # - if (preg_match('{^mode = $attr_m[2] . $attr_m[3]; - $span_mode = $this->mode == 'span' || $this->mode != 'block' && - preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag); - - # Calculate indent before tag. - if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { - $strlen = $this->utf8_strlen; - $indent = $strlen($matches[1], 'UTF-8'); - } else { - $indent = 0; - } - - # End preceding block with this tag. - $block_text .= $tag; - $parsed .= $this->$hash_method($block_text); - - # Get enclosing tag name for the ParseMarkdown function. - # (This pattern makes $tag_name_re safe without quoting.) - preg_match('/^<([\w:$]*)\b/', $tag, $matches); - $tag_name_re = $matches[1]; - - # Parse the content using the HTML-in-Markdown parser. - list ($block_text, $text) - = $this->_hashHTMLBlocks_inMarkdown($text, $indent, - $tag_name_re, $span_mode); - - # Outdent markdown text. - if ($indent > 0) { - $block_text = preg_replace("/^[ ]{1,$indent}/m", "", - $block_text); - } - - # Append tag content to parsed text. - if (!$span_mode) $parsed .= "\n\n$block_text\n\n"; - else $parsed .= "$block_text"; - - # Start over with a new block. - $block_text = ""; - } - else $block_text .= $tag; - } - - } while ($depth > 0); - - # - # Hash last block text that wasn't processed inside the loop. - # - $parsed .= $this->$hash_method($block_text); - - return array($parsed, $text); - } - - - protected function hashClean($text) { - # - # Called whenever a tag must be hashed when a function inserts a "clean" tag - # in $text, it passes through this function and is automaticaly escaped, - # blocking invalid nested overlap. - # - return $this->hashPart($text, 'C'); - } - - - protected function doAnchors($text) { - # - # Turn Markdown link shortcuts into XHTML tags. - # - if ($this->in_anchor) return $text; - $this->in_anchor = true; - - # - # First, handle reference-style links: [link text] [id] - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ('.$this->nested_brackets_re.') # link text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - # - # Next, inline-style links: [link text](url "optional title") - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ('.$this->nested_brackets_re.') # link text = $2 - \] - \( # literal paren - [ \n]* - (?: - <(.+?)> # href = $3 - | - ('.$this->nested_url_parenthesis_re.') # href = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # Title = $7 - \6 # matching quote - [ \n]* # ignore any spaces/tabs between closing quote and ) - )? # title is optional - \) - (?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes - ) - }xs', - array($this, '_doAnchors_inline_callback'), $text); - - # - # Last, handle reference-style shortcuts: [link text] - # These must come last in case you've also got [link text][1] - # or [link text](/foo) - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ([^\[\]]+) # link text = $2; can\'t contain [ or ] - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - $this->in_anchor = false; - return $text; - } - protected function _doAnchors_reference_callback($matches) { - $whole_match = $matches[1]; - $link_text = $matches[2]; - $link_id =& $matches[3]; - - if ($link_id == "") { - # for shortcut links like [this][] or [this]. - $link_id = $link_text; - } - - # lower-case and turn embedded newlines into spaces - $link_id = strtolower($link_id); - $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); - - if (isset($this->urls[$link_id])) { - $url = $this->urls[$link_id]; - $url = $this->encodeURLAttribute($url); - - $result = "titles[$link_id] ) ) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - if (isset($this->ref_attr[$link_id])) - $result .= $this->ref_attr[$link_id]; - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - $result = $this->hashPart($result); - } - else { - $result = $whole_match; - } - return $result; - } - protected function _doAnchors_inline_callback($matches) { - $whole_match = $matches[1]; - $link_text = $this->runSpanGamut($matches[2]); - $url = $matches[3] == '' ? $matches[4] : $matches[3]; - $title =& $matches[7]; - $attr = $this->doExtraAttributes("a", $dummy =& $matches[8]); - - // if the URL was of the form it got caught by the HTML - // tag parser and hashed. Need to reverse the process before using the URL. - $unhashed = $this->unhash($url); - if ($unhashed != $url) - $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); - - $url = $this->encodeURLAttribute($url); - - $result = "encodeAttribute($title); - $result .= " title=\"$title\""; - } - $result .= $attr; - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - - return $this->hashPart($result); - } - - - protected function doImages($text) { - # - # Turn Markdown image shortcuts into tags. - # - # - # First, handle reference-style labeled images: ![alt text][id] - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - ('.$this->nested_brackets_re.') # alt text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - - ) - }xs', - array($this, '_doImages_reference_callback'), $text); - - # - # Next, handle inline images: ![alt text](url "optional title") - # Don't forget: encode * and _ - # - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - ('.$this->nested_brackets_re.') # alt text = $2 - \] - \s? # One optional whitespace character - \( # literal paren - [ \n]* - (?: - <(\S*)> # src url = $3 - | - ('.$this->nested_url_parenthesis_re.') # src url = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # title = $7 - \6 # matching quote - [ \n]* - )? # title is optional - \) - (?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes - ) - }xs', - array($this, '_doImages_inline_callback'), $text); - - return $text; - } - protected function _doImages_reference_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $link_id = strtolower($matches[3]); - - if ($link_id == "") { - $link_id = strtolower($alt_text); # for shortcut links like ![this][]. - } - - $alt_text = $this->encodeAttribute($alt_text); - if (isset($this->urls[$link_id])) { - $url = $this->encodeURLAttribute($this->urls[$link_id]); - $result = "\"$alt_text\"";titles[$link_id])) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - if (isset($this->ref_attr[$link_id])) - $result .= $this->ref_attr[$link_id]; - $result .= $this->empty_element_suffix; - $result = $this->hashPart($result); - } - else { - # If there's no such link ID, leave intact: - $result = $whole_match; - } - - return $result; - } - protected function _doImages_inline_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $url = $matches[3] == '' ? $matches[4] : $matches[3]; - $title =& $matches[7]; - $attr = $this->doExtraAttributes("img", $dummy =& $matches[8]); - - $alt_text = $this->encodeAttribute($alt_text); - $url = $this->encodeURLAttribute($url); - $result = "\"$alt_text\"";encodeAttribute($title); - $result .= " title=\"$title\""; # $title already quoted - } - $result .= $attr; - $result .= $this->empty_element_suffix; - - return $this->hashPart($result); - } - - - protected function doHeaders($text) { - # - # Redefined to add id and class attribute support. - # - # Setext-style headers: - # Header 1 {#header1} - # ======== - # - # Header 2 {#header2 .class1 .class2} - # -------- - # - $text = preg_replace_callback( - '{ - (^.+?) # $1: Header text - (?:[ ]+ '.$this->id_class_attr_catch_re.' )? # $3 = id/class attributes - [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer - }mx', - array($this, '_doHeaders_callback_setext'), $text); - - # atx-style headers: - # # Header 1 {#header1} - # ## Header 2 {#header2} - # ## Header 2 with closing hashes ## {#header3.class1.class2} - # ... - # ###### Header 6 {.class2} - # - $text = preg_replace_callback('{ - ^(\#{1,6}) # $1 = string of #\'s - [ ]* - (.+?) # $2 = Header text - [ ]* - \#* # optional closing #\'s (not counted) - (?:[ ]+ '.$this->id_class_attr_catch_re.' )? # $3 = id/class attributes - [ ]* - \n+ - }xm', - array($this, '_doHeaders_callback_atx'), $text); - - return $text; - } - protected function _doHeaders_callback_setext($matches) { - if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) - return $matches[0]; - $level = $matches[3]{0} == '=' ? 1 : 2; - $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[2]); - $block = "".$this->runSpanGamut($matches[1]).""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - protected function _doHeaders_callback_atx($matches) { - $level = strlen($matches[1]); - $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[3]); - $block = "".$this->runSpanGamut($matches[2]).""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - - - protected function doTables($text) { - # - # Form HTML tables. - # - $less_than_tab = $this->tab_width - 1; - # - # Find tables with leading pipe. - # - # | Header 1 | Header 2 - # | -------- | -------- - # | Cell 1 | Cell 2 - # | Cell 3 | Cell 4 - # - $text = preg_replace_callback(' - { - ^ # Start of a line - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - [|] # Optional leading pipe (present) - (.+) \n # $1: Header row (at least one pipe) - - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline - - ( # $3: Cells - (?> - [ ]* # Allowed whitespace. - [|] .* \n # Row content. - )* - ) - (?=\n|\Z) # Stop at final double newline. - }xm', - array($this, '_doTable_leadingPipe_callback'), $text); - - # - # Find tables without leading pipe. - # - # Header 1 | Header 2 - # -------- | -------- - # Cell 1 | Cell 2 - # Cell 3 | Cell 4 - # - $text = preg_replace_callback(' - { - ^ # Start of a line - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - (\S.*[|].*) \n # $1: Header row (at least one pipe) - - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline - - ( # $3: Cells - (?> - .* [|] .* \n # Row content - )* - ) - (?=\n|\Z) # Stop at final double newline. - }xm', - array($this, '_DoTable_callback'), $text); - - return $text; - } - protected function _doTable_leadingPipe_callback($matches) { - $head = $matches[1]; - $underline = $matches[2]; - $content = $matches[3]; - - # Remove leading pipe for each row. - $content = preg_replace('/^ *[|]/m', '', $content); - - return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); - } - protected function _doTable_makeAlignAttr($alignname) - { - if (empty($this->table_align_class_tmpl)) - return " align=\"$alignname\""; - - $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl); - return " class=\"$classname\""; - } - protected function _doTable_callback($matches) { - $head = $matches[1]; - $underline = $matches[2]; - $content = $matches[3]; - - # Remove any tailing pipes for each line. - $head = preg_replace('/[|] *$/m', '', $head); - $underline = preg_replace('/[|] *$/m', '', $underline); - $content = preg_replace('/[|] *$/m', '', $content); - - # Reading alignement from header underline. - $separators = preg_split('/ *[|] */', $underline); - foreach ($separators as $n => $s) { - if (preg_match('/^ *-+: *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('right'); - else if (preg_match('/^ *:-+: *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('center'); - else if (preg_match('/^ *:-+ *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('left'); - else - $attr[$n] = ''; - } - - # Parsing span elements, including code spans, character escapes, - # and inline HTML tags, so that pipes inside those gets ignored. - $head = $this->parseSpan($head); - $headers = preg_split('/ *[|] */', $head); - $col_count = count($headers); - $attr = array_pad($attr, $col_count, ''); - - # Write column headers. - $text = "\n"; - $text .= "\n"; - $text .= "\n"; - foreach ($headers as $n => $header) - $text .= " ".$this->runSpanGamut(trim($header))."\n"; - $text .= "\n"; - $text .= "\n"; - - # Split content by row. - $rows = explode("\n", trim($content, "\n")); - - $text .= "\n"; - foreach ($rows as $row) { - # Parsing span elements, including code spans, character escapes, - # and inline HTML tags, so that pipes inside those gets ignored. - $row = $this->parseSpan($row); - - # Split row by cell. - $row_cells = preg_split('/ *[|] */', $row, $col_count); - $row_cells = array_pad($row_cells, $col_count, ''); - - $text .= "\n"; - foreach ($row_cells as $n => $cell) - $text .= " ".$this->runSpanGamut(trim($cell))."\n"; - $text .= "\n"; - } - $text .= "\n"; - $text .= "
    "; - - return $this->hashBlock($text) . "\n"; - } - - - protected function doDefLists($text) { - # - # Form HTML definition lists. - # - $less_than_tab = $this->tab_width - 1; - - # Re-usable pattern to match any entire dl list: - $whole_list_re = '(?> - ( # $1 = whole list - ( # $2 - [ ]{0,'.$less_than_tab.'} - ((?>.*\S.*\n)+) # $3 = defined term - \n? - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition - ) - (?s:.+?) - ( # $4 - \z - | - \n{2,} - (?=\S) - (?! # Negative lookahead for another term - [ ]{0,'.$less_than_tab.'} - (?: \S.*\n )+? # defined term - \n? - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition - ) - (?! # Negative lookahead for another definition - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition - ) - ) - ) - )'; // mx - - $text = preg_replace_callback('{ - (?>\A\n?|(?<=\n\n)) - '.$whole_list_re.' - }mx', - array($this, '_doDefLists_callback'), $text); - - return $text; - } - protected function _doDefLists_callback($matches) { - # Re-usable patterns to match list item bullets and number markers: - $list = $matches[1]; - - # Turn double returns into triple returns, so that we can make a - # paragraph for the last item in a list, if necessary: - $result = trim($this->processDefListItems($list)); - $result = "
    \n" . $result . "\n
    "; - return $this->hashBlock($result) . "\n\n"; - } - - - protected function processDefListItems($list_str) { - # - # Process the contents of a single definition list, splitting it - # into individual term and definition list items. - # - $less_than_tab = $this->tab_width - 1; - - # trim trailing blank lines: - $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); - - # Process definition terms. - $list_str = preg_replace_callback('{ - (?>\A\n?|\n\n+) # leading line - ( # definition terms = $1 - [ ]{0,'.$less_than_tab.'} # leading whitespace - (?!\:[ ]|[ ]) # negative lookahead for a definition - # mark (colon) or more whitespace. - (?> \S.* \n)+? # actual term (not whitespace). - ) - (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed - # with a definition mark. - }xm', - array($this, '_processDefListItems_callback_dt'), $list_str); - - # Process actual definitions. - $list_str = preg_replace_callback('{ - \n(\n+)? # leading line = $1 - ( # marker space = $2 - [ ]{0,'.$less_than_tab.'} # whitespace before colon - \:[ ]+ # definition mark (colon) - ) - ((?s:.+?)) # definition text = $3 - (?= \n+ # stop at next definition mark, - (?: # next term or end of text - [ ]{0,'.$less_than_tab.'} \:[ ] | -
    | \z - ) - ) - }xm', - array($this, '_processDefListItems_callback_dd'), $list_str); - - return $list_str; - } - protected function _processDefListItems_callback_dt($matches) { - $terms = explode("\n", trim($matches[1])); - $text = ''; - foreach ($terms as $term) { - $term = $this->runSpanGamut(trim($term)); - $text .= "\n
    " . $term . "
    "; - } - return $text . "\n"; - } - protected function _processDefListItems_callback_dd($matches) { - $leading_line = $matches[1]; - $marker_space = $matches[2]; - $def = $matches[3]; - - if ($leading_line || preg_match('/\n{2,}/', $def)) { - # Replace marker with the appropriate whitespace indentation - $def = str_repeat(' ', strlen($marker_space)) . $def; - $def = $this->runBlockGamut($this->outdent($def . "\n\n")); - $def = "\n". $def ."\n"; - } - else { - $def = rtrim($def); - $def = $this->runSpanGamut($this->outdent($def)); - } - - return "\n
    " . $def . "
    \n"; - } - - - protected function doFencedCodeBlocks($text) { - # - # Adding the fenced code block syntax to regular Markdown: - # - # ~~~ - # Code block - # ~~~ - # - $less_than_tab = $this->tab_width; - - $text = preg_replace_callback('{ - (?:\n|\A) - # 1: Opening marker - ( - (?:~{3,}|`{3,}) # 3 or more tildes/backticks. - ) - [ ]* - (?: - \.?([-_:a-zA-Z0-9]+) # 2: standalone class name - | - '.$this->id_class_attr_catch_re.' # 3: Extra attributes - )? - [ ]* \n # Whitespace and newline following marker. - - # 4: Content - ( - (?> - (?!\1 [ ]* \n) # Not a closing marker. - .*\n+ - )+ - ) - - # Closing marker. - \1 [ ]* (?= \n ) - }xm', - array($this, '_doFencedCodeBlocks_callback'), $text); - - return $text; - } - protected function _doFencedCodeBlocks_callback($matches) { - $classname =& $matches[2]; - $attrs =& $matches[3]; - $codeblock = $matches[4]; - $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); - $codeblock = preg_replace_callback('/^\n+/', - array($this, '_doFencedCodeBlocks_newlines'), $codeblock); - - if ($classname != "") { - if ($classname{0} == '.') - $classname = substr($classname, 1); - $attr_str = ' class="'.$this->code_class_prefix.$classname.'"'; - } else { - $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs); - } - $pre_attr_str = $this->code_attr_on_pre ? $attr_str : ''; - $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str; - $codeblock = "$codeblock
    "; - - return "\n\n".$this->hashBlock($codeblock)."\n\n"; - } - protected function _doFencedCodeBlocks_newlines($matches) { - return str_repeat("empty_element_suffix", - strlen($matches[0])); - } - - - # - # Redefining emphasis markers so that emphasis by underscore does not - # work in the middle of a word. - # - protected $em_relist = array( - '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(? tags - # - # Strip leading and trailing lines: - $text = preg_replace('/\A\n+|\n+\z/', '', $text); - - $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); - - # - # Wrap

    tags and unhashify HTML blocks - # - foreach ($grafs as $key => $value) { - $value = trim($this->runSpanGamut($value)); - - # Check if this should be enclosed in a paragraph. - # Clean tag hashes & block tag hashes are left alone. - $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); - - if ($is_p) { - $value = "

    $value

    "; - } - $grafs[$key] = $value; - } - - # Join grafs in one text, then unhash HTML tags. - $text = implode("\n\n", $grafs); - - # Finish by removing any tag hashes still present in $text. - $text = $this->unhash($text); - - return $text; - } - - - ### Footnotes - - protected function stripFootnotes($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # - $less_than_tab = $this->tab_width - 1; - - # Link defs are in the form: [^id]: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1 - [ ]* - \n? # maybe *one* newline - ( # text = $2 (no blank lines allowed) - (?: - .+ # actual text - | - \n # newlines but - (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker. - (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed - # by non-indented content - )* - ) - }xm', - array($this, '_stripFootnotes_callback'), - $text); - return $text; - } - protected function _stripFootnotes_callback($matches) { - $note_id = $this->fn_id_prefix . $matches[1]; - $this->footnotes[$note_id] = $this->outdent($matches[2]); - return ''; # String that will replace the block - } - - - protected function doFootnotes($text) { - # - # Replace footnote references in $text [^id] with a special text-token - # which will be replaced by the actual footnote marker in appendFootnotes. - # - if (!$this->in_anchor) { - $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); - } - return $text; - } - - - protected function appendFootnotes($text) { - # - # Append footnote list to text. - # - $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array($this, '_appendFootnotes_callback'), $text); - - if (!empty($this->footnotes_ordered)) { - $text .= "\n\n"; - $text .= "
    \n"; - $text .= "empty_element_suffix ."\n"; - $text .= "
      \n\n"; - - $attr = ""; - if ($this->fn_backlink_class != "") { - $class = $this->fn_backlink_class; - $class = $this->encodeAttribute($class); - $attr .= " class=\"$class\""; - } - if ($this->fn_backlink_title != "") { - $title = $this->fn_backlink_title; - $title = $this->encodeAttribute($title); - $attr .= " title=\"$title\""; - } - $num = 0; - - while (!empty($this->footnotes_ordered)) { - $footnote = reset($this->footnotes_ordered); - $note_id = key($this->footnotes_ordered); - unset($this->footnotes_ordered[$note_id]); - $ref_count = $this->footnotes_ref_count[$note_id]; - unset($this->footnotes_ref_count[$note_id]); - unset($this->footnotes[$note_id]); - - $footnote .= "\n"; # Need to append newline before parsing. - $footnote = $this->runBlockGamut("$footnote\n"); - $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array($this, '_appendFootnotes_callback'), $footnote); - - $attr = str_replace("%%", ++$num, $attr); - $note_id = $this->encodeAttribute($note_id); - - # Prepare backlink, multiple backlinks if multiple references - $backlink = ""; - for ($ref_num = 2; $ref_num <= $ref_count; ++$ref_num) { - $backlink .= " "; - } - # Add backlink to last paragraph; create new paragraph if needed. - if (preg_match('{

      $}', $footnote)) { - $footnote = substr($footnote, 0, -4) . " $backlink

      "; - } else { - $footnote .= "\n\n

      $backlink

      "; - } - - $text .= "
    1. \n"; - $text .= $footnote . "\n"; - $text .= "
    2. \n\n"; - } - - $text .= "
    \n"; - $text .= "
    "; - } - return $text; - } - protected function _appendFootnotes_callback($matches) { - $node_id = $this->fn_id_prefix . $matches[1]; - - # Create footnote marker only if it has a corresponding footnote *and* - # the footnote hasn't been used by another marker. - if (isset($this->footnotes[$node_id])) { - $num =& $this->footnotes_numbers[$node_id]; - if (!isset($num)) { - # Transfer footnote content to the ordered list and give it its - # number - $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; - $this->footnotes_ref_count[$node_id] = 1; - $num = $this->footnote_counter++; - $ref_count_mark = ''; - } else { - $ref_count_mark = $this->footnotes_ref_count[$node_id] += 1; - } - - $attr = ""; - if ($this->fn_link_class != "") { - $class = $this->fn_link_class; - $class = $this->encodeAttribute($class); - $attr .= " class=\"$class\""; - } - if ($this->fn_link_title != "") { - $title = $this->fn_link_title; - $title = $this->encodeAttribute($title); - $attr .= " title=\"$title\""; - } - - $attr = str_replace("%%", $num, $attr); - $node_id = $this->encodeAttribute($node_id); - - return - "". - "$num". - ""; - } - - return "[^".$matches[1]."]"; - } - - - ### Abbreviations ### - - protected function stripAbbreviations($text) { - # - # Strips abbreviations from text, stores titles in hash references. - # - $less_than_tab = $this->tab_width - 1; - - # Link defs are in the form: [id]*: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1 - (.*) # text = $2 (no blank lines allowed) - }xm', - array($this, '_stripAbbreviations_callback'), - $text); - return $text; - } - protected function _stripAbbreviations_callback($matches) { - $abbr_word = $matches[1]; - $abbr_desc = $matches[2]; - if ($this->abbr_word_re) - $this->abbr_word_re .= '|'; - $this->abbr_word_re .= preg_quote($abbr_word); - $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); - return ''; # String that will replace the block - } - - - protected function doAbbreviations($text) { - # - # Find defined abbreviations in text and wrap them in elements. - # - if ($this->abbr_word_re) { - // cannot use the /x modifier because abbr_word_re may - // contain significant spaces: - $text = preg_replace_callback('{'. - '(?abbr_word_re.')'. - '(?![\w\x1A])'. - '}', - array($this, '_doAbbreviations_callback'), $text); - } - return $text; - } - protected function _doAbbreviations_callback($matches) { - $abbr = $matches[0]; - if (isset($this->abbr_desciptions[$abbr])) { - $desc = $this->abbr_desciptions[$abbr]; - if (empty($desc)) { - return $this->hashPart("$abbr"); - } else { - $desc = $this->encodeAttribute($desc); - return $this->hashPart("$abbr"); - } - } else { - return $matches[0]; - } - } - } diff --git a/library/php-markdown/Michelf/MarkdownExtra.inc.php b/library/php-markdown/Michelf/MarkdownExtra.inc.php index e11b1ef971..d09bd7a480 100644 --- a/library/php-markdown/Michelf/MarkdownExtra.inc.php +++ b/library/php-markdown/Michelf/MarkdownExtra.inc.php @@ -1,10 +1,10 @@ -# -# Original Markdown -# Copyright (c) 2004-2006 John Gruber -# -# +/** + * Markdown Extra - A text-to-HTML conversion tool for web writers + * + * @package php-markdown + * @author Michel Fortin + * @copyright 2004-2016 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + namespace Michelf; +/** + * Markdown Extra Parser Class + */ +class MarkdownExtra extends \Michelf\Markdown { + /** + * Configuration variables + */ -# Just force Michelf/Markdown.php to load. This is needed to load -# the temporary implementation class. See below for details. -\Michelf\Markdown::MARKDOWNLIB_VERSION; + /** + * Prefix for footnote ids. + * @var string + */ + public $fn_id_prefix = ""; + + /** + * Optional title attribute for footnote links and backlinks. + * @var string + */ + public $fn_link_title = ""; + public $fn_backlink_title = ""; + + /** + * Optional class attribute for footnote links and backlinks. + * @var string + */ + public $fn_link_class = "footnote-ref"; + public $fn_backlink_class = "footnote-backref"; -# -# Markdown Extra Parser Class -# -# Note: Currently the implementation resides in the temporary class -# \Michelf\MarkdownExtra_TmpImpl (in the same file as \Michelf\Markdown). -# This makes it easier to propagate the changes between the three different -# packaging styles of PHP Markdown. Once this issue is resolved, the -# _MarkdownExtra_TmpImpl will disappear and this one will contain the code. -# + /** + * Content to be displayed within footnote backlinks. The default is '↩'; + * the U+FE0E on the end is a Unicode variant selector used to prevent iOS + * from displaying the arrow character as an emoji. + * @var string + */ + public $fn_backlink_html = '↩︎'; -class MarkdownExtra extends \Michelf\_MarkdownExtra_TmpImpl { + /** + * Class name for table cell alignment (%% replaced left/center/right) + * For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' + * If empty, the align attribute is used instead of a class name. + * @var string + */ + public $table_align_class_tmpl = ''; - ### Parser Implementation ### + /** + * Optional class prefix for fenced code block. + * @var string + */ + public $code_class_prefix = ""; - # Temporarily, the implemenation is in the _MarkdownExtra_TmpImpl class. - # See note above. + /** + * Class attribute for code blocks goes on the `code` tag; + * setting this to true will put attributes on the `pre` tag instead. + * @var boolean + */ + public $code_attr_on_pre = false; + /** + * Predefined abbreviations. + * @var array + */ + public $predef_abbr = array(); + + /** + * Parser implementation + */ + + /** + * Constructor function. Initialize the parser object. + * @return void + */ + public function __construct() { + // Add extra escapable characters before parent constructor + // initialize the table. + $this->escape_chars .= ':|'; + + // Insert extra document, block, and span transformations. + // Parent constructor will do the sorting. + $this->document_gamut += array( + "doFencedCodeBlocks" => 5, + "stripFootnotes" => 15, + "stripAbbreviations" => 25, + "appendFootnotes" => 50, + ); + $this->block_gamut += array( + "doFencedCodeBlocks" => 5, + "doTables" => 15, + "doDefLists" => 45, + ); + $this->span_gamut += array( + "doFootnotes" => 5, + "doAbbreviations" => 70, + ); + + $this->enhanced_ordered_list = true; + parent::__construct(); + } + + + /** + * Extra variables used during extra transformations. + * @var array + */ + protected $footnotes = array(); + protected $footnotes_ordered = array(); + protected $footnotes_ref_count = array(); + protected $footnotes_numbers = array(); + protected $abbr_desciptions = array(); + /** @var string */ + protected $abbr_word_re = ''; + + /** + * Give the current footnote number. + * @var integer + */ + protected $footnote_counter = 1; + + /** + * Setting up Extra-specific variables. + */ + protected function setup() { + parent::setup(); + + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->footnotes_ref_count = array(); + $this->footnotes_numbers = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + $this->footnote_counter = 1; + + foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { + if ($this->abbr_word_re) + $this->abbr_word_re .= '|'; + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + } + } + + /** + * Clearing Extra-specific variables. + */ + protected function teardown() { + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->footnotes_ref_count = array(); + $this->footnotes_numbers = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + + parent::teardown(); + } + + + /** + * Extra attribute parser + */ + + /** + * Expression to use to catch attributes (includes the braces) + * @var string + */ + protected $id_class_attr_catch_re = '\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}'; + + /** + * Expression to use when parsing in a context when no capture is desired + * @var string + */ + protected $id_class_attr_nocatch_re = '\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}'; + + /** + * Parse attributes caught by the $this->id_class_attr_catch_re expression + * and return the HTML-formatted list of attributes. + * + * Currently supported attributes are .class and #id. + * + * In addition, this method also supports supplying a default Id value, + * which will be used to populate the id attribute in case it was not + * overridden. + * @param string $tag_name + * @param string $attr + * @param mixed $defaultIdValue + * @param array $classes + * @return string + */ + protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) { + if (empty($attr) && !$defaultIdValue && empty($classes)) return ""; + + // Split on components + preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches); + $elements = $matches[0]; + + // Handle classes and IDs (only first ID taken into account) + $attributes = array(); + $id = false; + foreach ($elements as $element) { + if ($element{0} == '.') { + $classes[] = substr($element, 1); + } else if ($element{0} == '#') { + if ($id === false) $id = substr($element, 1); + } else if (strpos($element, '=') > 0) { + $parts = explode('=', $element, 2); + $attributes[] = $parts[0] . '="' . $parts[1] . '"'; + } + } + + if (!$id) $id = $defaultIdValue; + + // Compose attributes as string + $attr_str = ""; + if (!empty($id)) { + $attr_str .= ' id="'.$this->encodeAttribute($id) .'"'; + } + if (!empty($classes)) { + $attr_str .= ' class="'. implode(" ", $classes) . '"'; + } + if (!$this->no_markup && !empty($attributes)) { + $attr_str .= ' '.implode(" ", $attributes); + } + return $attr_str; + } + + /** + * Strips link definitions from text, stores the URLs and titles in + * hash references. + * @param string $text + * @return string + */ + protected function stripLinkDefinitions($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: ^[id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 + [ ]* + \n? # maybe *one* newline + [ ]* + (?: + <(.+?)> # url = $2 + | + (\S+?) # url = $3 + ) + [ ]* + \n? # maybe one newline + [ ]* + (?: + (?<=\s) # lookbehind for whitespace + ["(] + (.*?) # title = $4 + [")] + [ ]* + )? # title is optional + (?:[ ]* '.$this->id_class_attr_catch_re.' )? # $5 = extra id & class attr + (?:\n+|\Z) + }xm', + array($this, '_stripLinkDefinitions_callback'), + $text); + return $text; + } + + /** + * Strip link definition callback + * @param array $matches + * @return string + */ + protected function _stripLinkDefinitions_callback($matches) { + $link_id = strtolower($matches[1]); + $url = $matches[2] == '' ? $matches[3] : $matches[2]; + $this->urls[$link_id] = $url; + $this->titles[$link_id] =& $matches[4]; + $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]); + return ''; // String that will replace the block + } + + + /** + * HTML block parser + */ + + /** + * Tags that are always treated as block tags + * @var string + */ + protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure'; + + /** + * Tags treated as block tags only if the opening tag is alone on its line + * @var string + */ + protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video'; + + /** + * Tags where markdown="1" default to span mode: + * @var string + */ + protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; + + /** + * Tags which must not have their contents modified, no matter where + * they appear + * @var string + */ + protected $clean_tags_re = 'script|style|math|svg'; + + /** + * Tags that do not need to be closed. + * @var string + */ + protected $auto_close_tags_re = 'hr|img|param|source|track'; + + /** + * Hashify HTML Blocks and "clean tags". + * + * We only want to do this for block-level HTML tags, such as headers, + * lists, and tables. That's because we still want to wrap

    s around + * "paragraphs" that are wrapped in non-block-level tags, such as anchors, + * phrase emphasis, and spans. The list of tags we're looking for is + * hard-coded. + * + * This works by calling _HashHTMLBlocks_InMarkdown, which then calls + * _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" + * attribute is found within a tag, _HashHTMLBlocks_InHTML calls back + * _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. + * These two functions are calling each other. It's recursive! + * @param string $text + * @return string + */ + protected function hashHTMLBlocks($text) { + if ($this->no_markup) { + return $text; + } + + // Call the HTML-in-Markdown hasher. + list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); + + return $text; + } + + /** + * Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. + * + * * $indent is the number of space to be ignored when checking for code + * blocks. This is important because if we don't take the indent into + * account, something like this (which looks right) won't work as expected: + * + *

    + *
    + * Hello World. <-- Is this a Markdown code block or text? + *
    <-- Is this a Markdown code block or a real tag? + *
    + * + * If you don't like this, just don't indent the tag on which + * you apply the markdown="1" attribute. + * + * * If $enclosing_tag_re is not empty, stops at the first unmatched closing + * tag with that name. Nested tags supported. + * + * * If $span is true, text inside must treated as span. So any double + * newline will be replaced by a single newline so that it does not create + * paragraphs. + * + * Returns an array of that form: ( processed text , remaining text ) + * + * @param string $text + * @param integer $indent + * @param string $enclosing_tag_re + * @param boolean $span + * @return array + */ + protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0, + $enclosing_tag_re = '', $span = false) + { + + if ($text === '') return array('', ''); + + // Regex to check for the presense of newlines around a block tag. + $newline_before_re = '/(?:^\n?|\n\n)*$/'; + $newline_after_re = + '{ + ^ # Start of text following the tag. + (?>[ ]*)? # Optional comment. + [ ]*\n # Must be followed by newline. + }xs'; + + // Regex to match any tag. + $block_tag_re = + '{ + ( # $2: Capture whole tag. + # Tag name. + ' . $this->block_tags_re . ' | + ' . $this->context_block_tags_re . ' | + ' . $this->clean_tags_re . ' | + (?!\s)'.$enclosing_tag_re . ' + ) + (?: + (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name. + (?> + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + ' . ( !$span ? ' # If not in span. + | + # Indented code block + (?: ^[ ]*\n | ^ | \n[ ]*\n ) + [ ]{' . ($indent + 4) . '}[^\n]* \n + (?> + (?: [ ]{' . ($indent + 4) . '}[^\n]* | [ ]* ) \n + )* + | + # Fenced code block marker + (?<= ^ | \n ) + [ ]{0,' . ($indent + 3) . '}(?:~{3,}|`{3,}) + [ ]* + (?: \.?[-_:a-zA-Z0-9]+ )? # standalone class name + [ ]* + (?: ' . $this->id_class_attr_nocatch_re . ' )? # extra attributes + [ ]* + (?= \n ) + ' : '' ) . ' # End (if not is span). + | + # Code span marker + # Note, this regex needs to go after backtick fenced + # code blocks but it should also be kept outside of the + # "if not in span" condition adding backticks to the parser + `+ + ) + }xs'; + + + $depth = 0; // Current depth inside the tag tree. + $parsed = ""; // Parsed text that will be returned. + + // Loop through every tag until we find the closing tag of the parent + // or loop until reaching the end of text if no parent tag specified. + do { + // Split the text using the first $tag_match pattern found. + // Text before pattern will be first in the array, text after + // pattern will be at the end, and between will be any catches made + // by the pattern. + $parts = preg_split($block_tag_re, $text, 2, + PREG_SPLIT_DELIM_CAPTURE); + + // If in Markdown span mode, add a empty-string span-level hash + // after each newline to prevent triggering any block element. + if ($span) { + $void = $this->hashPart("", ':'); + $newline = "\n$void"; + $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; + } + + $parsed .= $parts[0]; // Text before current tag. + + // If end of $text has been reached. Stop loop. + if (count($parts) < 3) { + $text = ""; + break; + } + + $tag = $parts[1]; // Tag to handle. + $text = $parts[2]; // Remaining text after current tag. + $tag_re = preg_quote($tag); // For use in a regular expression. + + // Check for: Fenced code block marker. + // Note: need to recheck the whole tag to disambiguate backtick + // fences from code spans + if (preg_match('{^\n?([ ]{0,' . ($indent + 3) . '})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+)?[ ]*(?:' . $this->id_class_attr_nocatch_re . ')?[ ]*\n?$}', $tag, $capture)) { + // Fenced code block marker: find matching end marker. + $fence_indent = strlen($capture[1]); // use captured indent in re + $fence_re = $capture[2]; // use captured fence in re + if (preg_match('{^(?>.*\n)*?[ ]{' . ($fence_indent) . '}' . $fence_re . '[ ]*(?:\n|$)}', $text, + $matches)) + { + // End marker found: pass text unchanged until marker. + $parsed .= $tag . $matches[0]; + $text = substr($text, strlen($matches[0])); + } + else { + // No end marker: just skip it. + $parsed .= $tag; + } + } + // Check for: Indented code block. + else if ($tag{0} == "\n" || $tag{0} == " ") { + // Indented code block: pass it unchanged, will be handled + // later. + $parsed .= $tag; + } + // Check for: Code span marker + // Note: need to check this after backtick fenced code blocks + else if ($tag{0} == "`") { + // Find corresponding end marker. + $tag_re = preg_quote($tag); + if (preg_match('{^(?>.+?|\n(?!\n))*?(?block_tags_re . ')\b}', $tag) || + ( preg_match('{^<(?:' . $this->context_block_tags_re . ')\b}', $tag) && + preg_match($newline_before_re, $parsed) && + preg_match($newline_after_re, $text) ) + ) + { + // Need to parse tag and following text using the HTML parser. + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); + + // Make sure it stays outside of any paragraph by adding newlines. + $parsed .= "\n\n$block_text\n\n"; + } + // Check for: Clean tag (like script, math) + // HTML Comments, processing instructions. + else if (preg_match('{^<(?:' . $this->clean_tags_re . ')\b}', $tag) || + $tag{1} == '!' || $tag{1} == '?') + { + // Need to parse tag and following text using the HTML parser. + // (don't check for markdown attribute) + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); + + $parsed .= $block_text; + } + // Check for: Tag with same name as enclosing tag. + else if ($enclosing_tag_re !== '' && + // Same name as enclosing tag. + preg_match('{^= 0); + + return array($parsed, $text); + } + + /** + * Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. + * + * * Calls $hash_method to convert any blocks. + * * Stops when the first opening tag closes. + * * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. + * (it is not inside clean tags) + * + * Returns an array of that form: ( processed text , remaining text ) + * @param string $text + * @param string $hash_method + * @param string $md_attr + * @return array + */ + protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { + if ($text === '') return array('', ''); + + // Regex to match `markdown` attribute inside of a tag. + $markdown_attr_re = ' + { + \s* # Eat whitespace before the `markdown` attribute + markdown + \s*=\s* + (?> + (["\']) # $1: quote delimiter + (.*?) # $2: attribute value + \1 # matching delimiter + | + ([^\s>]*) # $3: unquoted attribute value + ) + () # $4: make $3 always defined (avoid warnings) + }xs'; + + // Regex to match any tag. + $tag_re = '{ + ( # $2: Capture whole tag. + + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + ) + }xs'; + + $original_text = $text; // Save original text in case of faliure. + + $depth = 0; // Current depth inside the tag tree. + $block_text = ""; // Temporary text holder for current text. + $parsed = ""; // Parsed text that will be returned. + + // Get the name of the starting tag. + // (This pattern makes $base_tag_name_re safe without quoting.) + if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) + $base_tag_name_re = $matches[1]; + + // Loop through every tag until we find the corresponding closing tag. + do { + // Split the text using the first $tag_match pattern found. + // Text before pattern will be first in the array, text after + // pattern will be at the end, and between will be any catches made + // by the pattern. + $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + + if (count($parts) < 3) { + // End of $text reached with unbalenced tag(s). + // In that case, we return original text unchanged and pass the + // first character as filtered to prevent an infinite loop in the + // parent function. + return array($original_text{0}, substr($original_text, 1)); + } + + $block_text .= $parts[0]; // Text before current tag. + $tag = $parts[1]; // Tag to handle. + $text = $parts[2]; // Remaining text after current tag. + + // Check for: Auto-close tag (like
    ) + // Comments and Processing Instructions. + if (preg_match('{^auto_close_tags_re . ')\b}', $tag) || + $tag{1} == '!' || $tag{1} == '?') + { + // Just add the tag to the block as if it was text. + $block_text .= $tag; + } + else { + // Increase/decrease nested tag count. Only do so if + // the tag's name match base tag's. + if (preg_match('{^mode = $attr_m[2] . $attr_m[3]; + $span_mode = $this->mode == 'span' || $this->mode != 'block' && + preg_match('{^<(?:' . $this->contain_span_tags_re . ')\b}', $tag); + + // Calculate indent before tag. + if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { + $strlen = $this->utf8_strlen; + $indent = $strlen($matches[1], 'UTF-8'); + } else { + $indent = 0; + } + + // End preceding block with this tag. + $block_text .= $tag; + $parsed .= $this->$hash_method($block_text); + + // Get enclosing tag name for the ParseMarkdown function. + // (This pattern makes $tag_name_re safe without quoting.) + preg_match('/^<([\w:$]*)\b/', $tag, $matches); + $tag_name_re = $matches[1]; + + // Parse the content using the HTML-in-Markdown parser. + list ($block_text, $text) + = $this->_hashHTMLBlocks_inMarkdown($text, $indent, + $tag_name_re, $span_mode); + + // Outdent markdown text. + if ($indent > 0) { + $block_text = preg_replace("/^[ ]{1,$indent}/m", "", + $block_text); + } + + // Append tag content to parsed text. + if (!$span_mode) $parsed .= "\n\n$block_text\n\n"; + else $parsed .= "$block_text"; + + // Start over with a new block. + $block_text = ""; + } + else $block_text .= $tag; + } + + } while ($depth > 0); + + // Hash last block text that wasn't processed inside the loop. + $parsed .= $this->$hash_method($block_text); + + return array($parsed, $text); + } + + /** + * Called whenever a tag must be hashed when a function inserts a "clean" tag + * in $text, it passes through this function and is automaticaly escaped, + * blocking invalid nested overlap. + * @param string $text + * @return string + */ + protected function hashClean($text) { + return $this->hashPart($text, 'C'); + } + + /** + * Turn Markdown link shortcuts into XHTML tags. + * @param string $text + * @return string + */ + protected function doAnchors($text) { + if ($this->in_anchor) { + return $text; + } + $this->in_anchor = true; + + // First, handle reference-style links: [link text] [id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + (' . $this->nested_brackets_re . ') # link text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + // Next, inline-style links: [link text](url "optional title") + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + (' . $this->nested_brackets_re . ') # link text = $2 + \] + \( # literal paren + [ \n]* + (?: + <(.+?)> # href = $3 + | + (' . $this->nested_url_parenthesis_re . ') # href = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # Title = $7 + \6 # matching quote + [ \n]* # ignore any spaces/tabs between closing quote and ) + )? # title is optional + \) + (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes + ) + }xs', + array($this, '_doAnchors_inline_callback'), $text); + + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link text][1] + // or [link text](/foo) + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ([^\[\]]+) # link text = $2; can\'t contain [ or ] + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + $this->in_anchor = false; + return $text; + } + + /** + * Callback for reference anchors + * @param array $matches + * @return string + */ + protected function _doAnchors_reference_callback($matches) { + $whole_match = $matches[1]; + $link_text = $matches[2]; + $link_id =& $matches[3]; + + if ($link_id == "") { + // for shortcut links like [this][] or [this]. + $link_id = $link_text; + } + + // lower-case and turn embedded newlines into spaces + $link_id = strtolower($link_id); + $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); + + if (isset($this->urls[$link_id])) { + $url = $this->urls[$link_id]; + $url = $this->encodeURLAttribute($url); + + $result = "titles[$link_id] ) ) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + if (isset($this->ref_attr[$link_id])) + $result .= $this->ref_attr[$link_id]; + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + $result = $this->hashPart($result); + } + else { + $result = $whole_match; + } + return $result; + } + + /** + * Callback for inline anchors + * @param array $matches + * @return string + */ + protected function _doAnchors_inline_callback($matches) { + $whole_match = $matches[1]; + $link_text = $this->runSpanGamut($matches[2]); + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + $attr = $this->doExtraAttributes("a", $dummy =& $matches[8]); + + // if the URL was of the form it got caught by the HTML + // tag parser and hashed. Need to reverse the process before using the URL. + $unhashed = $this->unhash($url); + if ($unhashed != $url) + $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); + + $url = $this->encodeURLAttribute($url); + + $result = "encodeAttribute($title); + $result .= " title=\"$title\""; + } + $result .= $attr; + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + + return $this->hashPart($result); + } + + /** + * Turn Markdown image shortcuts into tags. + * @param string $text + * @return string + */ + protected function doImages($text) { + // First, handle reference-style labeled images: ![alt text][id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + (' . $this->nested_brackets_re . ') # alt text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + + ) + }xs', + array($this, '_doImages_reference_callback'), $text); + + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + (' . $this->nested_brackets_re . ') # alt text = $2 + \] + \s? # One optional whitespace character + \( # literal paren + [ \n]* + (?: + <(\S*)> # src url = $3 + | + (' . $this->nested_url_parenthesis_re . ') # src url = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # title = $7 + \6 # matching quote + [ \n]* + )? # title is optional + \) + (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes + ) + }xs', + array($this, '_doImages_inline_callback'), $text); + + return $text; + } + + /** + * Callback for referenced images + * @param array $matches + * @return string + */ + protected function _doImages_reference_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $link_id = strtolower($matches[3]); + + if ($link_id == "") { + $link_id = strtolower($alt_text); // for shortcut links like ![this][]. + } + + $alt_text = $this->encodeAttribute($alt_text); + if (isset($this->urls[$link_id])) { + $url = $this->encodeURLAttribute($this->urls[$link_id]); + $result = "\"$alt_text\"";titles[$link_id])) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + if (isset($this->ref_attr[$link_id])) + $result .= $this->ref_attr[$link_id]; + $result .= $this->empty_element_suffix; + $result = $this->hashPart($result); + } + else { + // If there's no such link ID, leave intact: + $result = $whole_match; + } + + return $result; + } + + /** + * Callback for inline images + * @param array $matches + * @return string + */ + protected function _doImages_inline_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + $attr = $this->doExtraAttributes("img", $dummy =& $matches[8]); + + $alt_text = $this->encodeAttribute($alt_text); + $url = $this->encodeURLAttribute($url); + $result = "\"$alt_text\"";encodeAttribute($title); + $result .= " title=\"$title\""; // $title already quoted + } + $result .= $attr; + $result .= $this->empty_element_suffix; + + return $this->hashPart($result); + } + + /** + * Process markdown headers. Redefined to add ID and class attribute support. + * @param string $text + * @return string + */ + protected function doHeaders($text) { + // Setext-style headers: + // Header 1 {#header1} + // ======== + // + // Header 2 {#header2 .class1 .class2} + // -------- + // + $text = preg_replace_callback( + '{ + (^.+?) # $1: Header text + (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes + [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer + }mx', + array($this, '_doHeaders_callback_setext'), $text); + + // atx-style headers: + // # Header 1 {#header1} + // ## Header 2 {#header2} + // ## Header 2 with closing hashes ## {#header3.class1.class2} + // ... + // ###### Header 6 {.class2} + // + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]* + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes + [ ]* + \n+ + }xm', + array($this, '_doHeaders_callback_atx'), $text); + + return $text; + } + + /** + * Callback for setext headers + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_setext($matches) { + if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) { + return $matches[0]; + } + + $level = $matches[3]{0} == '=' ? 1 : 2; + + $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[1]) : null; + + $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[2], $defaultId); + $block = "" . $this->runSpanGamut($matches[1]) . ""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * Callback for atx headers + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_atx($matches) { + $level = strlen($matches[1]); + + $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[2]) : null; + $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[3], $defaultId); + $block = "" . $this->runSpanGamut($matches[2]) . ""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * Form HTML tables. + * @param string $text + * @return string + */ + protected function doTables($text) { + $less_than_tab = $this->tab_width - 1; + // Find tables with leading pipe. + // + // | Header 1 | Header 2 + // | -------- | -------- + // | Cell 1 | Cell 2 + // | Cell 3 | Cell 4 + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + [|] # Optional leading pipe (present) + (.+) \n # $1: Header row (at least one pipe) + + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + [ ]* # Allowed whitespace. + [|] .* \n # Row content. + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array($this, '_doTable_leadingPipe_callback'), $text); + + // Find tables without leading pipe. + // + // Header 1 | Header 2 + // -------- | -------- + // Cell 1 | Cell 2 + // Cell 3 | Cell 4 + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + (\S.*[|].*) \n # $1: Header row (at least one pipe) + + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + .* [|] .* \n # Row content + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array($this, '_DoTable_callback'), $text); + + return $text; + } + + /** + * Callback for removing the leading pipe for each row + * @param array $matches + * @return string + */ + protected function _doTable_leadingPipe_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + $content = preg_replace('/^ *[|]/m', '', $content); + + return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); + } + + /** + * Make the align attribute in a table + * @param string $alignname + * @return string + */ + protected function _doTable_makeAlignAttr($alignname) + { + if (empty($this->table_align_class_tmpl)) { + return " align=\"$alignname\""; + } + + $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl); + return " class=\"$classname\""; + } + + /** + * Calback for processing tables + * @param array $matches + * @return string + */ + protected function _doTable_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + // Remove any tailing pipes for each line. + $head = preg_replace('/[|] *$/m', '', $head); + $underline = preg_replace('/[|] *$/m', '', $underline); + $content = preg_replace('/[|] *$/m', '', $content); + + // Reading alignement from header underline. + $separators = preg_split('/ *[|] */', $underline); + foreach ($separators as $n => $s) { + if (preg_match('/^ *-+: *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('right'); + else if (preg_match('/^ *:-+: *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('center'); + else if (preg_match('/^ *:-+ *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('left'); + else + $attr[$n] = ''; + } + + // Parsing span elements, including code spans, character escapes, + // and inline HTML tags, so that pipes inside those gets ignored. + $head = $this->parseSpan($head); + $headers = preg_split('/ *[|] */', $head); + $col_count = count($headers); + $attr = array_pad($attr, $col_count, ''); + + // Write column headers. + $text = "\n"; + $text .= "\n"; + $text .= "\n"; + foreach ($headers as $n => $header) + $text .= " " . $this->runSpanGamut(trim($header)) . "\n"; + $text .= "\n"; + $text .= "\n"; + + // Split content by row. + $rows = explode("\n", trim($content, "\n")); + + $text .= "\n"; + foreach ($rows as $row) { + // Parsing span elements, including code spans, character escapes, + // and inline HTML tags, so that pipes inside those gets ignored. + $row = $this->parseSpan($row); + + // Split row by cell. + $row_cells = preg_split('/ *[|] */', $row, $col_count); + $row_cells = array_pad($row_cells, $col_count, ''); + + $text .= "\n"; + foreach ($row_cells as $n => $cell) + $text .= " " . $this->runSpanGamut(trim($cell)) . "\n"; + $text .= "\n"; + } + $text .= "\n"; + $text .= "
    "; + + return $this->hashBlock($text) . "\n"; + } + + /** + * Form HTML definition lists. + * @param string $text + * @return string + */ + protected function doDefLists($text) { + $less_than_tab = $this->tab_width - 1; + + // Re-usable pattern to match any entire dl list: + $whole_list_re = '(?> + ( # $1 = whole list + ( # $2 + [ ]{0,' . $less_than_tab . '} + ((?>.*\S.*\n)+) # $3 = defined term + \n? + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + (?s:.+?) + ( # $4 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another term + [ ]{0,' . $less_than_tab . '} + (?: \S.*\n )+? # defined term + \n? + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + (?! # Negative lookahead for another definition + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + ) + ) + )'; // mx + + $text = preg_replace_callback('{ + (?>\A\n?|(?<=\n\n)) + ' . $whole_list_re . ' + }mx', + array($this, '_doDefLists_callback'), $text); + + return $text; + } + + /** + * Callback for processing definition lists + * @param array $matches + * @return string + */ + protected function _doDefLists_callback($matches) { + // Re-usable patterns to match list item bullets and number markers: + $list = $matches[1]; + + // Turn double returns into triple returns, so that we can make a + // paragraph for the last item in a list, if necessary: + $result = trim($this->processDefListItems($list)); + $result = "
    \n" . $result . "\n
    "; + return $this->hashBlock($result) . "\n\n"; + } + + /** + * Process the contents of a single definition list, splitting it + * into individual term and definition list items. + * @param string $list_str + * @return string + */ + protected function processDefListItems($list_str) { + + $less_than_tab = $this->tab_width - 1; + + // Trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + // Process definition terms. + $list_str = preg_replace_callback('{ + (?>\A\n?|\n\n+) # leading line + ( # definition terms = $1 + [ ]{0,' . $less_than_tab . '} # leading whitespace + (?!\:[ ]|[ ]) # negative lookahead for a definition + # mark (colon) or more whitespace. + (?> \S.* \n)+? # actual term (not whitespace). + ) + (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed + # with a definition mark. + }xm', + array($this, '_processDefListItems_callback_dt'), $list_str); + + // Process actual definitions. + $list_str = preg_replace_callback('{ + \n(\n+)? # leading line = $1 + ( # marker space = $2 + [ ]{0,' . $less_than_tab . '} # whitespace before colon + \:[ ]+ # definition mark (colon) + ) + ((?s:.+?)) # definition text = $3 + (?= \n+ # stop at next definition mark, + (?: # next term or end of text + [ ]{0,' . $less_than_tab . '} \:[ ] | +
    | \z + ) + ) + }xm', + array($this, '_processDefListItems_callback_dd'), $list_str); + + return $list_str; + } + + /** + * Callback for
    elements in definition lists + * @param array $matches + * @return string + */ + protected function _processDefListItems_callback_dt($matches) { + $terms = explode("\n", trim($matches[1])); + $text = ''; + foreach ($terms as $term) { + $term = $this->runSpanGamut(trim($term)); + $text .= "\n
    " . $term . "
    "; + } + return $text . "\n"; + } + + /** + * Callback for
    elements in definition lists + * @param array $matches + * @return string + */ + protected function _processDefListItems_callback_dd($matches) { + $leading_line = $matches[1]; + $marker_space = $matches[2]; + $def = $matches[3]; + + if ($leading_line || preg_match('/\n{2,}/', $def)) { + // Replace marker with the appropriate whitespace indentation + $def = str_repeat(' ', strlen($marker_space)) . $def; + $def = $this->runBlockGamut($this->outdent($def . "\n\n")); + $def = "\n". $def ."\n"; + } + else { + $def = rtrim($def); + $def = $this->runSpanGamut($this->outdent($def)); + } + + return "\n
    " . $def . "
    \n"; + } + + /** + * Adding the fenced code block syntax to regular Markdown: + * + * ~~~ + * Code block + * ~~~ + * + * @param string $text + * @return string + */ + protected function doFencedCodeBlocks($text) { + + $less_than_tab = $this->tab_width; + + $text = preg_replace_callback('{ + (?:\n|\A) + # 1: Opening marker + ( + (?:~{3,}|`{3,}) # 3 or more tildes/backticks. + ) + [ ]* + (?: + \.?([-_:a-zA-Z0-9]+) # 2: standalone class name + )? + [ ]* + (?: + ' . $this->id_class_attr_catch_re . ' # 3: Extra attributes + )? + [ ]* \n # Whitespace and newline following marker. + + # 4: Content + ( + (?> + (?!\1 [ ]* \n) # Not a closing marker. + .*\n+ + )+ + ) + + # Closing marker. + \1 [ ]* (?= \n ) + }xm', + array($this, '_doFencedCodeBlocks_callback'), $text); + + return $text; + } + + /** + * Callback to process fenced code blocks + * @param array $matches + * @return string + */ + protected function _doFencedCodeBlocks_callback($matches) { + $classname =& $matches[2]; + $attrs =& $matches[3]; + $codeblock = $matches[4]; + + if ($this->code_block_content_func) { + $codeblock = call_user_func($this->code_block_content_func, $codeblock, $classname); + } else { + $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); + } + + $codeblock = preg_replace_callback('/^\n+/', + array($this, '_doFencedCodeBlocks_newlines'), $codeblock); + + $classes = array(); + if ($classname != "") { + if ($classname{0} == '.') + $classname = substr($classname, 1); + $classes[] = $this->code_class_prefix . $classname; + } + $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes); + $pre_attr_str = $this->code_attr_on_pre ? $attr_str : ''; + $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str; + $codeblock = "$codeblock
    "; + + return "\n\n".$this->hashBlock($codeblock)."\n\n"; + } + + /** + * Replace new lines in fenced code blocks + * @param array $matches + * @return string + */ + protected function _doFencedCodeBlocks_newlines($matches) { + return str_repeat("empty_element_suffix", + strlen($matches[0])); + } + + /** + * Redefining emphasis markers so that emphasis by underscore does not + * work in the middle of a word. + * @var array + */ + protected $em_relist = array( + '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(? tags + * @return string HTML output + */ + protected function formParagraphs($text, $wrap_in_p = true) { + // Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + // Wrap

    tags and unhashify HTML blocks + foreach ($grafs as $key => $value) { + $value = trim($this->runSpanGamut($value)); + + // Check if this should be enclosed in a paragraph. + // Clean tag hashes & block tag hashes are left alone. + $is_p = $wrap_in_p && !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); + + if ($is_p) { + $value = "

    $value

    "; + } + $grafs[$key] = $value; + } + + // Join grafs in one text, then unhash HTML tags. + $text = implode("\n\n", $grafs); + + // Finish by removing any tag hashes still present in $text. + $text = $this->unhash($text); + + return $text; + } + + + /** + * Footnotes - Strips link definitions from text, stores the URLs and + * titles in hash references. + * @param string $text + * @return string + */ + protected function stripFootnotes($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: [^id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,' . $less_than_tab . '}\[\^(.+?)\][ ]?: # note_id = $1 + [ ]* + \n? # maybe *one* newline + ( # text = $2 (no blank lines allowed) + (?: + .+ # actual text + | + \n # newlines but + (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker. + (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed + # by non-indented content + )* + ) + }xm', + array($this, '_stripFootnotes_callback'), + $text); + return $text; + } + + /** + * Callback for stripping footnotes + * @param array $matches + * @return string + */ + protected function _stripFootnotes_callback($matches) { + $note_id = $this->fn_id_prefix . $matches[1]; + $this->footnotes[$note_id] = $this->outdent($matches[2]); + return ''; // String that will replace the block + } + + /** + * Replace footnote references in $text [^id] with a special text-token + * which will be replaced by the actual footnote marker in appendFootnotes. + * @param string $text + * @return string + */ + protected function doFootnotes($text) { + if (!$this->in_anchor) { + $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); + } + return $text; + } + + /** + * Append footnote list to text + * @param string $text + * @return string + */ + protected function appendFootnotes($text) { + $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array($this, '_appendFootnotes_callback'), $text); + + if (!empty($this->footnotes_ordered)) { + $text .= "\n\n"; + $text .= "
    \n"; + $text .= "empty_element_suffix . "\n"; + $text .= "
      \n\n"; + + $attr = ""; + if ($this->fn_backlink_class != "") { + $class = $this->fn_backlink_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_backlink_title != "") { + $title = $this->fn_backlink_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + } + $backlink_text = $this->fn_backlink_html; + $num = 0; + + while (!empty($this->footnotes_ordered)) { + $footnote = reset($this->footnotes_ordered); + $note_id = key($this->footnotes_ordered); + unset($this->footnotes_ordered[$note_id]); + $ref_count = $this->footnotes_ref_count[$note_id]; + unset($this->footnotes_ref_count[$note_id]); + unset($this->footnotes[$note_id]); + + $footnote .= "\n"; // Need to append newline before parsing. + $footnote = $this->runBlockGamut("$footnote\n"); + $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array($this, '_appendFootnotes_callback'), $footnote); + + $attr = str_replace("%%", ++$num, $attr); + $note_id = $this->encodeAttribute($note_id); + + // Prepare backlink, multiple backlinks if multiple references + $backlink = "$backlink_text"; + for ($ref_num = 2; $ref_num <= $ref_count; ++$ref_num) { + $backlink .= " $backlink_text"; + } + // Add backlink to last paragraph; create new paragraph if needed. + if (preg_match('{

      $}', $footnote)) { + $footnote = substr($footnote, 0, -4) . " $backlink

      "; + } else { + $footnote .= "\n\n

      $backlink

      "; + } + + $text .= "
    1. \n"; + $text .= $footnote . "\n"; + $text .= "
    2. \n\n"; + } + + $text .= "
    \n"; + $text .= "
    "; + } + return $text; + } + + /** + * Callback for appending footnotes + * @param array $matches + * @return string + */ + protected function _appendFootnotes_callback($matches) { + $node_id = $this->fn_id_prefix . $matches[1]; + + // Create footnote marker only if it has a corresponding footnote *and* + // the footnote hasn't been used by another marker. + if (isset($this->footnotes[$node_id])) { + $num =& $this->footnotes_numbers[$node_id]; + if (!isset($num)) { + // Transfer footnote content to the ordered list and give it its + // number + $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; + $this->footnotes_ref_count[$node_id] = 1; + $num = $this->footnote_counter++; + $ref_count_mark = ''; + } else { + $ref_count_mark = $this->footnotes_ref_count[$node_id] += 1; + } + + $attr = ""; + if ($this->fn_link_class != "") { + $class = $this->fn_link_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_link_title != "") { + $title = $this->fn_link_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + } + + $attr = str_replace("%%", $num, $attr); + $node_id = $this->encodeAttribute($node_id); + + return + "". + "$num". + ""; + } + + return "[^" . $matches[1] . "]"; + } + + + /** + * Abbreviations - strips abbreviations from text, stores titles in hash + * references. + * @param string $text + * @return string + */ + protected function stripAbbreviations($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: [id]*: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,' . $less_than_tab . '}\*\[(.+?)\][ ]?: # abbr_id = $1 + (.*) # text = $2 (no blank lines allowed) + }xm', + array($this, '_stripAbbreviations_callback'), + $text); + return $text; + } + + /** + * Callback for stripping abbreviations + * @param array $matches + * @return string + */ + protected function _stripAbbreviations_callback($matches) { + $abbr_word = $matches[1]; + $abbr_desc = $matches[2]; + if ($this->abbr_word_re) { + $this->abbr_word_re .= '|'; + } + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + return ''; // String that will replace the block + } + + /** + * Find defined abbreviations in text and wrap them in elements. + * @param string $text + * @return string + */ + protected function doAbbreviations($text) { + if ($this->abbr_word_re) { + // cannot use the /x modifier because abbr_word_re may + // contain significant spaces: + $text = preg_replace_callback('{' . + '(?abbr_word_re . ')' . + '(?![\w\x1A])' . + '}', + array($this, '_doAbbreviations_callback'), $text); + } + return $text; + } + + /** + * Callback for processing abbreviations + * @param array $matches + * @return string + */ + protected function _doAbbreviations_callback($matches) { + $abbr = $matches[0]; + if (isset($this->abbr_desciptions[$abbr])) { + $desc = $this->abbr_desciptions[$abbr]; + if (empty($desc)) { + return $this->hashPart("$abbr"); + } else { + $desc = $this->encodeAttribute($desc); + return $this->hashPart("$abbr"); + } + } else { + return $matches[0]; + } + } } - diff --git a/library/php-markdown/Michelf/MarkdownInterface.inc.php b/library/php-markdown/Michelf/MarkdownInterface.inc.php index a023ed4e3a..c4e9ac7f64 100644 --- a/library/php-markdown/Michelf/MarkdownInterface.inc.php +++ b/library/php-markdown/Michelf/MarkdownInterface.inc.php @@ -1,9 +1,9 @@ -# -# Original Markdown -# Copyright (c) 2004-2006 John Gruber -# -# +/** + * Markdown - A text-to-HTML conversion tool for web writers + * + * @package php-markdown + * @author Michel Fortin + * @copyright 2004-2016 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + namespace Michelf; - -# -# Markdown Parser Interface -# - +/** + * Markdown Parser Interface + */ interface MarkdownInterface { + /** + * Initialize the parser and return the result of its transform method. + * This will work fine for derived classes too. + * + * @api + * + * @param string $text + * @return string + */ + public static function defaultTransform($text); - # - # Initialize the parser and return the result of its transform method. - # This will work fine for derived classes too. - # - public static function defaultTransform($text); - - # - # Main function. Performs some preprocessing on the input text - # and pass it through the document gamut. - # - public function transform($text); - + /** + * Main function. Performs some preprocessing on the input text + * and pass it through the document gamut. + * + * @api + * + * @param string $text + * @return string + */ + public function transform($text); } diff --git a/library/php-markdown/Readme.md b/library/php-markdown/Readme.md index 80504c27c2..63e8c1eceb 100644 --- a/library/php-markdown/Readme.md +++ b/library/php-markdown/Readme.md @@ -1,13 +1,13 @@ PHP Markdown ============ -PHP Markdown Lib 1.4.1 - 4 May 2013 +PHP Markdown Lib 1.7.0 - 29 Oct 2016 by Michel Fortin - + based on Markdown by John Gruber - + Introduction @@ -25,10 +25,10 @@ software tool, originally written in Perl, that converts the plain text markup to HTML. PHP Markdown is a port to PHP of the original Markdown program by John Gruber. -* [Full documentation of the Markdown syntax]() - - Daring Fireball (John Gruber) -* [Markdown Extra syntax additions]() - - Michel Fortin +* [Full documentation of the Markdown syntax]() + — Daring Fireball (John Gruber) +* [Markdown Extra syntax additions]() + — Michel Fortin Requirement @@ -83,7 +83,7 @@ configuration variables: To learn more, see the full list of [configuration variables]. - [configuration variables]: http://michelf.ca/projects/php-markdown/configuration/ + [configuration variables]: https://michelf.ca/projects/php-markdown/configuration/ ### Usage without an autoloader @@ -149,7 +149,7 @@ Development and Testing ----------------------- Pull requests for fixing bugs are welcome. Proposed new features are -going meticulously reviewed -- taking into account backward compatibility, +going to be meticulously reviewed -- taking into account backward compatibility, potential side effects, and future extensibility -- before deciding on acceptance or rejection. @@ -174,11 +174,80 @@ PHP Markdown, please visit [michelf.ca/donate] or send Bitcoin to Version History --------------- -Unreleased +PHP Markdown Lib 1.7.0 (29 Oct 2016) -* Added the ability to insert custom HTML attributes everywhere an extra - attribute block is allowed (links, images, headers). Credits to - Peter Droogmans for providing the implementation. +* Added a `hard_wrap` configuration variable to make all newline characters + in the text become `
    ` tags in the HTML output. By default, according + to the standard Markdown syntax these newlines are ignored unless they a + preceded by two spaces. Thanks to Jonathan Cohlmeyer for the implementation. + +* Improved the parsing of list items to fix problematic cases that came to + light with the addition of `hard_wrap`. This should have no effect on the + output except span-level list items that ended with two spaces (and thus + ended with a line break). + +* Added a `code_span_content_func` configuration variable which takes a + function that will convert the content of the code span to HTML. This can + be useful to implement syntax highlighting. Although contrary to its + code block equivalent, there is no syntax for specifying a language. + Credits to styxit for the implementation. + +* Fixed a Markdown Extra issue where two-space-at-end-of-line hard breaks + wouldn't work inside of HTML block elements such as `

    ` + where the element expects only span-level content. + +* In the parser code, switched to PHPDoc comment format. Thanks to + Robbie Averill for the help. + + +PHP Markdown Lib 1.6.0 (23 Dec 2015) + +Note: this version was incorrectly released as 1.5.1 on Dec 22, a number +that contradicted the versioning policy. + +* For fenced code blocks in Markdown Extra, can now set a class name for the + code block's language before the special attribute block. Previously, this + class name was only allowed in the absence of the special attribute block. + +* Added a `code_block_content_func` configuration variable which takes a + function that will convert the content of the code block to HTML. This is + most useful for syntax highlighting. For fenced code blocks in Markdown + Extra, the function has access to the language class name (the one outside + of the special attribute block). Credits to Mario Konrad for providing the + implementation. + +* The curled arrow character for the backlink in footnotes is now followed + by a Unicode variant selector to prevent it from being displayed in emoji + form on iOS. + + Note that in older browsers the variant selector is often interpreted as a + separate character, making it visible after the arrow. So there is now a + also a `fn_backlink_html` configuration variable that can be used to set + the link text to something else. Credits to Dana for providing the + implementation. + +* Fixed an issue in MarkdownExtra where long header lines followed by a + special attribute block would hit the backtrack limit an cause an empty + string to be returned. + + +PHP Markdown Lib 1.5.0 (1 Mar 2015) + +* Added the ability start ordered lists with a number different from 1 and + and have that reflected in the HTML output. This can be enabled with + the `enhanced_ordered_lists` configuration variable for the Markdown + parser; it is enabled by default for Markdown Extra. + Credits to Matt Gorle for providing the implementation. + +* Added the ability to insert custom HTML attributes with simple values + everywhere an extra attribute block is allowed (links, images, headers). + The value must be unquoted, cannot contains spaces and is limited to + alphanumeric ASCII characters. + Credits to Peter Droogmans for providing the implementation. + +* Added a `header_id_func` configuration variable which takes a function + that can generate an `id` attribute value from the header text. + Credits to Evert Pot for providing the implementation. * Added a `url_filter_func` configuration variable which takes a function that can rewrite any link or image URL to something different. @@ -239,7 +308,7 @@ PHP Markdown Extra 1.2.6: * Plugin interface for WordPress and other systems is no longer present in the Lib package. The classic package is still available if you need it: - + * Added `public` and `protected` protection attributes, plus a section about what is "public API" and what isn't in the Readme file. @@ -277,13 +346,13 @@ Copyright and License --------------------- PHP Markdown Lib -Copyright (c) 2004-2014 Michel Fortin - +Copyright (c) 2004-2016 Michel Fortin + All rights reserved. Based on Markdown Copyright (c) 2003-2005 John Gruber - + All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/library/php-markdown/Readme.php b/library/php-markdown/Readme.php index d007b119f2..89449dea4d 100644 --- a/library/php-markdown/Readme.php +++ b/library/php-markdown/Readme.php @@ -1,18 +1,18 @@ diff --git a/library/php-markdown/composer.json b/library/php-markdown/composer.json index 45abc67744..c219e543c2 100644 --- a/library/php-markdown/composer.json +++ b/library/php-markdown/composer.json @@ -2,19 +2,19 @@ "name": "michelf/php-markdown", "type": "library", "description": "PHP Markdown", - "homepage": "http://michelf.ca/projects/php-markdown/", + "homepage": "https://michelf.ca/projects/php-markdown/", "keywords": ["markdown"], "license": "BSD-3-Clause", "authors": [ { "name": "Michel Fortin", "email": "michel.fortin@michelf.ca", - "homepage": "http://michelf.ca/", + "homepage": "https://michelf.ca/", "role": "Developer" }, { "name": "John Gruber", - "homepage": "http://daringfireball.net/" + "homepage": "https://daringfireball.net/" } ], "require": { @@ -22,10 +22,5 @@ }, "autoload": { "psr-0": { "Michelf": "" } - }, - "extra": { - "branch-alias": { - "dev-lib": "1.4.x-dev" - } } } diff --git a/mod/admin.php b/mod/admin.php index e8c071113d..aee1017b34 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -27,7 +27,7 @@ require_once("include/text.php"); function admin_post(App $a) { - if(!is_site_admin()) { + if (!is_site_admin()) { return; } @@ -39,7 +39,7 @@ function admin_post(App $a) { // urls if ($a->argc > 1) { - switch ($a->argv[1]){ + switch ($a->argv[1]) { case 'site': admin_page_site_post($a); break; @@ -47,10 +47,10 @@ function admin_post(App $a) { admin_page_users_post($a); break; case 'plugins': - if($a->argc > 2 && + if ($a->argc > 2 && is_file("addon/".$a->argv[2]."/".$a->argv[2].".php")) { @include_once("addon/".$a->argv[2]."/".$a->argv[2].".php"); - if(function_exists($a->argv[2].'_plugin_admin_post')) { + if (function_exists($a->argv[2].'_plugin_admin_post')) { $func = $a->argv[2].'_plugin_admin_post'; $func($a); } @@ -59,14 +59,16 @@ function admin_post(App $a) { return; // NOTREACHED break; case 'themes': - if($a->argc < 2) { - if(is_ajax()) return; + if ($a->argc < 2) { + if (is_ajax()) { + return; + } goaway('admin/'); return; } $theme = $a->argv[2]; - if(is_file("view/theme/$theme/config.php")){ + if (is_file("view/theme/$theme/config.php")) { function __call_theme_admin_post(App $a, $theme) { $orig_theme = $a->theme; $orig_page = $a->page; @@ -77,8 +79,10 @@ function admin_post(App $a) { $init = $theme."_init"; - if(function_exists($init)) $init($a); - if(function_exists("theme_admin_post")) { + if (function_exists($init)) { + $init($a); + } + if (function_exists("theme_admin_post")) { $admin_form = theme_admin_post($a); } @@ -90,8 +94,9 @@ function admin_post(App $a) { __call_theme_admin_post($a, $theme); } info(t('Theme settings updated.')); - if(is_ajax()) return; - + if (is_ajax()) { + return; + } goaway('admin/themes/'.$theme); return; break; @@ -130,7 +135,7 @@ function admin_post(App $a) { */ function admin_content(App $a) { - if(!is_site_admin()) { + if (!is_site_admin()) { return login(false); } @@ -168,7 +173,7 @@ function admin_content(App $a) { $r = q("SELECT `name` FROM `addon` WHERE `plugin_admin` = 1 ORDER BY `name`"); $aside_tools['plugins_admin']=array(); - foreach ($r as $h){ + foreach ($r as $h) { $plugin =$h['name']; $aside_tools['plugins_admin'][] = array("admin/plugins/".$plugin, $plugin, "plugin"); // temp plugins with admin @@ -199,8 +204,8 @@ function admin_content(App $a) { */ $o = ''; // urls - if($a->argc > 1) { - switch ($a->argv[1]){ + if ($a->argc > 1) { + switch ($a->argv[1]) { case 'site': $o = admin_page_site($a); break; @@ -238,7 +243,7 @@ function admin_content(App $a) { $o = admin_page_summary($a); } - if(is_ajax()) { + if (is_ajax()) { echo $o; killme(); return ''; @@ -270,8 +275,8 @@ function admin_page_federation(App $a) { // off one % two of them are needed in the query // Add more platforms if you like, when one returns 0 known nodes it is not // displayed on the stats page. - $platforms = array('Friendica', 'Diaspora', '%%red%%', 'Hubzilla', 'BlaBlaNet', 'GNU Social', 'StatusNet', 'Mastodon'); - $colors = array('Friendica' => '#ffc018', // orange from the logo + $platforms = array('Friendi%%a', 'Diaspora', '%%red%%', 'Hubzilla', 'BlaBlaNet', 'GNU Social', 'StatusNet', 'Mastodon'); + $colors = array('Friendi%%a' => '#ffc018', // orange from the logo 'Diaspora' => '#a1a1a1', // logo is black and white, makes a gray '%%red%%' => '#c50001', // fire red from the logo 'Hubzilla' => '#43488a', // blue from the logo @@ -310,19 +315,21 @@ function admin_page_federation(App $a) { // in the DB the Diaspora versions have the format x.x.x.x-xx the last // part (-xx) should be removed to clean up the versions from the "head // commit" information and combined into a single entry for x.x.x.x - if($p=='Diaspora') { + if ($p == 'Diaspora') { $newV = array(); $newVv = array(); - foreach($v as $vv) { + foreach ($v as $vv) { $newVC = $vv['total']; $newVV = $vv['version']; $posDash = strpos($newVV, '-'); - if($posDash) + if ($posDash) { $newVV = substr($newVV, 0, $posDash); - if(isset($newV[$newVV])) + } + if (isset($newV[$newVV])) { $newV[$newVV] += $newVC; - else + } else { $newV[$newVV] = $newVC; + } } foreach ($newV as $key => $value) { array_push($newVv, array('total'=>$value, 'version'=>$key)); @@ -333,7 +340,7 @@ function admin_page_federation(App $a) { // early friendica versions have the format x.x.xxxx where xxxx is the // DB version stamp; those should be operated out and versions be // conbined - if($p=='Friendica') { + if ($p == 'Friendi%%a') { $newV = array(); $newVv = array(); foreach ($v as $vv) { @@ -341,12 +348,14 @@ function admin_page_federation(App $a) { $newVV = $vv['version']; $lastDot = strrpos($newVV,'.'); $len = strlen($newVV)-1; - if(($lastDot == $len-4) && (!strrpos($newVV,'-rc')==$len-3)) + if (($lastDot == $len-4) && (!strrpos($newVV,'-rc') == $len-3)) { $newVV = substr($newVV, 0, $lastDot); - if(isset($newV[$newVV])) + } + if (isset($newV[$newVV])) { $newV[$newVV] += $newVC; - else + } else { $newV[$newVV] = $newVC; + } } foreach ($newV as $key => $value) { array_push($newVv, array('total'=>$value, 'version'=>$key)); @@ -455,7 +464,10 @@ function admin_page_summary(App $a) { ); $users=0; - foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; } + foreach ($r as $u) { + $accounts[$u['page-flags']][1] = $u['count']; + $users+= $u['count']; + } logger('accounts: '.print_r($accounts,true),LOGGER_DATA); @@ -468,12 +480,8 @@ function admin_page_summary(App $a) { $r = qu("SELECT COUNT(*) AS `total` FROM `queue` WHERE 1"); $queue = (($r) ? $r[0]['total'] : 0); - if (get_config('system','worker')) { - $r = qu("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE 1"); - $workerqueue = (($r) ? $r[0]['total'] : 0); - } else { - $workerqueue = 0; - } + $r = qu("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE 1"); + $workerqueue = (($r) ? $r[0]['total'] : 0); // We can do better, but this is a quick queue status @@ -485,7 +493,6 @@ function admin_page_summary(App $a) { '$title' => t('Administration'), '$page' => t('Summary'), '$queues' => $queues, - '$workeractive' => get_config('system','worker'), '$users' => array(t('Registered users'), $users), '$accounts' => $accounts, '$pending' => array(t('Pending registrations'), $pending), @@ -506,19 +513,19 @@ function admin_page_summary(App $a) { * @param App $a */ function admin_page_site_post(App $a) { - if(!x($_POST,"page_site")) { + if (!x($_POST,"page_site")) { return; } check_form_security_token_redirectOnErr('/admin/site', 'admin_site'); // relocate - if(x($_POST,'relocate') && x($_POST,'relocate_url') && $_POST['relocate_url']!="") { + if (x($_POST,'relocate') && x($_POST,'relocate_url') && $_POST['relocate_url'] != "") { $new_url = $_POST['relocate_url']; $new_url = rtrim($new_url,"/"); $parsed = @parse_url($new_url); - if(!$parsed || (!x($parsed,'host') || !x($parsed,'scheme'))) { + if (!$parsed || (!x($parsed,'host') || !x($parsed,'scheme'))) { notice(t("Can not parse base url. Must have at least ://")); goaway('admin/site'); } @@ -551,7 +558,7 @@ function admin_page_site_post(App $a) { $q = sprintf("UPDATE %s SET %s;", $table_name, $upds); $r = q($q); - if(!$r) { + if (!$r) { notice("Failed updating '$table_name': ".$db->error); goaway('admin/site'); } @@ -622,7 +629,6 @@ function admin_page_site_post(App $a) { $no_multi_reg = ((x($_POST,'no_multi_reg')) ? True : False); $no_openid = !((x($_POST,'no_openid')) ? True : False); $no_regfullname = !((x($_POST,'no_regfullname')) ? True : False); - $no_utf = !((x($_POST,'no_utf')) ? True : False); $community_page_style = ((x($_POST,'community_page_style')) ? intval(trim($_POST['community_page_style'])) : 0); $max_author_posts_community_page = ((x($_POST,'max_author_posts_community_page')) ? intval(trim($_POST['max_author_posts_community_page'])) : 0); @@ -630,8 +636,6 @@ function admin_page_site_post(App $a) { $proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : ''); $proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : ''); $timeout = ((x($_POST,'timeout')) ? intval(trim($_POST['timeout'])) : 60); - $delivery_interval = ((x($_POST,'delivery_interval')) ? intval(trim($_POST['delivery_interval'])) : 0); - $poll_interval = ((x($_POST,'poll_interval')) ? intval(trim($_POST['poll_interval'])) : 0); $maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50); $maxloadavg_frontend = ((x($_POST,'maxloadavg_frontend')) ? intval(trim($_POST['maxloadavg_frontend'])) : 50); $optimize_max_tablesize = ((x($_POST,'optimize_max_tablesize')) ? intval(trim($_POST['optimize_max_tablesize'])): 100); @@ -655,28 +659,25 @@ function admin_page_site_post(App $a) { $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); - $lockpath = ((x($_POST,'lockpath')) ? notags(trim($_POST['lockpath'])) : ''); $temppath = ((x($_POST,'temppath')) ? notags(trim($_POST['temppath'])) : ''); $basepath = ((x($_POST,'basepath')) ? notags(trim($_POST['basepath'])) : ''); $singleuser = ((x($_POST,'singleuser')) ? notags(trim($_POST['singleuser'])) : ''); $proxy_disabled = ((x($_POST,'proxy_disabled')) ? True : False); $only_tag_search = ((x($_POST,'only_tag_search')) ? True : False); $rino = ((x($_POST,'rino')) ? intval($_POST['rino']) : 0); - $embedly = ((x($_POST,'embedly')) ? notags(trim($_POST['embedly'])) : ''); - $worker = ((x($_POST,'worker')) ? True : False); $worker_queues = ((x($_POST,'worker_queues')) ? intval($_POST['worker_queues']) : 4); $worker_dont_fork = ((x($_POST,'worker_dont_fork')) ? True : False); $worker_fastlane = ((x($_POST,'worker_fastlane')) ? True : False); $worker_frontend = ((x($_POST,'worker_frontend')) ? True : False); - if($a->get_path() != "") + if ($a->get_path() != "") { $diaspora_enabled = false; - - if(!$thread_allow) + } + if (!$thread_allow) { $ostatus_disabled = true; - - if($ssl_policy != intval(get_config('system','ssl_policy'))) { - if($ssl_policy == SSL_POLICY_FULL) { + } + if ($ssl_policy != intval(get_config('system','ssl_policy'))) { + if ($ssl_policy == SSL_POLICY_FULL) { q("UPDATE `contact` SET `url` = REPLACE(`url` , 'http:' , 'https:'), `photo` = REPLACE(`photo` , 'http:' , 'https:'), @@ -694,8 +695,7 @@ function admin_page_site_post(App $a) { `thumb` = REPLACE(`thumb` , 'http:' , 'https:') WHERE 1 " ); - } - elseif($ssl_policy == SSL_POLICY_SELFSIGN) { + } elseif ($ssl_policy == SSL_POLICY_SELFSIGN) { q("UPDATE `contact` SET `url` = REPLACE(`url` , 'https:' , 'http:'), `photo` = REPLACE(`photo` , 'https:' , 'http:'), @@ -716,8 +716,6 @@ function admin_page_site_post(App $a) { } } set_config('system','ssl_policy',$ssl_policy); - set_config('system','delivery_interval',$delivery_interval); - set_config('system','poll_interval',$poll_interval); set_config('system','maxloadavg',$maxloadavg); set_config('system','maxloadavg_frontend',$maxloadavg_frontend); set_config('system','optimize_max_tablesize',$optimize_max_tablesize); @@ -735,7 +733,7 @@ function admin_page_site_post(App $a) { set_config('system','shortcut_icon',$shortcut_icon); set_config('system','touch_icon',$touch_icon); - if($banner=="") { + if ($banner == "") { // don't know why, but del_config doesn't work... q("DELETE FROM `config` WHERE `cat` = '%s' AND `k` = '%s' LIMIT 1", dbesc("system"), @@ -745,7 +743,7 @@ function admin_page_site_post(App $a) { set_config('system','banner', $banner); } - if($info=="") { + if ($info == "") { del_config('config','info'); } else { set_config('config','info',$info); @@ -753,12 +751,12 @@ function admin_page_site_post(App $a) { set_config('system','language', $language); set_config('system','theme', $theme); - if($theme_mobile === '---') { + if ($theme_mobile === '---') { del_config('system','mobile-theme'); } else { set_config('system','mobile-theme', $theme_mobile); } - if($singleuser === '---') { + if ($singleuser === '---') { del_config('system','singleuser'); } else { set_config('system','singleuser', $singleuser); @@ -787,7 +785,6 @@ function admin_page_site_post(App $a) { set_config('system','no_regfullname', $no_regfullname); set_config('system','community_page_style', $community_page_style); set_config('system','max_author_posts_community_page', $max_author_posts_community_page); - set_config('system','no_utf', $no_utf); set_config('system','verifyssl', $verifyssl); set_config('system','proxyuser', $proxyuser); set_config('system','proxy', $proxy); @@ -806,26 +803,21 @@ function admin_page_site_post(App $a) { set_config('system','itemcache', $itemcache); set_config('system','itemcache_duration', $itemcache_duration); set_config('system','max_comments', $max_comments); - set_config('system','lockpath', $lockpath); set_config('system','temppath', $temppath); set_config('system','basepath', $basepath); set_config('system','proxy_disabled', $proxy_disabled); set_config('system','only_tag_search', $only_tag_search); - set_config('system','worker', $worker); set_config('system','worker_queues', $worker_queues); set_config('system','worker_dont_fork', $worker_dont_fork); set_config('system','worker_fastlane', $worker_fastlane); set_config('system','frontend_worker', $worker_frontend); - if($rino==2 and !function_exists('mcrypt_create_iv')) { + if (($rino == 2) and !function_exists('mcrypt_create_iv')) { notice(t("RINO2 needs mcrypt php extension to work.")); } else { set_config('system','rino_encrypt', $rino); } - set_config('system','embedly', $embedly); - - info(t('Site settings updated.').EOL); goaway('admin/site'); return; // NOTREACHED @@ -845,7 +837,7 @@ function admin_page_site(App $a) { /* Installed langs */ $lang_choices = get_available_languages(); - if(strlen(get_config('system','directory_submit_url')) AND + if (strlen(get_config('system','directory_submit_url')) AND !strlen(get_config('system','directory'))) { set_config('system','directory', dirname(get_config('system','directory_submit_url'))); del_config('system','directory_submit_url'); @@ -856,12 +848,12 @@ function admin_page_site(App $a) { $theme_choices_mobile = array(); $theme_choices_mobile["---"] = t("No special theme for mobile devices"); $files = glob('view/theme/*'); - if($files) { + if ($files) { $allowed_theme_list = Config::get('system', 'allowed_themes'); - foreach($files as $file) { - if(intval(file_exists($file.'/unsupported'))) + foreach ($files as $file) { + if (intval(file_exists($file.'/unsupported'))) continue; $f = basename($file); @@ -873,7 +865,7 @@ function admin_page_site(App $a) { $theme_name = ((file_exists($file.'/experimental')) ? sprintf("%s - \x28Experimental\x29", $f) : $f); - if(file_exists($file.'/mobile')) { + if (file_exists($file.'/mobile')) { $theme_choices_mobile[$f] = $theme_name; } else { $theme_choices[$f] = $theme_name; @@ -922,15 +914,15 @@ function admin_page_site(App $a) { /* Banner */ $banner = get_config('system','banner'); - if($banner == false) + if ($banner == false) { $banner = 'logoFriendica'; + } $banner = htmlspecialchars($banner); $info = get_config('config','info'); $info = htmlspecialchars($info); // Automatically create temporary paths get_temppath(); - get_lockpath(); get_itemcachepath(); //echo "

    "; var_dump($lang_choices); die("
    "); @@ -948,9 +940,9 @@ function admin_page_site(App $a) { SSL_POLICY_SELFSIGN => t("Self-signed certificate, use SSL for local links only (discouraged)") ); - if($a->config['hostname'] == "") + if ($a->config['hostname'] == "") { $a->config['hostname'] = $a->get_hostname(); - + } $diaspora_able = ($a->get_path() == ""); $optimize_max_tablesize = Config::get('system','optimize_max_tablesize', 100); @@ -1014,7 +1006,6 @@ function admin_page_site(App $a) { '$no_multi_reg' => array('no_multi_reg', t("Block multiple registrations"), get_config('system','block_extended_register'), t("Disallow users to register additional accounts for use as pages.")), '$no_openid' => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")), '$no_regfullname' => array('no_regfullname', t("Fullname check"), !get_config('system','no_regfullname'), t("Force users to register with a space between firstname and lastname in Full name, as an antispam measure")), - '$no_utf' => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")), '$community_page_style' => array('community_page_style', t("Community Page Style"), get_config('system','community_page_style'), t("Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."), $community_page_style_choices), '$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")), '$ostatus_disabled' => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")), @@ -1029,8 +1020,6 @@ function admin_page_site(App $a) { '$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""), '$proxy' => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""), '$timeout' => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")), - '$delivery_interval' => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")), - '$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")), '$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")), '$maxloadavg_frontend' => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(get_config('system','maxloadavg_frontend')) > 0)?get_config('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")), '$optimize_max_tablesize'=> array('optimize_max_tablesize', t("Maximum table size for optimization"), $optimize_max_tablesize, t("Maximum table size (in MB) for the automatic optimization - default 100 MB. Enter -1 to disable it.")), @@ -1049,7 +1038,6 @@ function admin_page_site(App $a) { '$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.")), '$max_comments' => array('max_comments', t("Maximum numbers of comments per post"), get_config('system','max_comments'), t("How much comments should be shown for each post? Default value is 100.")), - '$lockpath' => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), t("The lock file is used to avoid multiple pollers at one time. Only define a folder here.")), '$temppath' => array('temppath', t("Temp path"), get_config('system','temppath'), t("If you have a restricted system where the webserver can't access the system temp path, enter another path here.")), '$basepath' => array('basepath', t("Base path to installation"), get_config('system','basepath'), t("If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot.")), '$proxy_disabled' => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")), @@ -1058,9 +1046,7 @@ function admin_page_site(App $a) { '$relocate_url' => array('relocate_url', t("New base url"), App::get_baseurl(), t("Change base url for this server. Sends relocate message to all DFRN contacts of all users.")), '$rino' => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")), - '$embedly' => array('embedly', t("Embedly API key"), get_config('system','embedly'), t("Embedly is used to fetch additional data for web pages. This is an optional parameter.")), - '$worker' => array('worker', t("Enable 'worker' background processing"), get_config('system','worker'), t("The worker background processing limits the number of parallel background jobs to a maximum number and respects the system load.")), '$worker_queues' => array('worker_queues', t("Maximum number of parallel workers"), get_config('system','worker_queues'), t("On shared hosters set this to 2. On larger systems, values of 10 are great. Default value is 4.")), '$worker_dont_fork' => array('worker_dont_fork', t("Don't use 'proc_open' with the worker"), get_config('system','worker_dont_fork'), t("Enable this if your system doesn't allow the use of 'proc_open'. This can happen on shared hosters. If this is enabled you should increase the frequency of poller calls in your crontab.")), '$worker_fastlane' => array('worker_fastlane', t("Enable fastlane"), get_config('system','worker_fastlane'), t("When enabed, the fastlane mechanism starts an additional worker if processes with higher priority are blocked by processes of lower priority.")), @@ -1088,42 +1074,45 @@ function admin_page_dbsync(App $a) { $o = ''; - if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') { + if ($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') { set_config('database', 'update_'.intval($a->argv[3]), 'success'); $curr = get_config('system','build'); - if(intval($curr) == intval($a->argv[3])) + if (intval($curr) == intval($a->argv[3])) { set_config('system','build',intval($curr) + 1); + } info(t('Update has been marked successful').EOL); goaway('admin/dbsync'); } - if(($a->argc > 2) AND (intval($a->argv[2]) OR ($a->argv[2] === 'check'))) { + if (($a->argc > 2) AND (intval($a->argv[2]) OR ($a->argv[2] === 'check'))) { require_once("include/dbstructure.php"); $retval = update_structure(false, true); - if(!$retval) { + if (!$retval) { $o .= sprintf(t("Database structure update %s was successfully applied."), DB_UPDATE_VERSION)."
    "; set_config('database', 'dbupdate_'.DB_UPDATE_VERSION, 'success'); - } else + } else { $o .= sprintf(t("Executing of database structure update %s failed with error: %s"), DB_UPDATE_VERSION, $retval)."
    "; - if($a->argv[2] === 'check') + } + if ($a->argv[2] === 'check') { return $o; + } } - if($a->argc > 2 && intval($a->argv[2])) { + if ($a->argc > 2 && intval($a->argv[2])) { require_once('update.php'); $func = 'update_'.intval($a->argv[2]); - if(function_exists($func)) { + if (function_exists($func)) { $retval = $func(); - if($retval === UPDATE_FAILED) { + if ($retval === UPDATE_FAILED) { $o .= sprintf(t("Executing %s failed with error: %s"), $func, $retval); } - elseif($retval === UPDATE_SUCCESS) { + elseif ($retval === UPDATE_SUCCESS) { $o .= sprintf(t('Update %s was successfully applied.', $func)); set_config('database',$func, 'success'); - } - else + } else { $o .= sprintf(t('Update %s did not return a status. Unknown if it succeeded.'), $func); + } } else { $o .= sprintf(t('There was no additional update function %s that needed to be called.'), $func)."
    "; set_config('database',$func, 'success'); @@ -1136,8 +1125,9 @@ function admin_page_dbsync(App $a) { if (dbm::is_result($r)) { foreach ($r as $rr) { $upd = intval(substr($rr['k'],7)); - if($upd < 1139 || $rr['v'] === 'success') + if ($upd < 1139 || $rr['v'] === 'success') { continue; + } $failed[] = $upd; } } @@ -1177,7 +1167,7 @@ function admin_page_users_post(App $a) { check_form_security_token_redirectOnErr('/admin/users', 'admin_users'); - if (!($nu_name==="") && !($nu_email==="") && !($nu_nickname==="")) { + if (!($nu_name === "") && !($nu_email === "") && !($nu_nickname === "")) { require_once('include/user.php'); $result = create_user(array('username'=>$nu_name, 'email'=>$nu_email, @@ -1228,31 +1218,31 @@ function admin_page_users_post(App $a) { } - if(x($_POST,'page_users_block')) { - foreach($users as $uid){ + if (x($_POST,'page_users_block')) { + foreach ($users as $uid) { q("UPDATE `user` SET `blocked` = 1-`blocked` WHERE `uid` = %s", intval($uid) ); } notice(sprintf(tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users))); } - if(x($_POST,'page_users_delete')) { + if (x($_POST,'page_users_delete')) { require_once("include/Contact.php"); - foreach($users as $uid){ + foreach ($users as $uid) { user_remove($uid); } notice(sprintf(tt("%s user deleted", "%s users deleted", count($users)), count($users))); } - if(x($_POST,'page_users_approve')) { + if (x($_POST,'page_users_approve')) { require_once("mod/regmod.php"); - foreach($pending as $hash){ + foreach ($pending as $hash) { user_allow($hash); } } - if(x($_POST,'page_users_deny')) { + if (x($_POST,'page_users_deny')) { require_once("mod/regmod.php"); - foreach($pending as $hash){ + foreach ($pending as $hash) { user_deny($hash); } } @@ -1273,31 +1263,31 @@ function admin_page_users_post(App $a) { * @return string */ function admin_page_users(App $a) { - if($a->argc>2) { + if ($a->argc>2) { $uid = $a->argv[3]; $user = q("SELECT `username`, `blocked` FROM `user` WHERE `uid` = %d", intval($uid)); - if(count($user)==0) { + if (count($user) == 0) { notice('User not found'.EOL); goaway('admin/users'); return ''; // NOTREACHED } - switch($a->argv[2]){ - case "delete":{ + switch($a->argv[2]) { + case "delete": check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't'); // delete user require_once("include/Contact.php"); user_remove($uid); notice(sprintf(t("User '%s' deleted"), $user[0]['username']).EOL); - }; break; - case "block":{ + break; + case "block": check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't'); q("UPDATE `user` SET `blocked` = %d WHERE `uid` = %s", intval(1-$user[0]['blocked']), intval($uid) ); notice(sprintf(($user[0]['blocked']?t("User '%s' unblocked"):t("User '%s' blocked")) , $user[0]['username']).EOL); - }; break; + break; } goaway('admin/users'); return ''; // NOTREACHED @@ -1313,7 +1303,7 @@ function admin_page_users(App $a) { /* get users */ $total = qu("SELECT COUNT(*) AS `total` FROM `user` WHERE 1"); - if(count($total)) { + if (count($total)) { $a->set_pager_total($total[0]['total']); $a->set_pager_itemspage(100); } @@ -1330,22 +1320,22 @@ function admin_page_users(App $a) { $order = "contact.name"; $order_direction = "+"; - if (x($_GET,'o')){ + if (x($_GET,'o')) { $new_order = $_GET['o']; - if ($new_order[0]==="-") { + if ($new_order[0] === "-") { $order_direction = "-"; $new_order = substr($new_order,1); } - if (in_array($new_order, $valid_orders)){ + if (in_array($new_order, $valid_orders)) { $order = $new_order; } - if (x($_GET,'d')){ + if (x($_GET,'d')) { $new_direction = $_GET['d']; } } $sql_order = "`".str_replace('.','`.`',$order)."`"; - $sql_order_direction = ($order_direction==="+")?"ASC":"DESC"; + $sql_order_direction = ($order_direction === "+")?"ASC":"DESC"; $users = qu("SELECT `user`.*, `contact`.`name`, `contact`.`url`, `contact`.`micro`, `user`.`account_expired`, `contact`.`last-item` AS `lastitem_date` FROM `user` @@ -1359,7 +1349,7 @@ function admin_page_users(App $a) { //echo "
    $users"; killme();
     
     	$adminlist = explode(",", str_replace(" ", "", $a->config['admin_email']));
    -	$_setup_users = function ($e) use ($adminlist){
    +	$_setup_users = function ($e) use ($adminlist) {
     		$accounts = array(
     			t('Normal Account'),
     			t('Soapbox Account'),
    @@ -1385,22 +1375,21 @@ function admin_page_users(App $a) {
     	$tmp_users = array();
     	$deleted = array();
     
    -	while(count($users)) {
    +	while (count($users)) {
     		$new_user = array();
    -		foreach(array_pop($users) as $k => $v) {
    +		foreach (array_pop($users) as $k => $v) {
     			$k = str_replace('-','_',$k);
     			$new_user[$k] = $v;
     		}
    -		if($new_user['deleted']) {
    +		if ($new_user['deleted']) {
     			array_push($deleted, $new_user);
    -		}
    -		else {
    +		} else {
     			array_push($tmp_users, $new_user);
     		}
     	}
     	//Reversing the two array, and moving $tmp_users to $users
     	array_reverse($deleted);
    -	while(count($tmp_users)) {
    +	while (count($tmp_users)) {
     		array_push($users, array_pop($tmp_users));
     	}
     
    @@ -1477,19 +1466,19 @@ function admin_page_plugins(App $a) {
     	/*
     	 * Single plugin
     	 */
    -	if($a->argc == 3) {
    +	if ($a->argc == 3) {
     		$plugin = $a->argv[2];
    -		if(!is_file("addon/$plugin/$plugin.php")) {
    +		if (!is_file("addon/$plugin/$plugin.php")) {
     			notice(t("Item not found."));
     			return '';
     		}
     
    -		if(x($_GET,"a") && $_GET['a']=="t") {
    +		if (x($_GET,"a") && $_GET['a']=="t") {
     			check_form_security_token_redirectOnErr('/admin/plugins', 'admin_themes', 't');
     
     			// Toggle plugin status
     			$idx = array_search($plugin, $a->plugins);
    -			if($idx !== false) {
    +			if ($idx !== false) {
     				unset($a->plugins[$idx]);
     				uninstall_plugin($plugin);
     				info(sprintf(t("Plugin %s disabled."), $plugin));
    @@ -1506,22 +1495,22 @@ function admin_page_plugins(App $a) {
     		// display plugin details
     		require_once('library/markdown.php');
     
    -		if(in_array($plugin, $a->plugins)) {
    +		if (in_array($plugin, $a->plugins)) {
     			$status="on"; $action= t("Disable");
     		} else {
     			$status="off"; $action= t("Enable");
     		}
     
     		$readme=Null;
    -		if(is_file("addon/$plugin/README.md")) {
    +		if (is_file("addon/$plugin/README.md")) {
     			$readme = file_get_contents("addon/$plugin/README.md");
     			$readme = Markdown($readme);
    -		} elseif(is_file("addon/$plugin/README")) {
    +		} elseif (is_file("addon/$plugin/README")) {
     			$readme = "
    ". file_get_contents("addon/$plugin/README") ."
    "; } $admin_form=""; - if(is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)) { + if (is_array($a->plugins_admin) && in_array($plugin, $a->plugins_admin)) { @require_once("addon/$plugin/$plugin.php"); $func = $plugin.'_plugin_admin'; $func($a, $admin_form); @@ -1613,8 +1602,8 @@ function admin_page_plugins(App $a) { */ function toggle_theme(&$themes,$th,&$result) { for($x = 0; $x < count($themes); $x ++) { - if($themes[$x]['name'] === $th) { - if($themes[$x]['allowed']) { + if ($themes[$x]['name'] === $th) { + if ($themes[$x]['allowed']) { $themes[$x]['allowed'] = 0; $result = 0; } @@ -1633,8 +1622,8 @@ function toggle_theme(&$themes,$th,&$result) { */ function theme_status($themes,$th) { for($x = 0; $x < count($themes); $x ++) { - if($themes[$x]['name'] === $th) { - if($themes[$x]['allowed']) { + if ($themes[$x]['name'] === $th) { + if ($themes[$x]['allowed']) { return 1; } else { @@ -1652,11 +1641,12 @@ function theme_status($themes,$th) { */ function rebuild_theme_table($themes) { $o = ''; - if(count($themes)) { - foreach($themes as $th) { - if($th['allowed']) { - if(strlen($o)) + if (count($themes)) { + foreach ($themes as $th) { + if ($th['allowed']) { + if (strlen($o)) { $o .= ','; + } $o .= $th['name']; } } @@ -1686,15 +1676,18 @@ function admin_page_themes(App $a) { $allowed_themes_str = get_config('system','allowed_themes'); $allowed_themes_raw = explode(',',$allowed_themes_str); $allowed_themes = array(); - if(count($allowed_themes_raw)) - foreach($allowed_themes_raw as $x) - if(strlen(trim($x))) + if (count($allowed_themes_raw)) { + foreach ($allowed_themes_raw as $x) { + if (strlen(trim($x))) { $allowed_themes[] = trim($x); + } + } + } $themes = array(); $files = glob('view/theme/*'); - if($files) { - foreach($files as $file) { + if ($files) { + foreach ($files as $file) { $f = basename($file); // Is there a style file? @@ -1709,12 +1702,13 @@ function admin_page_themes(App $a) { $is_supported = 1-(intval(file_exists($file.'/unsupported'))); $is_allowed = intval(in_array($f,$allowed_themes)); - if($is_allowed OR $is_supported OR get_config("system", "show_unsupported_themes")) + if ($is_allowed OR $is_supported OR get_config("system", "show_unsupported_themes")) { $themes[] = array('name' => $f, 'experimental' => $is_experimental, 'supported' => $is_supported, 'allowed' => $is_allowed); + } } } - if(! count($themes)) { + if (! count($themes)) { notice(t('No themes found.')); return ''; } @@ -1723,25 +1717,24 @@ function admin_page_themes(App $a) { * Single theme */ - if($a->argc == 3) { + if ($a->argc == 3) { $theme = $a->argv[2]; - if(! is_dir("view/theme/$theme")) { + if (! is_dir("view/theme/$theme")) { notice(t("Item not found.")); return ''; } - if(x($_GET,"a") && $_GET['a']=="t") { + if (x($_GET,"a") && $_GET['a']=="t") { check_form_security_token_redirectOnErr('/admin/themes', 'admin_themes', 't'); // Toggle theme status toggle_theme($themes,$theme,$result); $s = rebuild_theme_table($themes); - if($result) { + if ($result) { install_theme($theme); info(sprintf('Theme %s enabled.',$theme)); - } - else { + } else { uninstall_theme($theme); info(sprintf('Theme %s disabled.',$theme)); } @@ -1754,22 +1747,22 @@ function admin_page_themes(App $a) { // display theme details require_once('library/markdown.php'); - if(theme_status($themes,$theme)) { + if (theme_status($themes,$theme)) { $status="on"; $action= t("Disable"); } else { $status="off"; $action= t("Enable"); } - $readme=Null; - if(is_file("view/theme/$theme/README.md")) { + $readme = Null; + if (is_file("view/theme/$theme/README.md")) { $readme = file_get_contents("view/theme/$theme/README.md"); $readme = Markdown($readme); - } elseif(is_file("view/theme/$theme/README")) { + } elseif (is_file("view/theme/$theme/README")) { $readme = "
    ". file_get_contents("view/theme/$theme/README") ."
    "; } - $admin_form=""; - if(is_file("view/theme/$theme/config.php")) { + $admin_form = ""; + if (is_file("view/theme/$theme/config.php")) { function __get_theme_admin_form(App $a, $theme) { $orig_theme = $a->theme; $orig_page = $a->page; @@ -1780,8 +1773,10 @@ function admin_page_themes(App $a) { $init = $theme."_init"; - if(function_exists($init)) $init($a); - if(function_exists("theme_admin")) { + if (function_exists($init)) { + $init($a); + } + if (function_exists("theme_admin")) { $admin_form = theme_admin($a); } @@ -1794,9 +1789,9 @@ function admin_page_themes(App $a) { } $screenshot = array(get_theme_screenshot($theme), t('Screenshot')); - if(! stristr($screenshot[0],$theme)) + if (! stristr($screenshot[0],$theme)) { $screenshot = null; - + } $t = get_markup_template("admin_plugins_details.tpl"); return replace_macros($t, array( @@ -1842,7 +1837,7 @@ function admin_page_themes(App $a) { $xthemes = array(); if ($themes) { - foreach($themes as $th) { + foreach ($themes as $th) { $xthemes[] = array($th['name'],(($th['allowed']) ? "on" : "off"), get_theme_info($th['name'])); } } @@ -1967,25 +1962,25 @@ function admin_page_viewlogs(App $a) { $f = get_config('system','logfile'); $data = ''; - if(!file_exists($f)) { + if (!file_exists($f)) { $data = t("Error trying to open $f log file.\r\n
    Check to see if file $f exist and is readable."); - } - else { + } else { $fp = fopen($f, 'r'); - if(!$fp) { + if (!$fp) { $data = t("Couldn't open $f log file.\r\n
    Check to see if file $f is readable."); - } - else { + } else { $fstat = fstat($fp); $size = $fstat['size']; - if($size != 0) { - if($size > 5000000 || $size < 0) + if ($size != 0) { + if ($size > 5000000 || $size < 0) { $size = 5000000; + } $seek = fseek($fp,0-$size,SEEK_END); - if($seek === 0) { + if ($seek === 0) { $data = escape_tags(fread($fp,$size)); - while(! feof($fp)) + while (! feof($fp)) { $data .= escape_tags(fread($fp,4096)); + } } } fclose($fp); @@ -2013,22 +2008,24 @@ function admin_page_features_post(App $a) { $arr = array(); $features = get_features(false); - foreach($features as $fname => $fdata) { - foreach(array_slice($fdata,1) as $f) { + foreach ($features as $fname => $fdata) { + foreach (array_slice($fdata,1) as $f) { $feature = $f[0]; $feature_state = 'feature_'.$feature; $featurelock = 'featurelock_'.$feature; - if(x($_POST[$feature_state])) + if (x($_POST[$feature_state])) { $val = intval($_POST['feature_'.$feature]); - else + } else { $val = 0; + } set_config('feature',$feature,$val); - if(x($_POST[$featurelock])) + if (x($_POST[$featurelock])) { set_config('feature_lock',$feature,$val); - else + } else { del_config('feature_lock',$feature); + } } } @@ -2052,18 +2049,19 @@ function admin_page_features_post(App $a) { */ function admin_page_features(App $a) { - if((argc() > 1) && (argv(1) === 'features')) { + if ((argc() > 1) && (argv(1) === 'features')) { $arr = array(); $features = get_features(false); - foreach($features as $fname => $fdata) { + foreach ($features as $fname => $fdata) { $arr[$fname] = array(); $arr[$fname][0] = $fdata[0]; - foreach(array_slice($fdata,1) as $f) { + foreach (array_slice($fdata,1) as $f) { $set = get_config('feature',$f[0]); - if($set === false) + if ($set === false) { $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'))) diff --git a/mod/contacts.php b/mod/contacts.php index a2a77e2a5c..f2500099c3 100644 --- a/mod/contacts.php +++ b/mod/contacts.php @@ -534,13 +534,13 @@ function contacts_content(App $a) { $insecure = t('Private communications are not available for this contact.'); - $last_update = (($contact['last-update'] == '0000-00-00 00:00:00') + $last_update = (($contact['last-update'] <= NULL_DATE) ? t('Never') : datetime_convert('UTC',date_default_timezone_get(),$contact['last-update'],'D, j M Y, g:i A')); - if($contact['last-update'] !== '0000-00-00 00:00:00') + if ($contact['last-update'] > NULL_DATE) { $last_update .= ' ' . (($contact['last-update'] <= $contact['success_update']) ? t("\x28Update was successful\x29") : t("\x28Update was not successful\x29")); - + } $lblsuggest = (($contact['network'] === NETWORK_DFRN) ? t('Suggest friends') : ''); $poll_enabled = in_array($contact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_FEED, NETWORK_MAIL, NETWORK_MAIL2)); @@ -558,12 +558,12 @@ function contacts_content(App $a) { // tabs $tab_str = contacts_tab($a, $contact_id, 2); - $lost_contact = (($contact['archive'] && $contact['term-date'] != '0000-00-00 00:00:00' && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : ''); + $lost_contact = (($contact['archive'] && $contact['term-date'] > NULL_DATE && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : ''); - if ($contact['network'] == NETWORK_FEED) + if ($contact['network'] == NETWORK_FEED) { $fetch_further_information = array('fetch_further_information', t('Fetch further information for feeds'), $contact['fetch_further_information'], t('Fetch further information for feeds'), array('0'=>t('Disabled'), '1'=>t('Fetch information'), '2'=>t('Fetch information and keywords'))); - + } if (in_array($contact['network'], array(NETWORK_FEED, NETWORK_MAIL, NETWORK_MAIL2))) $poll_interval = contact_poll_interval($contact['priority'],(! $poll_enabled)); diff --git a/mod/events.php b/mod/events.php index ac0c444cb5..60e7b9f390 100644 --- a/mod/events.php +++ b/mod/events.php @@ -1,12 +1,12 @@ argc == 1) { - // if it's a json request abort here becaus we don't + // If it's a json request abort here because we don't // need the widget data - if ($a->argv[1] === 'json') + if ($a->argv[1] === 'json') { return; + } $cal_widget = widget_events(); @@ -33,17 +34,17 @@ function events_init(App $a) { function events_post(App $a) { - logger('post: ' . print_r($_REQUEST,true)); + logger('post: ' . print_r($_REQUEST, true), LOGGER_DATA); if (! local_user()) { return; } - $event_id = ((x($_POST,'event_id')) ? intval($_POST['event_id']) : 0); - $cid = ((x($_POST,'cid')) ? intval($_POST['cid']) : 0); - $uid = local_user(); + $event_id = ((x($_POST, 'event_id')) ? intval($_POST['event_id']) : 0); + $cid = ((x($_POST, 'cid')) ? intval($_POST['cid']) : 0); + $uid = local_user(); - $start_text = escape_tags($_REQUEST['start_text']); + $start_text = escape_tags($_REQUEST['start_text']); $finish_text = escape_tags($_REQUEST['finish_text']); $adjust = intval($_POST['adjust']); @@ -52,34 +53,26 @@ function events_post(App $a) { // The default setting for the `private` field in event_store() is false, so mirror that $private_event = false; + $start = NULL_DATE; + $finish = NULL_DATE; + if ($start_text) { $start = $start_text; } - else { - $start = sprintf('%d-%d-%d %d:%d:0',$startyear,$startmonth,$startday,$starthour,$startminute); - } - - if ($nofinish) { - $finish = '0000-00-00 00:00:00'; - } if ($finish_text) { $finish = $finish_text; } - else { - $finish = sprintf('%d-%d-%d %d:%d:0',$finishyear,$finishmonth,$finishday,$finishhour,$finishminute); - } if ($adjust) { - $start = datetime_convert(date_default_timezone_get(),'UTC',$start); + $start = datetime_convert(date_default_timezone_get(), 'UTC', $start); if (! $nofinish) { - $finish = datetime_convert(date_default_timezone_get(),'UTC',$finish); + $finish = datetime_convert(date_default_timezone_get(), 'UTC', $finish); } - } - else { - $start = datetime_convert('UTC','UTC',$start); + } else { + $start = datetime_convert('UTC', 'UTC', $start); if (! $nofinish) { - $finish = datetime_convert('UTC','UTC',$finish); + $finish = datetime_convert('UTC', 'UTC', $finish); } } @@ -96,19 +89,19 @@ function events_post(App $a) { $action = ($event_id == '') ? 'new' : "event/" . $event_id; $onerror_url = App::get_baseurl() . "/events/" . $action . "?summary=$summary&description=$desc&location=$location&start=$start_text&finish=$finish_text&adjust=$adjust&nofinish=$nofinish"; - if (strcmp($finish,$start) < 0 && !$nofinish) { - notice( t('Event can not end before it has started.') . EOL); + if (strcmp($finish, $start) < 0 && !$nofinish) { + notice(t('Event can not end before it has started.') . EOL); if (intval($_REQUEST['preview'])) { - echo( t('Event can not end before it has started.')); + echo t('Event can not end before it has started.'); killme(); } goaway($onerror_url); } - if((! $summary) || (! $start)) { - notice( t('Event title and start time are required.') . EOL); - if(intval($_REQUEST['preview'])) { - echo( t('Event title and start time are required.')); + if ((! $summary) || ($start === NULL_DATE)) { + notice(t('Event title and start time are required.') . EOL); + if (intval($_REQUEST['preview'])) { + echo t('Event title and start time are required.'); killme(); } goaway($onerror_url); @@ -116,35 +109,33 @@ function events_post(App $a) { $share = ((intval($_POST['share'])) ? intval($_POST['share']) : 0); - $c = q("select id from contact where uid = %d and self = 1 limit 1", + $c = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval(local_user()) ); - if(count($c)) + if (count($c)) { $self = $c[0]['id']; - else + } else { $self = 0; + } - if($share) { + if ($share) { $str_group_allow = perms2str($_POST['group_allow']); $str_contact_allow = perms2str($_POST['contact_allow']); $str_group_deny = perms2str($_POST['group_deny']); $str_contact_deny = perms2str($_POST['contact_deny']); // Undo the pseudo-contact of self, since there are real contacts now - if( strpos($str_contact_allow, '<' . $self . '>') !== false ) - { + if (strpos($str_contact_allow, '<' . $self . '>') !== false ) { $str_contact_allow = str_replace('<' . $self . '>', '', $str_contact_allow); } // Make sure to set the `private` field as true. This is necessary to // have the posts show up correctly in Diaspora if an event is created // as visible only to self at first, but then edited to display to others. - if( strlen($str_group_allow) or strlen($str_contact_allow) or strlen($str_group_deny) or strlen($str_contact_deny) ) - { + if (strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) { $private_event = true; } - } - else { + } else { // Note: do not set `private` field for self-only events. It will // keep even you from seeing them! $str_contact_allow = '<' . $self . '>'; @@ -153,46 +144,45 @@ function events_post(App $a) { $datarray = array(); - $datarray['guid'] = get_guid(32); - $datarray['start'] = $start; - $datarray['finish'] = $finish; - $datarray['summary'] = $summary; - $datarray['desc'] = $desc; - $datarray['location'] = $location; - $datarray['type'] = $type; - $datarray['adjust'] = $adjust; - $datarray['nofinish'] = $nofinish; - $datarray['uid'] = $uid; - $datarray['cid'] = $cid; + $datarray['guid'] = get_guid(32); + $datarray['start'] = $start; + $datarray['finish'] = $finish; + $datarray['summary'] = $summary; + $datarray['desc'] = $desc; + $datarray['location'] = $location; + $datarray['type'] = $type; + $datarray['adjust'] = $adjust; + $datarray['nofinish'] = $nofinish; + $datarray['uid'] = $uid; + $datarray['cid'] = $cid; $datarray['allow_cid'] = $str_contact_allow; $datarray['allow_gid'] = $str_group_allow; - $datarray['deny_cid'] = $str_contact_deny; - $datarray['deny_gid'] = $str_group_deny; - $datarray['private'] = (($private_event) ? 1 : 0); - $datarray['id'] = $event_id; - $datarray['created'] = $created; - $datarray['edited'] = $edited; + $datarray['deny_cid'] = $str_contact_deny; + $datarray['deny_gid'] = $str_group_deny; + $datarray['private'] = (($private_event) ? 1 : 0); + $datarray['id'] = $event_id; + $datarray['created'] = $created; + $datarray['edited'] = $edited; - if(intval($_REQUEST['preview'])) { + if (intval($_REQUEST['preview'])) { $html = format_event_html($datarray); echo $html; - killme(); + killme(); } $item_id = event_store($datarray); - if(! $cid) + if (! $cid) { proc_run(PRIORITY_HIGH, "include/notifier.php", "event", $item_id); + } goaway($_SESSION['return_url']); } - - function events_content(App $a) { if (! local_user()) { - notice( t('Permission denied.') . EOL); + notice(t('Permission denied.') . EOL); return; } @@ -201,14 +191,14 @@ function events_content(App $a) { } if (($a->argc > 2) && ($a->argv[1] === 'ignore') && intval($a->argv[2])) { - $r = q("update event set ignore = 1 where id = %d and uid = %d", + $r = q("UPDATE `event` SET `ignore` = 1 WHERE `id` = %d AND `uid` = %d", intval($a->argv[2]), intval(local_user()) ); } if (($a->argc > 2) && ($a->argv[1] === 'unignore') && intval($a->argv[2])) { - $r = q("update event set ignore = 0 where id = %d and uid = %d", + $r = q("UPDATE `event` SET `ignore` = 0 WHERE `id` = %d AND `uid` = %d", intval($a->argv[2]), intval(local_user()) ); @@ -224,7 +214,7 @@ function events_content(App $a) { $i18n = get_event_strings(); $htpl = get_markup_template('event_head.tpl'); - $a->page['htmlhead'] .= replace_macros($htpl,array( + $a->page['htmlhead'] .= replace_macros($htpl, array( '$baseurl' => App::get_baseurl(), '$module_url' => '/events', '$modparams' => 1, @@ -232,27 +222,30 @@ function events_content(App $a) { )); $etpl = get_markup_template('event_end.tpl'); - $a->page['end'] .= replace_macros($etpl,array( + $a->page['end'] .= replace_macros($etpl, array( '$baseurl' => App::get_baseurl(), )); - $o =""; + $o = ''; // tabs - if ($a->theme_events_in_profile) - $tabs = profile_tabs($a, True); - - + if ($a->theme_events_in_profile) { + $tabs = profile_tabs($a, true); + } $mode = 'view'; $y = 0; $m = 0; - $ignored = ((x($_REQUEST,'ignored')) ? intval($_REQUEST['ignored']) : 0); + $ignored = ((x($_REQUEST, 'ignored')) ? intval($_REQUEST['ignored']) : 0); - if($a->argc > 1) { + if ($a->argc > 1) { if ($a->argc > 2 && $a->argv[1] == 'event') { $mode = 'edit'; $event_id = intval($a->argv[2]); } + if ($a->argc > 2 && $a->argv[1] == 'drop') { + $mode = 'drop'; + $event_id = intval($a->argv[2]); + } if ($a->argv[1] === 'new') { $mode = 'new'; $event_id = 0; @@ -267,9 +260,8 @@ function events_content(App $a) { // The view mode part is similiar to /mod/cal.php if ($mode == 'view') { - - $thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y'); - $thismonth = datetime_convert('UTC',date_default_timezone_get(),'now','m'); + $thisyear = datetime_convert('UTC', date_default_timezone_get(), 'now', 'Y'); + $thismonth = datetime_convert('UTC', date_default_timezone_get(), 'now', 'm'); if (! $y) { $y = intval($thisyear); } @@ -289,47 +281,47 @@ function events_content(App $a) { $nextyear = $y; $nextmonth = $m + 1; - if($nextmonth > 12) { - $nextmonth = 1; + if ($nextmonth > 12) { + $nextmonth = 1; $nextyear ++; } $prevyear = $y; - if($m > 1) + if ($m > 1) { $prevmonth = $m - 1; - else { + } else { $prevmonth = 12; $prevyear --; } - $dim = get_dim($y,$m); - $start = sprintf('%d-%d-%d %d:%d:%d',$y,$m,1,0,0,0); - $finish = sprintf('%d-%d-%d %d:%d:%d',$y,$m,$dim,23,59,59); + $dim = get_dim($y, $m); + $start = sprintf('%d-%d-%d %d:%d:%d', $y, $m, 1, 0, 0, 0); + $finish = sprintf('%d-%d-%d %d:%d:%d', $y, $m, $dim, 23, 59, 59); - if ($a->argv[1] === 'json'){ - if (x($_GET,'start')) $start = $_GET['start']; - if (x($_GET,'end')) $finish = $_GET['end']; + if ($a->argv[1] === 'json') { + if (x($_GET, 'start')) {$start = $_GET['start'];} + if (x($_GET, 'end')) {$finish = $_GET['end'];} } - $start = datetime_convert('UTC','UTC',$start); - $finish = datetime_convert('UTC','UTC',$finish); + $start = datetime_convert('UTC', 'UTC', $start); + $finish = datetime_convert('UTC', 'UTC', $finish); - $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); + $adjust_start = datetime_convert('UTC', date_default_timezone_get(), $start); $adjust_finish = datetime_convert('UTC', date_default_timezone_get(), $finish); // put the event parametes in an array so we can better transmit them $event_params = array( - 'event_id' => (x($_GET,'id') ? $_GET["id"] : 0), - 'start' => $start, - 'finish' => $finish, - 'adjust_start' => $adjust_start, + 'event_id' => (x($_GET, 'id') ? $_GET['id'] : 0), + 'start' => $start, + 'finish' => $finish, + 'adjust_start' => $adjust_start, 'adjust_finish' => $adjust_finish, - 'ignored' => $ignored, + 'ignored' => $ignored, ); // get events by id or by date - if (x($_GET,'id')){ + if (x($_GET, 'id')) { $r = event_by_id(local_user(), $event_params); } else { $r = events_by_date(local_user(), $event_params); @@ -340,7 +332,7 @@ function events_content(App $a) { if (dbm::is_result($r)) { $r = sort_by_date($r); foreach ($r as $rr) { - $j = (($rr['adjust']) ? datetime_convert('UTC',date_default_timezone_get(),$rr['start'], 'j') : datetime_convert('UTC','UTC',$rr['start'],'j')); + $j = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['start'], 'j') : datetime_convert('UTC', 'UTC', $rr['start'], 'j')); if (! x($links,$j)) { $links[$j] = App::get_baseurl() . '/' . $a->cmd . '#link-' . $j; } @@ -356,127 +348,127 @@ function events_content(App $a) { } if ($a->argv[1] === 'json'){ - echo json_encode($events); killme(); + echo json_encode($events); + killme(); } - // links: array('href', 'text', 'extra css classes', 'title') - if (x($_GET,'id')){ + if (x($_GET, 'id')) { $tpl = get_markup_template("event.tpl"); } else { -// if (get_config('experimentals','new_calendar')==1){ - $tpl = get_markup_template("events_js.tpl"); -// } else { -// $tpl = get_markup_template("events.tpl"); -// } + $tpl = get_markup_template("events_js.tpl"); } // Get rid of dashes in key names, Smarty3 can't handle them - foreach($events as $key => $event) { + foreach ($events as $key => $event) { $event_item = array(); - foreach($event['item'] as $k => $v) { - $k = str_replace('-','_',$k); + foreach ($event['item'] as $k => $v) { + $k = str_replace('-' ,'_', $k); $event_item[$k] = $v; } $events[$key]['item'] = $event_item; } $o = replace_macros($tpl, array( - '$baseurl' => App::get_baseurl(), - '$tabs' => $tabs, - '$title' => t('Events'), - '$view' => t('View'), - '$new_event' => array(App::get_baseurl().'/events/new',t('Create New Event'),'',''), - '$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'), + '$baseurl' => App::get_baseurl(), + '$tabs' => $tabs, + '$title' => t('Events'), + '$view' => t('View'), + '$new_event' => array(App::get_baseurl() . '/events/new', t('Create New Event'), '', ''), + '$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, + '$events' => $events, - "today" => t("today"), - "month" => t("month"), - "week" => t("week"), - "day" => t("day"), - "list" => t("list"), + '$today' => t('today'), + '$month' => t('month'), + '$week' => t('week'), + '$day' => t('day'), + '$list' => t('list'), )); - if (x($_GET,'id')){ echo $o; killme(); } + if (x($_GET, 'id')) { + echo $o; + killme(); + } return $o; - } - if($mode === 'edit' && $event_id) { + if ($mode === 'edit' && $event_id) { $r = q("SELECT * FROM `event` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($event_id), intval(local_user()) ); - if (dbm::is_result($r)) + if (dbm::is_result($r)) { $orig_event = $r[0]; + } } // Passed parameters overrides anything found in the DB - if($mode === 'edit' || $mode === 'new') { - if(!x($orig_event)) $orig_event = array(); + if ($mode === 'edit' || $mode === 'new') { + if (!x($orig_event)) {$orig_event = array();} // In case of an error the browser is redirected back here, with these parameters filled in with the previous values - if(x($_REQUEST,'nofinish')) $orig_event['nofinish'] = $_REQUEST['nofinish']; - if(x($_REQUEST,'adjust')) $orig_event['adjust'] = $_REQUEST['adjust']; - if(x($_REQUEST,'summary')) $orig_event['summary'] = $_REQUEST['summary']; - if(x($_REQUEST,'description')) $orig_event['description'] = $_REQUEST['description']; - if(x($_REQUEST,'location')) $orig_event['location'] = $_REQUEST['location']; - if(x($_REQUEST,'start')) $orig_event['start'] = $_REQUEST['start']; - if(x($_REQUEST,'finish')) $orig_event['finish'] = $_REQUEST['finish']; - } - - if($mode === 'edit' || $mode === 'new') { + if (x($_REQUEST, 'nofinish')) {$orig_event['nofinish'] = $_REQUEST['nofinish'];} + if (x($_REQUEST, 'adjust')) {$orig_event['adjust'] = $_REQUEST['adjust'];} + if (x($_REQUEST, 'summary')) {$orig_event['summary'] = $_REQUEST['summary'];} + if (x($_REQUEST, 'description')) {$orig_event['description'] = $_REQUEST['description'];} + if (x($_REQUEST, 'location')) {$orig_event['location'] = $_REQUEST['location'];} + if (x($_REQUEST, 'start')) {$orig_event['start'] = $_REQUEST['start'];} + if (x($_REQUEST, 'finish')) {$orig_event['finish'] = $_REQUEST['finish'];} $n_checked = ((x($orig_event) && $orig_event['nofinish']) ? ' checked="checked" ' : ''); - $a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : ''); - $t_orig = ((x($orig_event)) ? $orig_event['summary'] : ''); - $d_orig = ((x($orig_event)) ? $orig_event['desc'] : ''); + $a_checked = ((x($orig_event) && $orig_event['adjust']) ? ' checked="checked" ' : ''); + + $t_orig = ((x($orig_event)) ? $orig_event['summary'] : ''); + $d_orig = ((x($orig_event)) ? $orig_event['desc'] : ''); $l_orig = ((x($orig_event)) ? $orig_event['location'] : ''); - $eid = ((x($orig_event)) ? $orig_event['id'] : 0); - $cid = ((x($orig_event)) ? $orig_event['cid'] : 0); - $uri = ((x($orig_event)) ? $orig_event['uri'] : ''); + $eid = ((x($orig_event)) ? $orig_event['id'] : 0); + $cid = ((x($orig_event)) ? $orig_event['cid'] : 0); + $uri = ((x($orig_event)) ? $orig_event['uri'] : ''); - - if(! x($orig_event)) + if (! x($orig_event)) { $sh_checked = ''; - else - $sh_checked = (($orig_event['allow_cid'] === '<' . local_user() . '>' && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" ' ); + } else { + $sh_checked = (($orig_event['allow_cid'] === '<' . local_user() . '>' && (! $orig_event['allow_gid']) && (! $orig_event['deny_cid']) && (! $orig_event['deny_gid'])) ? '' : ' checked="checked" '); + } - if($cid OR ($mode !== 'new')) + if ($cid OR ($mode !== 'new')) { $sh_checked .= ' disabled="disabled" '; - + } $sdt = ((x($orig_event)) ? $orig_event['start'] : 'now'); $fdt = ((x($orig_event)) ? $orig_event['finish'] : 'now'); $tz = date_default_timezone_get(); - if(x($orig_event)) + if (x($orig_event)) { $tz = (($orig_event['adjust']) ? date_default_timezone_get() : 'UTC'); + } - $syear = datetime_convert('UTC', $tz, $sdt, 'Y'); + $syear = datetime_convert('UTC', $tz, $sdt, 'Y'); $smonth = datetime_convert('UTC', $tz, $sdt, 'm'); - $sday = datetime_convert('UTC', $tz, $sdt, 'd'); + $sday = datetime_convert('UTC', $tz, $sdt, 'd'); - $shour = ((x($orig_event)) ? datetime_convert('UTC', $tz, $sdt, 'H') : 0); + $shour = ((x($orig_event)) ? datetime_convert('UTC', $tz, $sdt, 'H') : 0); $sminute = ((x($orig_event)) ? datetime_convert('UTC', $tz, $sdt, 'i') : 0); - $fyear = datetime_convert('UTC', $tz, $fdt, 'Y'); + $fyear = datetime_convert('UTC', $tz, $fdt, 'Y'); $fmonth = datetime_convert('UTC', $tz, $fdt, 'm'); - $fday = datetime_convert('UTC', $tz, $fdt, 'd'); + $fday = datetime_convert('UTC', $tz, $fdt, 'd'); - $fhour = ((x($orig_event)) ? datetime_convert('UTC', $tz, $fdt, 'H') : 0); + $fhour = ((x($orig_event)) ? datetime_convert('UTC', $tz, $fdt, 'H') : 0); $fminute = ((x($orig_event)) ? datetime_convert('UTC', $tz, $fdt, 'i') : 0); $f = get_config('system','event_input_format'); - if(! $f) + if (! $f) { $f = 'ymd'; + } - require_once('include/acl_selectors.php'); + require_once 'include/acl_selectors.php' ; - if ($mode === 'new') + if ($mode === 'new') { $acl = (($cid) ? '' : populate_acl(((x($orig_event)) ? $orig_event : $a->user))); + } $tpl = get_markup_template('event_form.tpl'); @@ -489,11 +481,11 @@ function events_content(App $a) { '$title' => t('Event details'), '$desc' => t('Starting date and Title are required.'), '$s_text' => t('Event Starts:') . ' *', - '$s_dsel' => datetimesel($f,new DateTime(),DateTime::createFromFormat('Y',$syear+5),DateTime::createFromFormat('Y-m-d H:i',"$syear-$smonth-$sday $shour:$sminute"),t('Event Starts:'),'start_text',true,true,'','',true), + '$s_dsel' => datetimesel($f, new DateTime(), DateTime::createFromFormat('Y', $syear+5), DateTime::createFromFormat('Y-m-d H:i', "$syear-$smonth-$sday $shour:$sminute"), t('Event Starts:'), 'start_text', true, true, '', '', true), '$n_text' => t('Finish date/time is not known or not relevant'), '$n_checked' => $n_checked, '$f_text' => t('Event Finishes:'), - '$f_dsel' => datetimesel($f,new DateTime(),DateTime::createFromFormat('Y',$fyear+5),DateTime::createFromFormat('Y-m-d H:i',"$fyear-$fmonth-$fday $fhour:$fminute"),t('Event Finishes:'),'finish_text',true,true,'start_text'), + '$f_dsel' => datetimesel($f, new DateTime(), DateTime::createFromFormat('Y', $fyear+5), DateTime::createFromFormat('Y-m-d H:i', "$fyear-$fmonth-$fday $fhour:$fminute"), t('Event Finishes:'), 'finish_text', true, true, 'start_text'), '$a_text' => t('Adjust for viewer timezone'), '$a_checked' => $a_checked, '$d_text' => t('Description:'), @@ -511,12 +503,33 @@ function events_content(App $a) { '$preview' => t('Preview'), '$acl' => $acl, '$submit' => t('Submit'), - '$basic' => t("Basic"), - '$advanced' => t("Advanced"), + '$basic' => t('Basic'), + '$advanced' => t('Advanced'), '$permissions' => t('Permissions'), )); return $o; } + + // Remove an event from the calendar and its related items + if ($mode === 'drop' && $event_id) { + $del = 0; + + $params = array('event_id' => ($event_id)); + $ev = event_by_id(local_user(), $params); + + // Delete only real events (no birthdays) + if (dbm::is_result($ev) && $ev[0]['type'] == 'event') { + $del = drop_item($ev[0]['itemid'], false); + } + + if ($del == 0) { + notice(t('Failed to remove event' ) . EOL); + } else { + info(t('Event removed') . EOL); + } + + goaway(App::get_baseurl() . '/events'); + } } diff --git a/mod/maintenance.php b/mod/maintenance.php index dcdc44194e..c4839de792 100644 --- a/mod/maintenance.php +++ b/mod/maintenance.php @@ -1,11 +1,23 @@ t('System down for maintenance') + '$sysdown' => t('System down for maintenance'), + '$reason' => $reason )); } diff --git a/mod/poco.php b/mod/poco.php index 4ce075301c..30648acab6 100644 --- a/mod/poco.php +++ b/mod/poco.php @@ -7,14 +7,14 @@ function poco_init(App $a) { $system_mode = false; - if(intval(get_config('system','block_public')) || (get_config('system','block_local_dir'))) + if (intval(get_config('system','block_public')) || (get_config('system','block_local_dir'))) { http_status_exit(401); + } - - if($a->argc > 1) { + if ($a->argc > 1) { $user = notags(trim($a->argv[1])); } - if(! x($user)) { + if (! x($user)) { $c = q("SELECT * FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1"); if (! dbm::is_result($c)) { http_status_exit(401); @@ -27,42 +27,55 @@ function poco_init(App $a) { $justme = false; $global = false; - if($a->argc > 1 && $a->argv[1] === '@global') { + if ($a->argc > 1 && $a->argv[1] === '@server') { + // List of all servers that this server knows + $ret = poco_serverlist(); + header('Content-type: application/json'); + echo json_encode($ret); + killme(); + } + if ($a->argc > 1 && $a->argv[1] === '@global') { + // List of all profiles that this server recently had data from $global = true; $update_limit = date("Y-m-d H:i:s", time() - 30 * 86400); } - if($a->argc > 2 && $a->argv[2] === '@me') + if ($a->argc > 2 && $a->argv[2] === '@me') { $justme = true; - if($a->argc > 3 && $a->argv[3] === '@all') + } + if ($a->argc > 3 && $a->argv[3] === '@all') { $justme = false; - if($a->argc > 3 && $a->argv[3] === '@self') + } + if ($a->argc > 3 && $a->argv[3] === '@self') { $justme = true; - if($a->argc > 4 && intval($a->argv[4]) && $justme == false) + } + if ($a->argc > 4 && intval($a->argv[4]) && $justme == false) { $cid = intval($a->argv[4]); + } - - if(!$system_mode AND !$global) { + if (!$system_mode AND !$global) { $r = q("SELECT `user`.*,`profile`.`hide-friends` from user left join profile on `user`.`uid` = `profile`.`uid` where `user`.`nickname` = '%s' and `profile`.`is-default` = 1 limit 1", dbesc($user) ); - if(! dbm::is_result($r) || $r[0]['hidewall'] || $r[0]['hide-friends']) + if (! dbm::is_result($r) || $r[0]['hidewall'] || $r[0]['hide-friends']) { http_status_exit(404); + } $user = $r[0]; } - if($justme) + if ($justme) { $sql_extra = " AND `contact`.`self` = 1 "; + } // else // $sql_extra = " AND `contact`.`self` = 0 "; - if($cid) + if ($cid) { $sql_extra = sprintf(" AND `contact`.`id` = %d ",intval($cid)); - - if(x($_GET,'updatedSince')) + } + if (x($_GET,'updatedSince')) { $update_limit = date("Y-m-d H:i:s",strtotime($_GET['updatedSince'])); - + } if ($global) { $r = q("SELECT count(*) AS `total` FROM `gcontact` WHERE `updated` >= '%s' AND `updated` >= `last_failure` AND NOT `hide` AND `network` IN ('%s', '%s', '%s')", dbesc($update_limit), @@ -70,7 +83,7 @@ function poco_init(App $a) { dbesc(NETWORK_DIASPORA), dbesc(NETWORK_OSTATUS) ); - } elseif($system_mode) { + } elseif ($system_mode) { $r = q("SELECT count(*) AS `total` FROM `contact` WHERE `self` = 1 AND `uid` IN (SELECT `uid` FROM `pconfig` WHERE `cat` = 'system' AND `k` = 'suggestme' AND `v` = 1) "); } else { @@ -84,14 +97,15 @@ function poco_init(App $a) { dbesc(NETWORK_STATUSNET) ); } - if (dbm::is_result($r)) + if (dbm::is_result($r)) { $totalResults = intval($r[0]['total']); - else + } else { $totalResults = 0; - + } $startIndex = intval($_GET['startIndex']); - if(! $startIndex) + if (! $startIndex) { $startIndex = 0; + } $itemsPerPage = ((x($_GET,'count') && intval($_GET['count'])) ? intval($_GET['count']) : $totalResults); if ($global) { @@ -105,7 +119,7 @@ function poco_init(App $a) { intval($startIndex), intval($itemsPerPage) ); - } elseif($system_mode) { + } elseif ($system_mode) { logger("Start system mode query", LOGGER_DEBUG); $r = q("SELECT `contact`.*, `profile`.`about` AS `pabout`, `profile`.`locality` AS `plocation`, `profile`.`pub_keywords`, `profile`.`gender` AS `pgender`, `profile`.`address` AS `paddress`, `profile`.`region` AS `pregion`, @@ -134,13 +148,15 @@ function poco_init(App $a) { logger("Query done", LOGGER_DEBUG); $ret = array(); - if(x($_GET,'sorted')) + if (x($_GET,'sorted')) { $ret['sorted'] = false; - if(x($_GET,'filtered')) + } + if (x($_GET,'filtered')) { $ret['filtered'] = false; - if(x($_GET,'updatedSince') AND !$global) + } + if (x($_GET,'updatedSince') AND !$global) { $ret['updatedSince'] = false; - + } $ret['startIndex'] = (int) $startIndex; $ret['itemsPerPage'] = (int) $itemsPerPage; $ret['totalResults'] = (int) $totalResults; @@ -164,58 +180,61 @@ function poco_init(App $a) { 'generation' => false ); - if((! x($_GET,'fields')) || ($_GET['fields'] === '@all')) - foreach($fields_ret as $k => $v) + if ((! x($_GET,'fields')) || ($_GET['fields'] === '@all')) { + foreach ($fields_ret as $k => $v) { $fields_ret[$k] = true; - else { + } + } else { $fields_req = explode(',',$_GET['fields']); - foreach($fields_req as $f) + foreach ($fields_req as $f) { $fields_ret[trim($f)] = true; + } } - if(is_array($r)) { + if (is_array($r)) { if (dbm::is_result($r)) { foreach ($r as $rr) { if (!isset($rr['generation'])) { - if ($global) + if ($global) { $rr['generation'] = 3; - elseif ($system_mode) + } elseif ($system_mode) { $rr['generation'] = 1; - else + } else { $rr['generation'] = 2; + } } - if (($rr['about'] == "") AND isset($rr['pabout'])) + if (($rr['about'] == "") AND isset($rr['pabout'])) { $rr['about'] = $rr['pabout']; - + } if ($rr['location'] == "") { - if (isset($rr['plocation'])) + if (isset($rr['plocation'])) { $rr['location'] = $rr['plocation']; - + } if (isset($rr['pregion']) AND ($rr['pregion'] != "")) { - if ($rr['location'] != "") + if ($rr['location'] != "") { $rr['location'] .= ", "; - + } $rr['location'] .= $rr['pregion']; } if (isset($rr['pcountry']) AND ($rr['pcountry'] != "")) { - if ($rr['location'] != "") + if ($rr['location'] != "") { $rr['location'] .= ", "; - + } $rr['location'] .= $rr['pcountry']; } } - if (($rr['gender'] == "") AND isset($rr['pgender'])) + if (($rr['gender'] == "") AND isset($rr['pgender'])) { $rr['gender'] = $rr['pgender']; - - if (($rr['keywords'] == "") AND isset($rr['pub_keywords'])) + } + if (($rr['keywords'] == "") AND isset($rr['pub_keywords'])) { $rr['keywords'] = $rr['pub_keywords']; - - if (isset($rr['account-type'])) + } + if (isset($rr['account-type'])) { $rr['contact-type'] = $rr['account-type']; - + } $about = Cache::get("about:".$rr['updated'].":".$rr['nurl']); if (is_null($about)) { $about = bbcode($rr['about'], false, false); @@ -230,111 +249,122 @@ function poco_init(App $a) { } $entry = array(); - if($fields_ret['id']) + if ($fields_ret['id']) { $entry['id'] = (int)$rr['id']; - if($fields_ret['displayName']) - $entry['displayName'] = $rr['name']; - if($fields_ret['aboutMe']) - $entry['aboutMe'] = $about; - if($fields_ret['currentLocation']) - $entry['currentLocation'] = $rr['location']; - if($fields_ret['gender']) - $entry['gender'] = $rr['gender']; - if($fields_ret['generation']) - $entry['generation'] = (int)$rr['generation']; - if($fields_ret['urls']) { - $entry['urls'] = array(array('value' => $rr['url'], 'type' => 'profile')); - if($rr['addr'] && ($rr['network'] !== NETWORK_MAIL)) - $entry['urls'][] = array('value' => 'acct:' . $rr['addr'], 'type' => 'webfinger'); } - if($fields_ret['preferredUsername']) + if ($fields_ret['displayName']) { + $entry['displayName'] = $rr['name']; + } + if ($fields_ret['aboutMe']) { + $entry['aboutMe'] = $about; + } + if ($fields_ret['currentLocation']) { + $entry['currentLocation'] = $rr['location']; + } + if ($fields_ret['gender']) { + $entry['gender'] = $rr['gender']; + } + if ($fields_ret['generation']) { + $entry['generation'] = (int)$rr['generation']; + } + if ($fields_ret['urls']) { + $entry['urls'] = array(array('value' => $rr['url'], 'type' => 'profile')); + if ($rr['addr'] && ($rr['network'] !== NETWORK_MAIL)) { + $entry['urls'][] = array('value' => 'acct:' . $rr['addr'], 'type' => 'webfinger'); + } + } + if ($fields_ret['preferredUsername']) { $entry['preferredUsername'] = $rr['nick']; - if($fields_ret['updated']) { + } + if ($fields_ret['updated']) { if (!$global) { $entry['updated'] = $rr['success_update']; - if ($rr['name-date'] > $entry['updated']) + if ($rr['name-date'] > $entry['updated']) { $entry['updated'] = $rr['name-date']; - - if ($rr['uri-date'] > $entry['updated']) + } + if ($rr['uri-date'] > $entry['updated']) { $entry['updated'] = $rr['uri-date']; - - if ($rr['avatar-date'] > $entry['updated']) + } + if ($rr['avatar-date'] > $entry['updated']) { $entry['updated'] = $rr['avatar-date']; - } else + } + } else { $entry['updated'] = $rr['updated']; - + } $entry['updated'] = date("c", strtotime($entry['updated'])); } - if($fields_ret['photos']) + if ($fields_ret['photos']) { $entry['photos'] = array(array('value' => $rr['photo'], 'type' => 'profile')); - if($fields_ret['network']) { - $entry['network'] = $rr['network']; - if ($entry['network'] == NETWORK_STATUSNET) - $entry['network'] = NETWORK_OSTATUS; - if (($entry['network'] == "") AND ($rr['self'])) - $entry['network'] = NETWORK_DFRN; } - if($fields_ret['tags']) { + if ($fields_ret['network']) { + $entry['network'] = $rr['network']; + if ($entry['network'] == NETWORK_STATUSNET) { + $entry['network'] = NETWORK_OSTATUS; + } + if (($entry['network'] == "") AND ($rr['self'])) { + $entry['network'] = NETWORK_DFRN; + } + } + if ($fields_ret['tags']) { $tags = str_replace(","," ",$rr['keywords']); $tags = explode(" ", $tags); $cleaned = array(); foreach ($tags as $tag) { $tag = trim(strtolower($tag)); - if ($tag != "") + if ($tag != "") { $cleaned[] = $tag; + } } $entry['tags'] = array($cleaned); } - if($fields_ret['address']) { + if ($fields_ret['address']) { $entry['address'] = array(); // Deactivated. It just reveals too much data. (Although its from the default profile) //if (isset($rr['paddress'])) // $entry['address']['streetAddress'] = $rr['paddress']; - if (isset($rr['plocation'])) + if (isset($rr['plocation'])) { $entry['address']['locality'] = $rr['plocation']; - - if (isset($rr['pregion'])) + } + if (isset($rr['pregion'])) { $entry['address']['region'] = $rr['pregion']; - + } // See above //if (isset($rr['ppostalcode'])) // $entry['address']['postalCode'] = $rr['ppostalcode']; - if (isset($rr['pcountry'])) + if (isset($rr['pcountry'])) { $entry['address']['country'] = $rr['pcountry']; + } } - if($fields_ret['contactType']) + if ($fields_ret['contactType']) { $entry['contactType'] = intval($rr['contact-type']); - + } $ret['entry'][] = $entry; } - } - else + } else { $ret['entry'][] = array(); - } - else + } + } else { http_status_exit(500); - + } logger("End of poco", LOGGER_DEBUG); - if($format === 'xml') { + if ($format === 'xml') { header('Content-type: text/xml'); echo replace_macros(get_markup_template('poco_xml.tpl'),array_xmlify(array('$response' => $ret))); killme(); } - if($format === 'json') { + if ($format === 'json') { header('Content-type: application/json'); echo json_encode($ret); killme(); - } - else + } else { http_status_exit(500); - - + } } diff --git a/mod/profiles.php b/mod/profiles.php index 4c6ff926b6..4e82ceaacd 100644 --- a/mod/profiles.php +++ b/mod/profiles.php @@ -233,11 +233,11 @@ function profiles_post(App $a) { $with = ((x($_POST,'with')) ? notags(trim($_POST['with'])) : ''); - if(! strlen($howlong)) - $howlong = '0000-00-00 00:00:00'; - else + if(! strlen($howlong)) { + $howlong = NULL_DATE; + } else { $howlong = datetime_convert(date_default_timezone_get(),'UTC',$howlong); - + } // linkify the relationship target if applicable $withchanged = false; @@ -721,7 +721,7 @@ function profiles_content(App $a) { '$gender' => gender_selector($r[0]['gender']), '$marital' => marital_selector($r[0]['marital']), '$with' => array('with', t("Who: \x28if applicable\x29"), strip_tags($r[0]['with']), t('Examples: cathy123, Cathy Williams, cathy@example.com')), - '$howlong' => array('howlong', t('Since [date]:'), ($r[0]['howlong'] === '0000-00-00 00:00:00' ? '' : datetime_convert('UTC',date_default_timezone_get(),$r[0]['howlong']))), + '$howlong' => array('howlong', t('Since [date]:'), ($r[0]['howlong'] <= NULL_DATE ? '' : datetime_convert('UTC',date_default_timezone_get(),$r[0]['howlong']))), '$sexual' => sexpref_selector($r[0]['sexual']), '$about' => array('about', t('Tell us about yourself...'), $r[0]['about']), '$xmpp' => array('xmpp', t('XMPP (Jabber) address:'), $r[0]['xmpp'], t("The XMPP address will be propagated to your contacts so that they can follow you.")), diff --git a/mod/settings.php b/mod/settings.php index 32ccaf541a..5c9c439e0a 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -872,7 +872,7 @@ function settings_content(App $a) { $mail_pubmail = ((dbm::is_result($r)) ? $r[0]['pubmail'] : 0); $mail_action = ((dbm::is_result($r)) ? $r[0]['action'] : 0); $mail_movetofolder = ((dbm::is_result($r)) ? $r[0]['movetofolder'] : ''); - $mail_chk = ((dbm::is_result($r)) ? $r[0]['last_check'] : '0000-00-00 00:00:00'); + $mail_chk = ((dbm::is_result($r)) ? $r[0]['last_check'] : NULL_DATE); $tpl = get_markup_template("settings_connectors.tpl"); diff --git a/mod/worker.php b/mod/worker.php index c202a28d64..4949b830f4 100644 --- a/mod/worker.php +++ b/mod/worker.php @@ -10,7 +10,7 @@ use \Friendica\Core\PConfig; function worker_init($a){ - if (!Config::get("system", "frontend_worker") OR !Config::get("system", "worker")) { + if (!Config::get("system", "frontend_worker")) { return; } diff --git a/update.php b/update.php index 64259bbb1d..3bce492682 100644 --- a/update.php +++ b/update.php @@ -1,6 +1,6 @@ 1) +if ($argc > 1) { $maint_mode = intval($argv[1]); -set_config('system', 'maintenance', $maint_mode); +} -if($maint_mode) +Config::set('system', 'maintenance', $maint_mode); + +if ($maint_mode AND ($argc > 2)) { + $reason_arr = $argv; + array_shift($reason_arr); + array_shift($reason_arr); + + $reason = implode(' ', $reason_arr); + Config::set('system', 'maintenance_reason', $reason); +} else { + Config::set('system', 'maintenance_reason', ''); +} + +if ($maint_mode) { $mode_str = "maintenance mode"; -else +} else { $mode_str = "normal mode"; +} + +echo "\n\tSystem set in $mode_str\n"; + +if ($reason != '') { + echo "\tMaintenance reason: $reason\n\n"; +} else { + echo "\n"; +} -echo "\n\tSystem set in $mode_str\n\n"; echo "Usage:\n\n"; -echo "\tphp {$argv[0]} [1]\tSet the system in maintenance mode\n"; -echo "\tphp {$argv[0]} 0 \tSet the system in normal mode\n\n"; - +echo "\tphp {$argv[0]} [1] [Maintenance reason|redirection url]\n"; +echo "\t\tSet the system in maintenance mode\n\n"; +echo "\t\tIf the optionally entered maintenance reason is an url\n"; +echo "\t\tthe visitor is redirected to that page.\n"; +echo "\n"; +echo "\t\tExamples:\n"; +echo "\t\t\tphp {$argv[0]} 1 System upgrade\n"; +echo "\t\t\tphp {$argv[0]} 1 http://domain.tld/downtime\n"; +echo "\n"; +echo "\tphp {$argv[0]} 0\n"; +echo "\t\tSet the system in normal mode\n\n"; diff --git a/util/messages.po b/util/messages.po index 150e2efaa0..4fcfa9b16b 100644 --- a/util/messages.po +++ b/util/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-03-03 10:29+0100\n" +"POT-Creation-Date: 2017-03-20 08:24+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,238 +18,132 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" -#: include/profile_selectors.php:6 -msgid "Male" +#: boot.php:976 +msgid "Delete this item?" msgstr "" -#: include/profile_selectors.php:6 -msgid "Female" +#: boot.php:977 include/ForumManager.php:119 include/contact_widgets.php:253 +#: include/items.php:2254 mod/content.php:624 object/Item.php:420 +#: view/theme/vier/theme.php:255 +msgid "show more" msgstr "" -#: include/profile_selectors.php:6 -msgid "Currently Male" +#: boot.php:978 +msgid "show fewer" msgstr "" -#: include/profile_selectors.php:6 -msgid "Currently Female" +#: boot.php:1667 +#, php-format +msgid "Update %s failed. See error logs." msgstr "" -#: include/profile_selectors.php:6 -msgid "Mostly Male" +#: boot.php:1779 +msgid "Create a New Account" msgstr "" -#: include/profile_selectors.php:6 -msgid "Mostly Female" +#: boot.php:1780 include/nav.php:109 mod/register.php:289 +msgid "Register" msgstr "" -#: include/profile_selectors.php:6 -msgid "Transgender" +#: boot.php:1804 include/nav.php:78 view/theme/frio/theme.php:243 +msgid "Logout" msgstr "" -#: include/profile_selectors.php:6 -msgid "Intersex" +#: boot.php:1805 include/nav.php:95 mod/bookmarklet.php:12 +msgid "Login" msgstr "" -#: include/profile_selectors.php:6 -msgid "Transsexual" +#: boot.php:1807 mod/lostpass.php:161 +msgid "Nickname or Email: " msgstr "" -#: include/profile_selectors.php:6 -msgid "Hermaphrodite" +#: boot.php:1808 +msgid "Password: " msgstr "" -#: include/profile_selectors.php:6 -msgid "Neuter" +#: boot.php:1809 +msgid "Remember me" msgstr "" -#: include/profile_selectors.php:6 -msgid "Non-specific" +#: boot.php:1812 +msgid "Or login using OpenID: " msgstr "" -#: include/profile_selectors.php:6 -msgid "Other" +#: boot.php:1818 +msgid "Forgot your password?" msgstr "" -#: include/profile_selectors.php:6 include/conversation.php:1478 -msgid "Undecided" -msgid_plural "Undecided" -msgstr[0] "" -msgstr[1] "" - -#: include/profile_selectors.php:23 -msgid "Males" +#: boot.php:1819 mod/lostpass.php:110 +msgid "Password Reset" msgstr "" -#: include/profile_selectors.php:23 -msgid "Females" +#: boot.php:1821 +msgid "Website Terms of Service" msgstr "" -#: include/profile_selectors.php:23 -msgid "Gay" +#: boot.php:1822 +msgid "terms of service" msgstr "" -#: include/profile_selectors.php:23 -msgid "Lesbian" +#: boot.php:1824 +msgid "Website Privacy Policy" msgstr "" -#: include/profile_selectors.php:23 -msgid "No Preference" +#: boot.php:1825 +msgid "privacy policy" msgstr "" -#: include/profile_selectors.php:23 -msgid "Bisexual" +#: include/Contact.php:387 include/Contact.php:400 include/Contact.php:445 +#: include/conversation.php:970 include/conversation.php:986 +#: mod/allfriends.php:68 mod/directory.php:157 mod/dirfind.php:209 +#: mod/match.php:73 mod/suggest.php:82 +msgid "View Profile" msgstr "" -#: include/profile_selectors.php:23 -msgid "Autosexual" +#: include/Contact.php:401 include/contact_widgets.php:32 +#: include/conversation.php:983 mod/allfriends.php:69 mod/contacts.php:610 +#: mod/dirfind.php:210 mod/follow.php:106 mod/match.php:74 mod/suggest.php:83 +msgid "Connect/Follow" msgstr "" -#: include/profile_selectors.php:23 -msgid "Abstinent" +#: include/Contact.php:444 include/conversation.php:969 +msgid "View Status" msgstr "" -#: include/profile_selectors.php:23 -msgid "Virgin" +#: include/Contact.php:446 include/conversation.php:971 +msgid "View Photos" msgstr "" -#: include/profile_selectors.php:23 -msgid "Deviant" +#: include/Contact.php:447 include/conversation.php:972 +msgid "Network Posts" msgstr "" -#: include/profile_selectors.php:23 -msgid "Fetish" +#: include/Contact.php:448 include/conversation.php:973 +msgid "View Contact" msgstr "" -#: include/profile_selectors.php:23 -msgid "Oodles" +#: include/Contact.php:449 +msgid "Drop Contact" msgstr "" -#: include/profile_selectors.php:23 -msgid "Nonsexual" +#: include/Contact.php:450 include/conversation.php:974 +msgid "Send PM" msgstr "" -#: include/profile_selectors.php:42 -msgid "Single" +#: include/Contact.php:451 include/conversation.php:978 +msgid "Poke" msgstr "" -#: include/profile_selectors.php:42 -msgid "Lonely" +#: include/Contact.php:828 +msgid "Organisation" msgstr "" -#: include/profile_selectors.php:42 -msgid "Available" +#: include/Contact.php:831 +msgid "News" msgstr "" -#: include/profile_selectors.php:42 -msgid "Unavailable" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Has crush" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Infatuated" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Dating" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Unfaithful" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Sex Addict" -msgstr "" - -#: include/profile_selectors.php:42 include/user.php:280 include/user.php:284 -msgid "Friends" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Friends/Benefits" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Casual" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Engaged" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Married" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Imaginarily married" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Partners" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Cohabiting" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Common law" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Happy" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Not looking" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Swinger" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Betrayed" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Separated" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Unstable" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Divorced" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Imaginarily divorced" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Widowed" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Uncertain" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "It's complicated" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Don't care" -msgstr "" - -#: include/profile_selectors.php:42 -msgid "Ask me" +#: include/Contact.php:834 +msgid "Forum" msgstr "" #: include/ForumManager.php:114 include/nav.php:131 include/text.php:1027 @@ -261,23 +155,17 @@ msgstr "" msgid "External link to forum" msgstr "" -#: include/ForumManager.php:119 include/contact_widgets.php:253 -#: include/items.php:2254 mod/content.php:624 object/Item.php:447 -#: view/theme/vier/theme.php:255 boot.php:971 -msgid "show more" -msgstr "" - #: include/NotificationsManager.php:153 msgid "System" msgstr "" -#: include/NotificationsManager.php:160 include/nav.php:158 mod/admin.php:412 +#: include/NotificationsManager.php:160 include/nav.php:158 mod/admin.php:421 #: view/theme/frio/theme.php:253 msgid "Network" msgstr "" -#: include/NotificationsManager.php:167 mod/profiles.php:695 -#: mod/network.php:846 +#: include/NotificationsManager.php:167 mod/network.php:829 +#: mod/profiles.php:695 msgid "Personal" msgstr "" @@ -348,24 +236,101 @@ msgstr "" msgid "Wall Photos" msgstr "" +#: include/acl_selectors.php:341 +msgid "Post to Email" +msgstr "" + +#: include/acl_selectors.php:346 +#, php-format +msgid "Connectors disabled, since \"%s\" is enabled." +msgstr "" + +#: include/acl_selectors.php:347 mod/settings.php:1188 +msgid "Hide your profile details from unknown viewers?" +msgstr "" + +#: include/acl_selectors.php:352 +msgid "Visible to everybody" +msgstr "" + +#: include/acl_selectors.php:353 view/theme/vier/config.php:108 +msgid "show" +msgstr "" + +#: include/acl_selectors.php:354 view/theme/vier/config.php:108 +msgid "don't show" +msgstr "" + +#: include/acl_selectors.php:360 mod/editpost.php:123 +msgid "CC: email addresses" +msgstr "" + +#: include/acl_selectors.php:361 mod/editpost.php:130 +msgid "Example: bob@example.com, mary@example.com" +msgstr "" + +#: include/acl_selectors.php:363 mod/events.php:516 mod/photos.php:1176 +#: mod/photos.php:1558 +msgid "Permissions" +msgstr "" + +#: include/acl_selectors.php:364 +msgid "Close" +msgstr "" + +#: include/api.php:1021 +#, php-format +msgid "Daily posting limit of %d posts reached. The post was rejected." +msgstr "" + +#: include/api.php:1041 +#, php-format +msgid "Weekly posting limit of %d posts reached. The post was rejected." +msgstr "" + +#: include/api.php:1062 +#, php-format +msgid "Monthly posting limit of %d posts reached. The post was rejected." +msgstr "" + #: include/auth.php:45 msgid "Logged out." msgstr "" -#: include/auth.php:116 include/auth.php:177 mod/openid.php:110 +#: include/auth.php:116 include/auth.php:178 mod/openid.php:110 msgid "Login failed." msgstr "" -#: include/auth.php:131 include/user.php:75 +#: include/auth.php:132 include/user.php:75 msgid "" "We encountered a problem while logging in with the OpenID you provided. " "Please check the correct spelling of the ID." msgstr "" -#: include/auth.php:131 include/user.php:75 +#: include/auth.php:132 include/user.php:75 msgid "The error message was:" msgstr "" +#: include/bb2diaspora.php:199 include/event.php:16 mod/localtime.php:12 +msgid "l F d, Y \\@ g:i A" +msgstr "" + +#: include/bb2diaspora.php:205 include/event.php:33 include/event.php:51 +#: include/event.php:488 +msgid "Starts:" +msgstr "" + +#: include/bb2diaspora.php:213 include/event.php:36 include/event.php:57 +#: include/event.php:489 +msgid "Finishes:" +msgstr "" + +#: include/bb2diaspora.php:221 include/event.php:39 include/event.php:63 +#: include/event.php:490 include/identity.php:331 mod/contacts.php:636 +#: mod/directory.php:139 mod/events.php:501 mod/notifications.php:238 +msgid "Location:" +msgstr "" + #: include/bbcode.php:350 include/bbcode.php:1055 include/bbcode.php:1056 msgid "Image/photo" msgstr "" @@ -383,19 +348,789 @@ msgstr "" msgid "Encrypted content" msgstr "" -#: include/bbcode.php:1167 +#: include/bbcode.php:1169 msgid "Invalid source protocol" msgstr "" -#: include/bbcode.php:1177 +#: include/bbcode.php:1179 msgid "Invalid link protocol" msgstr "" -#: include/dba_pdo.php:72 include/dba.php:56 +#: include/contact_selectors.php:32 +msgid "Unknown | Not categorised" +msgstr "" + +#: include/contact_selectors.php:33 +msgid "Block immediately" +msgstr "" + +#: include/contact_selectors.php:34 +msgid "Shady, spammer, self-marketer" +msgstr "" + +#: include/contact_selectors.php:35 +msgid "Known to me, but no opinion" +msgstr "" + +#: include/contact_selectors.php:36 +msgid "OK, probably harmless" +msgstr "" + +#: include/contact_selectors.php:37 +msgid "Reputable, has my trust" +msgstr "" + +#: include/contact_selectors.php:56 mod/admin.php:893 +msgid "Frequently" +msgstr "" + +#: include/contact_selectors.php:57 mod/admin.php:894 +msgid "Hourly" +msgstr "" + +#: include/contact_selectors.php:58 mod/admin.php:895 +msgid "Twice daily" +msgstr "" + +#: include/contact_selectors.php:59 mod/admin.php:896 +msgid "Daily" +msgstr "" + +#: include/contact_selectors.php:60 +msgid "Weekly" +msgstr "" + +#: include/contact_selectors.php:61 +msgid "Monthly" +msgstr "" + +#: include/contact_selectors.php:76 mod/dfrn_request.php:881 +msgid "Friendica" +msgstr "" + +#: include/contact_selectors.php:77 +msgid "OStatus" +msgstr "" + +#: include/contact_selectors.php:78 +msgid "RSS/Atom" +msgstr "" + +#: include/contact_selectors.php:79 include/contact_selectors.php:86 +#: mod/admin.php:1405 mod/admin.php:1418 mod/admin.php:1431 mod/admin.php:1449 +msgid "Email" +msgstr "" + +#: include/contact_selectors.php:80 mod/dfrn_request.php:883 +#: mod/settings.php:848 +msgid "Diaspora" +msgstr "" + +#: include/contact_selectors.php:81 +msgid "Facebook" +msgstr "" + +#: include/contact_selectors.php:82 +msgid "Zot!" +msgstr "" + +#: include/contact_selectors.php:83 +msgid "LinkedIn" +msgstr "" + +#: include/contact_selectors.php:84 +msgid "XMPP/IM" +msgstr "" + +#: include/contact_selectors.php:85 +msgid "MySpace" +msgstr "" + +#: include/contact_selectors.php:87 +msgid "Google+" +msgstr "" + +#: include/contact_selectors.php:88 +msgid "pump.io" +msgstr "" + +#: include/contact_selectors.php:89 +msgid "Twitter" +msgstr "" + +#: include/contact_selectors.php:90 +msgid "Diaspora Connector" +msgstr "" + +#: include/contact_selectors.php:91 +msgid "GNU Social" +msgstr "" + +#: include/contact_selectors.php:92 +msgid "pnut" +msgstr "" + +#: include/contact_selectors.php:93 +msgid "App.net" +msgstr "" + +#: include/contact_selectors.php:104 +msgid "Hubzilla/Redmatrix" +msgstr "" + +#: include/contact_widgets.php:6 +msgid "Add New Contact" +msgstr "" + +#: include/contact_widgets.php:7 +msgid "Enter address or web location" +msgstr "" + +#: include/contact_widgets.php:8 +msgid "Example: bob@example.com, http://example.com/barbara" +msgstr "" + +#: include/contact_widgets.php:10 include/identity.php:219 +#: mod/allfriends.php:85 mod/dirfind.php:207 mod/match.php:89 +#: mod/suggest.php:101 +msgid "Connect" +msgstr "" + +#: include/contact_widgets.php:24 +#, php-format +msgid "%d invitation available" +msgid_plural "%d invitations available" +msgstr[0] "" +msgstr[1] "" + +#: include/contact_widgets.php:30 +msgid "Find People" +msgstr "" + +#: include/contact_widgets.php:31 +msgid "Enter name or interest" +msgstr "" + +#: include/contact_widgets.php:33 +msgid "Examples: Robert Morgenstein, Fishing" +msgstr "" + +#: include/contact_widgets.php:34 mod/contacts.php:806 mod/directory.php:206 +msgid "Find" +msgstr "" + +#: include/contact_widgets.php:35 mod/suggest.php:114 +#: view/theme/vier/theme.php:198 +msgid "Friend Suggestions" +msgstr "" + +#: include/contact_widgets.php:36 view/theme/vier/theme.php:197 +msgid "Similar Interests" +msgstr "" + +#: include/contact_widgets.php:37 +msgid "Random Profile" +msgstr "" + +#: include/contact_widgets.php:38 view/theme/vier/theme.php:199 +msgid "Invite Friends" +msgstr "" + +#: include/contact_widgets.php:115 +msgid "Networks" +msgstr "" + +#: include/contact_widgets.php:118 +msgid "All Networks" +msgstr "" + +#: include/contact_widgets.php:150 include/features.php:104 +msgid "Saved Folders" +msgstr "" + +#: include/contact_widgets.php:153 include/contact_widgets.php:187 +msgid "Everything" +msgstr "" + +#: include/contact_widgets.php:184 +msgid "Categories" +msgstr "" + +#: include/contact_widgets.php:248 +#, php-format +msgid "%d contact in common" +msgid_plural "%d contacts in common" +msgstr[0] "" +msgstr[1] "" + +#: include/conversation.php:122 include/conversation.php:258 +#: include/like.php:180 include/text.php:1804 +msgid "event" +msgstr "" + +#: include/conversation.php:125 include/conversation.php:134 +#: include/conversation.php:261 include/conversation.php:270 +#: include/diaspora.php:1530 include/like.php:178 mod/subthread.php:88 +#: mod/tagger.php:62 +msgid "status" +msgstr "" + +#: include/conversation.php:130 include/conversation.php:266 +#: include/like.php:178 include/text.php:1806 mod/subthread.php:88 +#: mod/tagger.php:62 +msgid "photo" +msgstr "" + +#: include/conversation.php:141 include/diaspora.php:1526 include/like.php:27 +#, php-format +msgid "%1$s likes %2$s's %3$s" +msgstr "" + +#: include/conversation.php:144 include/like.php:31 include/like.php:36 +#, php-format +msgid "%1$s doesn't like %2$s's %3$s" +msgstr "" + +#: include/conversation.php:147 +#, php-format +msgid "%1$s attends %2$s's %3$s" +msgstr "" + +#: include/conversation.php:150 +#, php-format +msgid "%1$s doesn't attend %2$s's %3$s" +msgstr "" + +#: include/conversation.php:153 +#, php-format +msgid "%1$s attends maybe %2$s's %3$s" +msgstr "" + +#: include/conversation.php:185 mod/dfrn_confirm.php:478 +#, php-format +msgid "%1$s is now friends with %2$s" +msgstr "" + +#: include/conversation.php:219 +#, php-format +msgid "%1$s poked %2$s" +msgstr "" + +#: include/conversation.php:239 mod/mood.php:63 +#, php-format +msgid "%1$s is currently %2$s" +msgstr "" + +#: include/conversation.php:278 mod/tagger.php:95 +#, php-format +msgid "%1$s tagged %2$s's %3$s with %4$s" +msgstr "" + +#: include/conversation.php:303 +msgid "post/item" +msgstr "" + +#: include/conversation.php:304 +#, php-format +msgid "%1$s marked %2$s's %3$s as favorite" +msgstr "" + +#: include/conversation.php:587 mod/content.php:372 mod/photos.php:1629 +#: mod/profiles.php:346 +msgid "Likes" +msgstr "" + +#: include/conversation.php:587 mod/content.php:372 mod/photos.php:1629 +#: mod/profiles.php:350 +msgid "Dislikes" +msgstr "" + +#: include/conversation.php:588 include/conversation.php:1473 +#: mod/content.php:373 mod/photos.php:1630 +msgid "Attending" +msgid_plural "Attending" +msgstr[0] "" +msgstr[1] "" + +#: include/conversation.php:588 mod/content.php:373 mod/photos.php:1630 +msgid "Not attending" +msgstr "" + +#: include/conversation.php:588 mod/content.php:373 mod/photos.php:1630 +msgid "Might attend" +msgstr "" + +#: include/conversation.php:710 mod/content.php:453 mod/content.php:759 +#: mod/photos.php:1703 object/Item.php:137 +msgid "Select" +msgstr "" + +#: include/conversation.php:711 mod/admin.php:1423 mod/contacts.php:816 +#: mod/contacts.php:1015 mod/content.php:454 mod/content.php:760 +#: mod/group.php:181 mod/photos.php:1704 mod/settings.php:744 +#: object/Item.php:138 +msgid "Delete" +msgstr "" + +#: include/conversation.php:755 mod/content.php:487 mod/content.php:915 +#: mod/content.php:916 object/Item.php:356 object/Item.php:357 +#, php-format +msgid "View %s's profile @ %s" +msgstr "" + +#: include/conversation.php:767 object/Item.php:344 +msgid "Categories:" +msgstr "" + +#: include/conversation.php:768 object/Item.php:345 +msgid "Filed under:" +msgstr "" + +#: include/conversation.php:775 mod/content.php:497 mod/content.php:928 +#: object/Item.php:370 +#, php-format +msgid "%s from %s" +msgstr "" + +#: include/conversation.php:791 mod/content.php:513 +msgid "View in context" +msgstr "" + +#: include/conversation.php:793 include/conversation.php:1256 +#: mod/content.php:515 mod/content.php:953 mod/editpost.php:114 +#: mod/message.php:337 mod/message.php:522 mod/photos.php:1592 +#: mod/wallmessage.php:140 object/Item.php:395 +msgid "Please wait" +msgstr "" + +#: include/conversation.php:872 +msgid "remove" +msgstr "" + +#: include/conversation.php:876 +msgid "Delete Selected Items" +msgstr "" + +#: include/conversation.php:968 +msgid "Follow Thread" +msgstr "" + +#: include/conversation.php:1100 +#, php-format +msgid "%s likes this." +msgstr "" + +#: include/conversation.php:1103 +#, php-format +msgid "%s doesn't like this." +msgstr "" + +#: include/conversation.php:1106 +#, php-format +msgid "%s attends." +msgstr "" + +#: include/conversation.php:1109 +#, php-format +msgid "%s doesn't attend." +msgstr "" + +#: include/conversation.php:1112 +#, php-format +msgid "%s attends maybe." +msgstr "" + +#: include/conversation.php:1122 +msgid "and" +msgstr "" + +#: include/conversation.php:1128 +#, php-format +msgid ", and %d other people" +msgstr "" + +#: include/conversation.php:1137 +#, php-format +msgid "%2$d people like this" +msgstr "" + +#: include/conversation.php:1138 +#, php-format +msgid "%s like this." +msgstr "" + +#: include/conversation.php:1141 +#, php-format +msgid "%2$d people don't like this" +msgstr "" + +#: include/conversation.php:1142 +#, php-format +msgid "%s don't like this." +msgstr "" + +#: include/conversation.php:1145 +#, php-format +msgid "%2$d people attend" +msgstr "" + +#: include/conversation.php:1146 +#, php-format +msgid "%s attend." +msgstr "" + +#: include/conversation.php:1149 +#, php-format +msgid "%2$d people don't attend" +msgstr "" + +#: include/conversation.php:1150 +#, php-format +msgid "%s don't attend." +msgstr "" + +#: include/conversation.php:1153 +#, php-format +msgid "%2$d people attend maybe" +msgstr "" + +#: include/conversation.php:1154 +#, php-format +msgid "%s anttend maybe." +msgstr "" + +#: include/conversation.php:1184 include/conversation.php:1200 +msgid "Visible to everybody" +msgstr "" + +#: include/conversation.php:1185 include/conversation.php:1201 +#: mod/message.php:271 mod/message.php:278 mod/message.php:418 +#: mod/message.php:425 mod/wallmessage.php:114 mod/wallmessage.php:121 +msgid "Please enter a link URL:" +msgstr "" + +#: include/conversation.php:1186 include/conversation.php:1202 +msgid "Please enter a video link/URL:" +msgstr "" + +#: include/conversation.php:1187 include/conversation.php:1203 +msgid "Please enter an audio link/URL:" +msgstr "" + +#: include/conversation.php:1188 include/conversation.php:1204 +msgid "Tag term:" +msgstr "" + +#: include/conversation.php:1189 include/conversation.php:1205 +#: mod/filer.php:30 +msgid "Save to Folder:" +msgstr "" + +#: include/conversation.php:1190 include/conversation.php:1206 +msgid "Where are you right now?" +msgstr "" + +#: include/conversation.php:1191 +msgid "Delete item(s)?" +msgstr "" + +#: include/conversation.php:1237 +msgid "Share" +msgstr "" + +#: include/conversation.php:1238 mod/editpost.php:100 mod/message.php:335 +#: mod/message.php:519 mod/wallmessage.php:138 +msgid "Upload photo" +msgstr "" + +#: include/conversation.php:1239 mod/editpost.php:101 +msgid "upload photo" +msgstr "" + +#: include/conversation.php:1240 mod/editpost.php:102 +msgid "Attach file" +msgstr "" + +#: include/conversation.php:1241 mod/editpost.php:103 +msgid "attach file" +msgstr "" + +#: include/conversation.php:1242 mod/editpost.php:104 mod/message.php:336 +#: mod/message.php:520 mod/wallmessage.php:139 +msgid "Insert web link" +msgstr "" + +#: include/conversation.php:1243 mod/editpost.php:105 +msgid "web link" +msgstr "" + +#: include/conversation.php:1244 mod/editpost.php:106 +msgid "Insert video link" +msgstr "" + +#: include/conversation.php:1245 mod/editpost.php:107 +msgid "video link" +msgstr "" + +#: include/conversation.php:1246 mod/editpost.php:108 +msgid "Insert audio link" +msgstr "" + +#: include/conversation.php:1247 mod/editpost.php:109 +msgid "audio link" +msgstr "" + +#: include/conversation.php:1248 mod/editpost.php:110 +msgid "Set your location" +msgstr "" + +#: include/conversation.php:1249 mod/editpost.php:111 +msgid "set location" +msgstr "" + +#: include/conversation.php:1250 mod/editpost.php:112 +msgid "Clear browser location" +msgstr "" + +#: include/conversation.php:1251 mod/editpost.php:113 +msgid "clear location" +msgstr "" + +#: include/conversation.php:1253 mod/editpost.php:127 +msgid "Set title" +msgstr "" + +#: include/conversation.php:1255 mod/editpost.php:129 +msgid "Categories (comma-separated list)" +msgstr "" + +#: include/conversation.php:1257 mod/editpost.php:115 +msgid "Permission settings" +msgstr "" + +#: include/conversation.php:1258 mod/editpost.php:144 +msgid "permissions" +msgstr "" + +#: include/conversation.php:1266 mod/editpost.php:124 +msgid "Public post" +msgstr "" + +#: include/conversation.php:1271 mod/content.php:737 mod/editpost.php:135 +#: mod/events.php:511 mod/photos.php:1613 mod/photos.php:1661 +#: mod/photos.php:1747 object/Item.php:714 +msgid "Preview" +msgstr "" + +#: include/conversation.php:1275 include/items.php:1983 mod/contacts.php:455 +#: mod/dfrn_request.php:889 mod/editpost.php:138 mod/fbrowser.php:100 +#: mod/fbrowser.php:135 mod/follow.php:124 mod/message.php:209 +#: mod/photos.php:240 mod/photos.php:331 mod/settings.php:682 +#: mod/settings.php:708 mod/suggest.php:32 mod/tagrm.php:11 mod/tagrm.php:96 +#: mod/videos.php:132 +msgid "Cancel" +msgstr "" + +#: include/conversation.php:1281 +msgid "Post to Groups" +msgstr "" + +#: include/conversation.php:1282 +msgid "Post to Contacts" +msgstr "" + +#: include/conversation.php:1283 +msgid "Private post" +msgstr "" + +#: include/conversation.php:1288 include/identity.php:259 mod/editpost.php:142 +msgid "Message" +msgstr "" + +#: include/conversation.php:1289 mod/editpost.php:143 +msgid "Browser" +msgstr "" + +#: include/conversation.php:1445 +msgid "View all" +msgstr "" + +#: include/conversation.php:1467 +msgid "Like" +msgid_plural "Likes" +msgstr[0] "" +msgstr[1] "" + +#: include/conversation.php:1470 +msgid "Dislike" +msgid_plural "Dislikes" +msgstr[0] "" +msgstr[1] "" + +#: include/conversation.php:1476 +msgid "Not Attending" +msgid_plural "Not Attending" +msgstr[0] "" +msgstr[1] "" + +#: include/conversation.php:1479 include/profile_selectors.php:6 +msgid "Undecided" +msgid_plural "Undecided" +msgstr[0] "" +msgstr[1] "" + +#: include/datetime.php:58 include/datetime.php:60 mod/profiles.php:697 +msgid "Miscellaneous" +msgstr "" + +#: include/datetime.php:184 include/identity.php:641 +msgid "Birthday:" +msgstr "" + +#: include/datetime.php:186 mod/profiles.php:720 +msgid "Age: " +msgstr "" + +#: include/datetime.php:188 +msgid "YYYY-MM-DD or MM-DD" +msgstr "" + +#: include/datetime.php:343 +msgid "never" +msgstr "" + +#: include/datetime.php:349 +msgid "less than a second ago" +msgstr "" + +#: include/datetime.php:352 +msgid "year" +msgstr "" + +#: include/datetime.php:352 +msgid "years" +msgstr "" + +#: include/datetime.php:353 include/event.php:481 mod/cal.php:279 +#: mod/events.php:396 +msgid "month" +msgstr "" + +#: include/datetime.php:353 +msgid "months" +msgstr "" + +#: include/datetime.php:354 include/event.php:482 mod/cal.php:280 +#: mod/events.php:397 +msgid "week" +msgstr "" + +#: include/datetime.php:354 +msgid "weeks" +msgstr "" + +#: include/datetime.php:355 include/event.php:483 mod/cal.php:281 +#: mod/events.php:398 +msgid "day" +msgstr "" + +#: include/datetime.php:355 +msgid "days" +msgstr "" + +#: include/datetime.php:356 +msgid "hour" +msgstr "" + +#: include/datetime.php:356 +msgid "hours" +msgstr "" + +#: include/datetime.php:357 +msgid "minute" +msgstr "" + +#: include/datetime.php:357 +msgid "minutes" +msgstr "" + +#: include/datetime.php:358 +msgid "second" +msgstr "" + +#: include/datetime.php:358 +msgid "seconds" +msgstr "" + +#: include/datetime.php:367 +#, php-format +msgid "%1$d %2$s ago" +msgstr "" + +#: include/datetime.php:585 +#, php-format +msgid "%s's birthday" +msgstr "" + +#: include/datetime.php:586 include/dfrn.php:1131 +#, php-format +msgid "Happy Birthday %s" +msgstr "" + +#: include/dba.php:43 include/dba_pdo.php:72 #, php-format msgid "Cannot locate DNS info for database server '%s'" msgstr "" +#: include/dbstructure.php:36 +#, php-format +msgid "" +"\n" +"\t\t\tThe friendica developers released update %s recently,\n" +"\t\t\tbut when I tried to install it, something went terribly wrong.\n" +"\t\t\tThis needs to be fixed soon and I can't do it alone. Please contact a\n" +"\t\t\tfriendica developer if you can not help me on your own. My database " +"might be invalid." +msgstr "" + +#: include/dbstructure.php:41 +#, php-format +msgid "" +"The error message is\n" +"[pre]%s[/pre]" +msgstr "" + +#: include/dbstructure.php:199 +msgid "Errors encountered creating database tables." +msgstr "" + +#: include/dbstructure.php:333 include/dbstructure.php:341 +#: include/dbstructure.php:349 include/dbstructure.php:354 +#: include/dbstructure.php:359 +msgid "Errors encountered performing database changes." +msgstr "" + +#: include/delivery.php:427 +msgid "(no subject)" +msgstr "" + +#: include/delivery.php:439 include/enotify.php:43 +msgid "noreply" +msgstr "" + +#: include/dfrn.php:1130 +#, php-format +msgid "%s\\'s birthday" +msgstr "" + +#: include/diaspora.php:2087 +msgid "Sharing notification from Diaspora network" +msgstr "" + +#: include/diaspora.php:3096 +msgid "Attachments:" +msgstr "" + #: include/enotify.php:24 msgid "Friendica Notification" msgstr "" @@ -414,10 +1149,6 @@ msgstr "" msgid "%1$s, %2$s Administrator" msgstr "" -#: include/enotify.php:43 include/delivery.php:482 -msgid "noreply" -msgstr "" - #: include/enotify.php:70 #, php-format msgid "%s " @@ -692,1455 +1423,6 @@ msgstr "" msgid "Please visit %s to approve or reject the request." msgstr "" -#: include/follow.php:81 mod/dfrn_request.php:512 -msgid "Disallowed profile URL." -msgstr "" - -#: include/follow.php:86 -msgid "Connect URL missing." -msgstr "" - -#: include/follow.php:114 -msgid "" -"This site is not configured to allow communications with other networks." -msgstr "" - -#: include/follow.php:115 include/follow.php:129 -msgid "No compatible communication protocols or feeds were discovered." -msgstr "" - -#: include/follow.php:127 -msgid "The profile address specified does not provide adequate information." -msgstr "" - -#: include/follow.php:132 -msgid "An author or name was not found." -msgstr "" - -#: include/follow.php:135 -msgid "No browser URL could be matched to this address." -msgstr "" - -#: include/follow.php:138 -msgid "" -"Unable to match @-style Identity Address with a known protocol or email " -"contact." -msgstr "" - -#: include/follow.php:139 -msgid "Use mailto: in front of address to force email check." -msgstr "" - -#: include/follow.php:145 -msgid "" -"The profile address specified belongs to a network which has been disabled " -"on this site." -msgstr "" - -#: include/follow.php:150 -msgid "" -"Limited profile. This person will be unable to receive direct/personal " -"notifications from you." -msgstr "" - -#: include/follow.php:251 -msgid "Unable to retrieve contact information." -msgstr "" - -#: include/group.php:25 -msgid "" -"A deleted group with this name was revived. Existing item permissions " -"may apply to this group and any future members. If this is " -"not what you intended, please create another group with a different name." -msgstr "" - -#: include/group.php:210 -msgid "Default privacy group for new contacts" -msgstr "" - -#: include/group.php:243 -msgid "Everybody" -msgstr "" - -#: include/group.php:266 -msgid "edit" -msgstr "" - -#: include/group.php:287 mod/newmember.php:61 -msgid "Groups" -msgstr "" - -#: include/group.php:289 -msgid "Edit groups" -msgstr "" - -#: include/group.php:291 -msgid "Edit group" -msgstr "" - -#: include/group.php:292 -msgid "Create a new group" -msgstr "" - -#: include/group.php:293 mod/group.php:98 mod/group.php:188 -msgid "Group Name: " -msgstr "" - -#: include/group.php:295 -msgid "Contacts not in any group" -msgstr "" - -#: include/group.php:297 mod/network.php:200 -msgid "add" -msgstr "" - -#: include/like.php:164 include/conversation.php:130 -#: include/conversation.php:266 include/text.php:1806 mod/subthread.php:88 -#: mod/tagger.php:62 -msgid "photo" -msgstr "" - -#: include/like.php:164 include/conversation.php:125 -#: include/conversation.php:134 include/conversation.php:261 -#: include/conversation.php:270 include/diaspora.php:1530 mod/subthread.php:88 -#: mod/tagger.php:62 -msgid "status" -msgstr "" - -#: include/like.php:166 include/conversation.php:122 -#: include/conversation.php:258 include/text.php:1804 -msgid "event" -msgstr "" - -#: include/like.php:184 include/conversation.php:141 include/diaspora.php:1526 -#, php-format -msgid "%1$s likes %2$s's %3$s" -msgstr "" - -#: include/like.php:187 include/conversation.php:144 -#, php-format -msgid "%1$s doesn't like %2$s's %3$s" -msgstr "" - -#: include/like.php:190 -#, php-format -msgid "%1$s is attending %2$s's %3$s" -msgstr "" - -#: include/like.php:193 -#, php-format -msgid "%1$s is not attending %2$s's %3$s" -msgstr "" - -#: include/like.php:196 -#, php-format -msgid "%1$s may attend %2$s's %3$s" -msgstr "" - -#: include/message.php:15 include/message.php:169 -msgid "[no subject]" -msgstr "" - -#: include/nav.php:35 mod/navigation.php:19 -msgid "Nothing new here" -msgstr "" - -#: include/nav.php:39 mod/navigation.php:23 -msgid "Clear notifications" -msgstr "" - -#: include/nav.php:40 include/text.php:1017 -msgid "@name, !forum, #tags, content" -msgstr "" - -#: include/nav.php:78 view/theme/frio/theme.php:243 boot.php:1833 -msgid "Logout" -msgstr "" - -#: include/nav.php:78 view/theme/frio/theme.php:243 -msgid "End this session" -msgstr "" - -#: include/nav.php:81 include/identity.php:766 mod/contacts.php:645 -#: mod/contacts.php:841 view/theme/frio/theme.php:246 -msgid "Status" -msgstr "" - -#: include/nav.php:81 include/nav.php:161 view/theme/frio/theme.php:246 -msgid "Your posts and conversations" -msgstr "" - -#: include/nav.php:82 include/identity.php:617 include/identity.php:741 -#: include/identity.php:774 mod/newmember.php:32 mod/profperm.php:105 -#: mod/contacts.php:647 mod/contacts.php:849 view/theme/frio/theme.php:247 -msgid "Profile" -msgstr "" - -#: include/nav.php:82 view/theme/frio/theme.php:247 -msgid "Your profile page" -msgstr "" - -#: include/nav.php:83 include/identity.php:782 mod/fbrowser.php:31 -#: view/theme/frio/theme.php:248 -msgid "Photos" -msgstr "" - -#: include/nav.php:83 view/theme/frio/theme.php:248 -msgid "Your photos" -msgstr "" - -#: include/nav.php:84 include/identity.php:790 include/identity.php:793 -#: view/theme/frio/theme.php:249 -msgid "Videos" -msgstr "" - -#: include/nav.php:84 view/theme/frio/theme.php:249 -msgid "Your videos" -msgstr "" - -#: include/nav.php:85 include/nav.php:149 include/identity.php:802 -#: include/identity.php:813 mod/cal.php:270 mod/events.php:386 -#: view/theme/frio/theme.php:250 view/theme/frio/theme.php:254 -msgid "Events" -msgstr "" - -#: include/nav.php:85 view/theme/frio/theme.php:250 -msgid "Your events" -msgstr "" - -#: include/nav.php:86 -msgid "Personal notes" -msgstr "" - -#: include/nav.php:86 -msgid "Your personal notes" -msgstr "" - -#: include/nav.php:95 mod/bookmarklet.php:12 boot.php:1834 -msgid "Login" -msgstr "" - -#: include/nav.php:95 -msgid "Sign in" -msgstr "" - -#: include/nav.php:105 -msgid "Home Page" -msgstr "" - -#: include/nav.php:109 mod/register.php:289 boot.php:1809 -msgid "Register" -msgstr "" - -#: include/nav.php:109 -msgid "Create an account" -msgstr "" - -#: include/nav.php:115 mod/help.php:47 view/theme/vier/theme.php:293 -msgid "Help" -msgstr "" - -#: include/nav.php:115 -msgid "Help and documentation" -msgstr "" - -#: include/nav.php:119 -msgid "Apps" -msgstr "" - -#: include/nav.php:119 -msgid "Addon applications, utilities, games" -msgstr "" - -#: include/nav.php:123 include/text.php:1014 mod/search.php:149 -msgid "Search" -msgstr "" - -#: include/nav.php:123 -msgid "Search site content" -msgstr "" - -#: include/nav.php:126 include/text.php:1022 -msgid "Full Text" -msgstr "" - -#: include/nav.php:127 include/text.php:1023 -msgid "Tags" -msgstr "" - -#: include/nav.php:128 include/nav.php:192 include/identity.php:835 -#: include/identity.php:838 include/text.php:1024 mod/contacts.php:800 -#: mod/contacts.php:861 mod/viewcontacts.php:121 view/theme/frio/theme.php:257 -msgid "Contacts" -msgstr "" - -#: include/nav.php:143 include/nav.php:145 mod/community.php:36 -msgid "Community" -msgstr "" - -#: include/nav.php:143 -msgid "Conversations on this site" -msgstr "" - -#: include/nav.php:145 -msgid "Conversations on the network" -msgstr "" - -#: include/nav.php:149 include/identity.php:805 include/identity.php:816 -#: view/theme/frio/theme.php:254 -msgid "Events and Calendar" -msgstr "" - -#: include/nav.php:152 -msgid "Directory" -msgstr "" - -#: include/nav.php:152 -msgid "People directory" -msgstr "" - -#: include/nav.php:154 -msgid "Information" -msgstr "" - -#: include/nav.php:154 -msgid "Information about this friendica instance" -msgstr "" - -#: include/nav.php:158 view/theme/frio/theme.php:253 -msgid "Conversations from your friends" -msgstr "" - -#: include/nav.php:159 -msgid "Network Reset" -msgstr "" - -#: include/nav.php:159 -msgid "Load Network page with no filters" -msgstr "" - -#: include/nav.php:166 -msgid "Friend Requests" -msgstr "" - -#: include/nav.php:169 mod/notifications.php:96 -msgid "Notifications" -msgstr "" - -#: include/nav.php:170 -msgid "See all notifications" -msgstr "" - -#: include/nav.php:171 mod/settings.php:906 -msgid "Mark as seen" -msgstr "" - -#: include/nav.php:171 -msgid "Mark all system notifications seen" -msgstr "" - -#: include/nav.php:175 mod/message.php:179 view/theme/frio/theme.php:255 -msgid "Messages" -msgstr "" - -#: include/nav.php:175 view/theme/frio/theme.php:255 -msgid "Private mail" -msgstr "" - -#: include/nav.php:176 -msgid "Inbox" -msgstr "" - -#: include/nav.php:177 -msgid "Outbox" -msgstr "" - -#: include/nav.php:178 mod/message.php:16 -msgid "New Message" -msgstr "" - -#: include/nav.php:181 -msgid "Manage" -msgstr "" - -#: include/nav.php:181 -msgid "Manage other pages" -msgstr "" - -#: include/nav.php:184 mod/settings.php:81 -msgid "Delegations" -msgstr "" - -#: include/nav.php:184 mod/delegate.php:130 -msgid "Delegate Page Management" -msgstr "" - -#: include/nav.php:186 mod/newmember.php:22 mod/settings.php:111 -#: mod/admin.php:1545 mod/admin.php:1815 view/theme/frio/theme.php:256 -msgid "Settings" -msgstr "" - -#: include/nav.php:186 view/theme/frio/theme.php:256 -msgid "Account settings" -msgstr "" - -#: include/nav.php:189 include/identity.php:285 -msgid "Profiles" -msgstr "" - -#: include/nav.php:189 -msgid "Manage/Edit Profiles" -msgstr "" - -#: include/nav.php:192 view/theme/frio/theme.php:257 -msgid "Manage/edit friends and contacts" -msgstr "" - -#: include/nav.php:197 mod/admin.php:187 -msgid "Admin" -msgstr "" - -#: include/nav.php:197 -msgid "Site setup and configuration" -msgstr "" - -#: include/nav.php:200 -msgid "Navigation" -msgstr "" - -#: include/nav.php:200 -msgid "Site map" -msgstr "" - -#: include/oembed.php:266 -msgid "Embedded content" -msgstr "" - -#: include/oembed.php:274 -msgid "Embedding disabled" -msgstr "" - -#: include/ostatus.php:1832 -#, php-format -msgid "%s is now following %s." -msgstr "" - -#: include/ostatus.php:1833 -msgid "following" -msgstr "" - -#: include/ostatus.php:1836 -#, php-format -msgid "%s stopped following %s." -msgstr "" - -#: include/ostatus.php:1837 -msgid "stopped following" -msgstr "" - -#: include/plugin.php:530 include/plugin.php:532 -msgid "Click here to upgrade." -msgstr "" - -#: include/plugin.php:538 -msgid "This action exceeds the limits set by your subscription plan." -msgstr "" - -#: include/plugin.php:543 -msgid "This action is not available under your subscription plan." -msgstr "" - -#: include/security.php:22 -msgid "Welcome " -msgstr "" - -#: include/security.php:23 -msgid "Please upload a profile photo." -msgstr "" - -#: include/security.php:26 -msgid "Welcome back " -msgstr "" - -#: include/security.php:375 -msgid "" -"The form security token was not correct. This probably happened because the " -"form has been opened for too long (>3 hours) before submitting it." -msgstr "" - -#: include/uimport.php:94 -msgid "Error decoding account file" -msgstr "" - -#: include/uimport.php:100 -msgid "Error! No version data in file! This is not a Friendica account file?" -msgstr "" - -#: include/uimport.php:116 include/uimport.php:127 -msgid "Error! Cannot check nickname" -msgstr "" - -#: include/uimport.php:120 include/uimport.php:131 -#, php-format -msgid "User '%s' already exists on this server!" -msgstr "" - -#: include/uimport.php:153 -msgid "User creation error" -msgstr "" - -#: include/uimport.php:173 -msgid "User profile creation error" -msgstr "" - -#: include/uimport.php:222 -#, php-format -msgid "%d contact not imported" -msgid_plural "%d contacts not imported" -msgstr[0] "" -msgstr[1] "" - -#: include/uimport.php:292 -msgid "Done. You can now login with your username and password" -msgstr "" - -#: include/user.php:39 mod/settings.php:375 -msgid "Passwords do not match. Password unchanged." -msgstr "" - -#: include/user.php:48 -msgid "An invitation is required." -msgstr "" - -#: include/user.php:53 -msgid "Invitation could not be verified." -msgstr "" - -#: include/user.php:61 -msgid "Invalid OpenID url" -msgstr "" - -#: include/user.php:82 -msgid "Please enter the required information." -msgstr "" - -#: include/user.php:96 -msgid "Please use a shorter name." -msgstr "" - -#: include/user.php:98 -msgid "Name too short." -msgstr "" - -#: include/user.php:113 -msgid "That doesn't appear to be your full (First Last) name." -msgstr "" - -#: include/user.php:118 -msgid "Your email domain is not among those allowed on this site." -msgstr "" - -#: include/user.php:121 -msgid "Not a valid email address." -msgstr "" - -#: include/user.php:134 -msgid "Cannot use that email." -msgstr "" - -#: include/user.php:140 -msgid "Your \"nickname\" can only contain \"a-z\", \"0-9\" and \"_\"." -msgstr "" - -#: include/user.php:147 include/user.php:245 -msgid "Nickname is already registered. Please choose another." -msgstr "" - -#: include/user.php:157 -msgid "" -"Nickname was once registered here and may not be re-used. Please choose " -"another." -msgstr "" - -#: include/user.php:173 -msgid "SERIOUS ERROR: Generation of security keys failed." -msgstr "" - -#: include/user.php:231 -msgid "An error occurred during registration. Please try again." -msgstr "" - -#: include/user.php:256 view/theme/duepuntozero/config.php:43 -#: view/theme/clean/config.php:60 -msgid "default" -msgstr "" - -#: include/user.php:266 -msgid "An error occurred creating your default profile. Please try again." -msgstr "" - -#: include/user.php:326 include/user.php:334 include/user.php:342 -#: mod/profile_photo.php:74 mod/profile_photo.php:82 mod/profile_photo.php:90 -#: mod/profile_photo.php:215 mod/profile_photo.php:310 -#: mod/profile_photo.php:320 mod/photos.php:68 mod/photos.php:182 -#: mod/photos.php:768 mod/photos.php:1231 mod/photos.php:1252 -#: mod/photos.php:1839 -msgid "Profile Photos" -msgstr "" - -#: include/user.php:417 -#, php-format -msgid "" -"\n" -"\t\tDear %1$s,\n" -"\t\t\tThank you for registering at %2$s. Your account is pending for " -"approval by the administrator.\n" -"\t" -msgstr "" - -#: include/user.php:427 -#, php-format -msgid "Registration at %s" -msgstr "" - -#: include/user.php:437 -#, php-format -msgid "" -"\n" -"\t\tDear %1$s,\n" -"\t\t\tThank you for registering at %2$s. Your account has been created.\n" -"\t" -msgstr "" - -#: include/user.php:441 -#, php-format -msgid "" -"\n" -"\t\tThe login details are as follows:\n" -"\t\t\tSite Location:\t%3$s\n" -"\t\t\tLogin Name:\t%1$s\n" -"\t\t\tPassword:\t%5$s\n" -"\n" -"\t\tYou may change your password from your account \"Settings\" page after " -"logging\n" -"\t\tin.\n" -"\n" -"\t\tPlease take a few moments to review the other account settings on that " -"page.\n" -"\n" -"\t\tYou may also wish to add some basic information to your default profile\n" -"\t\t(on the \"Profiles\" page) so that other people can easily find you.\n" -"\n" -"\t\tWe recommend setting your full name, adding a profile photo,\n" -"\t\tadding some profile \"keywords\" (very useful in making new friends) - " -"and\n" -"\t\tperhaps what country you live in; if you do not wish to be more " -"specific\n" -"\t\tthan that.\n" -"\n" -"\t\tWe fully respect your right to privacy, and none of these items are " -"necessary.\n" -"\t\tIf you are new and do not know anybody here, they may help\n" -"\t\tyou to make some new and interesting friends.\n" -"\n" -"\n" -"\t\tThank you and welcome to %2$s." -msgstr "" - -#: include/user.php:473 mod/admin.php:1234 -#, php-format -msgid "Registration details for %s" -msgstr "" - -#: include/acl_selectors.php:341 -msgid "Post to Email" -msgstr "" - -#: include/acl_selectors.php:346 -#, php-format -msgid "Connectors disabled, since \"%s\" is enabled." -msgstr "" - -#: include/acl_selectors.php:347 mod/settings.php:1188 -msgid "Hide your profile details from unknown viewers?" -msgstr "" - -#: include/acl_selectors.php:352 -msgid "Visible to everybody" -msgstr "" - -#: include/acl_selectors.php:353 view/theme/vier/config.php:108 -msgid "show" -msgstr "" - -#: include/acl_selectors.php:354 view/theme/vier/config.php:108 -msgid "don't show" -msgstr "" - -#: include/acl_selectors.php:360 mod/editpost.php:123 -msgid "CC: email addresses" -msgstr "" - -#: include/acl_selectors.php:361 mod/editpost.php:130 -msgid "Example: bob@example.com, mary@example.com" -msgstr "" - -#: include/acl_selectors.php:363 mod/events.php:516 mod/photos.php:1176 -#: mod/photos.php:1558 -msgid "Permissions" -msgstr "" - -#: include/acl_selectors.php:364 -msgid "Close" -msgstr "" - -#: include/conversation.php:147 -#, php-format -msgid "%1$s attends %2$s's %3$s" -msgstr "" - -#: include/conversation.php:150 -#, php-format -msgid "%1$s doesn't attend %2$s's %3$s" -msgstr "" - -#: include/conversation.php:153 -#, php-format -msgid "%1$s attends maybe %2$s's %3$s" -msgstr "" - -#: include/conversation.php:185 mod/dfrn_confirm.php:478 -#, php-format -msgid "%1$s is now friends with %2$s" -msgstr "" - -#: include/conversation.php:219 -#, php-format -msgid "%1$s poked %2$s" -msgstr "" - -#: include/conversation.php:239 mod/mood.php:63 -#, php-format -msgid "%1$s is currently %2$s" -msgstr "" - -#: include/conversation.php:278 mod/tagger.php:95 -#, php-format -msgid "%1$s tagged %2$s's %3$s with %4$s" -msgstr "" - -#: include/conversation.php:303 -msgid "post/item" -msgstr "" - -#: include/conversation.php:304 -#, php-format -msgid "%1$s marked %2$s's %3$s as favorite" -msgstr "" - -#: include/conversation.php:587 mod/content.php:372 mod/photos.php:1629 -#: mod/profiles.php:346 -msgid "Likes" -msgstr "" - -#: include/conversation.php:587 mod/content.php:372 mod/photos.php:1629 -#: mod/profiles.php:350 -msgid "Dislikes" -msgstr "" - -#: include/conversation.php:588 include/conversation.php:1472 -#: mod/content.php:373 mod/photos.php:1630 -msgid "Attending" -msgid_plural "Attending" -msgstr[0] "" -msgstr[1] "" - -#: include/conversation.php:588 mod/content.php:373 mod/photos.php:1630 -msgid "Not attending" -msgstr "" - -#: include/conversation.php:588 mod/content.php:373 mod/photos.php:1630 -msgid "Might attend" -msgstr "" - -#: include/conversation.php:710 mod/content.php:453 mod/content.php:759 -#: mod/photos.php:1703 object/Item.php:137 -msgid "Select" -msgstr "" - -#: include/conversation.php:711 mod/content.php:454 mod/content.php:760 -#: mod/group.php:181 mod/settings.php:744 mod/contacts.php:816 -#: mod/contacts.php:1015 mod/photos.php:1704 mod/admin.php:1435 -#: object/Item.php:138 -msgid "Delete" -msgstr "" - -#: include/conversation.php:755 mod/content.php:487 mod/content.php:915 -#: mod/content.php:916 object/Item.php:382 object/Item.php:383 -#, php-format -msgid "View %s's profile @ %s" -msgstr "" - -#: include/conversation.php:767 object/Item.php:370 -msgid "Categories:" -msgstr "" - -#: include/conversation.php:768 object/Item.php:371 -msgid "Filed under:" -msgstr "" - -#: include/conversation.php:775 mod/content.php:497 mod/content.php:928 -#: object/Item.php:396 -#, php-format -msgid "%s from %s" -msgstr "" - -#: include/conversation.php:791 mod/content.php:513 -msgid "View in context" -msgstr "" - -#: include/conversation.php:793 include/conversation.php:1255 -#: mod/content.php:515 mod/content.php:953 mod/editpost.php:114 -#: mod/message.php:337 mod/message.php:522 mod/wallmessage.php:140 -#: mod/photos.php:1592 object/Item.php:421 -msgid "Please wait" -msgstr "" - -#: include/conversation.php:872 -msgid "remove" -msgstr "" - -#: include/conversation.php:876 -msgid "Delete Selected Items" -msgstr "" - -#: include/conversation.php:968 -msgid "Follow Thread" -msgstr "" - -#: include/conversation.php:969 include/Contact.php:445 -msgid "View Status" -msgstr "" - -#: include/conversation.php:970 include/conversation.php:986 -#: include/Contact.php:388 include/Contact.php:401 include/Contact.php:446 -#: mod/allfriends.php:68 mod/directory.php:157 mod/dirfind.php:209 -#: mod/match.php:73 mod/suggest.php:82 -msgid "View Profile" -msgstr "" - -#: include/conversation.php:971 include/Contact.php:447 -msgid "View Photos" -msgstr "" - -#: include/conversation.php:972 include/Contact.php:448 -msgid "Network Posts" -msgstr "" - -#: include/conversation.php:973 include/Contact.php:449 -msgid "View Contact" -msgstr "" - -#: include/conversation.php:974 include/Contact.php:451 -msgid "Send PM" -msgstr "" - -#: include/conversation.php:978 include/Contact.php:452 -msgid "Poke" -msgstr "" - -#: include/conversation.php:983 include/contact_widgets.php:32 -#: include/Contact.php:402 mod/allfriends.php:69 mod/dirfind.php:210 -#: mod/follow.php:106 mod/match.php:74 mod/suggest.php:83 mod/contacts.php:610 -msgid "Connect/Follow" -msgstr "" - -#: include/conversation.php:1099 -#, php-format -msgid "%s likes this." -msgstr "" - -#: include/conversation.php:1102 -#, php-format -msgid "%s doesn't like this." -msgstr "" - -#: include/conversation.php:1105 -#, php-format -msgid "%s attends." -msgstr "" - -#: include/conversation.php:1108 -#, php-format -msgid "%s doesn't attend." -msgstr "" - -#: include/conversation.php:1111 -#, php-format -msgid "%s attends maybe." -msgstr "" - -#: include/conversation.php:1121 -msgid "and" -msgstr "" - -#: include/conversation.php:1127 -#, php-format -msgid ", and %d other people" -msgstr "" - -#: include/conversation.php:1136 -#, php-format -msgid "%2$d people like this" -msgstr "" - -#: include/conversation.php:1137 -#, php-format -msgid "%s like this." -msgstr "" - -#: include/conversation.php:1140 -#, php-format -msgid "%2$d people don't like this" -msgstr "" - -#: include/conversation.php:1141 -#, php-format -msgid "%s don't like this." -msgstr "" - -#: include/conversation.php:1144 -#, php-format -msgid "%2$d people attend" -msgstr "" - -#: include/conversation.php:1145 -#, php-format -msgid "%s attend." -msgstr "" - -#: include/conversation.php:1148 -#, php-format -msgid "%2$d people don't attend" -msgstr "" - -#: include/conversation.php:1149 -#, php-format -msgid "%s don't attend." -msgstr "" - -#: include/conversation.php:1152 -#, php-format -msgid "%2$d people attend maybe" -msgstr "" - -#: include/conversation.php:1153 -#, php-format -msgid "%s anttend maybe." -msgstr "" - -#: include/conversation.php:1183 include/conversation.php:1199 -msgid "Visible to everybody" -msgstr "" - -#: include/conversation.php:1184 include/conversation.php:1200 -#: mod/message.php:271 mod/message.php:278 mod/message.php:418 -#: mod/message.php:425 mod/wallmessage.php:114 mod/wallmessage.php:121 -msgid "Please enter a link URL:" -msgstr "" - -#: include/conversation.php:1185 include/conversation.php:1201 -msgid "Please enter a video link/URL:" -msgstr "" - -#: include/conversation.php:1186 include/conversation.php:1202 -msgid "Please enter an audio link/URL:" -msgstr "" - -#: include/conversation.php:1187 include/conversation.php:1203 -msgid "Tag term:" -msgstr "" - -#: include/conversation.php:1188 include/conversation.php:1204 -#: mod/filer.php:30 -msgid "Save to Folder:" -msgstr "" - -#: include/conversation.php:1189 include/conversation.php:1205 -msgid "Where are you right now?" -msgstr "" - -#: include/conversation.php:1190 -msgid "Delete item(s)?" -msgstr "" - -#: include/conversation.php:1236 -msgid "Share" -msgstr "" - -#: include/conversation.php:1237 mod/editpost.php:100 mod/message.php:335 -#: mod/message.php:519 mod/wallmessage.php:138 -msgid "Upload photo" -msgstr "" - -#: include/conversation.php:1238 mod/editpost.php:101 -msgid "upload photo" -msgstr "" - -#: include/conversation.php:1239 mod/editpost.php:102 -msgid "Attach file" -msgstr "" - -#: include/conversation.php:1240 mod/editpost.php:103 -msgid "attach file" -msgstr "" - -#: include/conversation.php:1241 mod/editpost.php:104 mod/message.php:336 -#: mod/message.php:520 mod/wallmessage.php:139 -msgid "Insert web link" -msgstr "" - -#: include/conversation.php:1242 mod/editpost.php:105 -msgid "web link" -msgstr "" - -#: include/conversation.php:1243 mod/editpost.php:106 -msgid "Insert video link" -msgstr "" - -#: include/conversation.php:1244 mod/editpost.php:107 -msgid "video link" -msgstr "" - -#: include/conversation.php:1245 mod/editpost.php:108 -msgid "Insert audio link" -msgstr "" - -#: include/conversation.php:1246 mod/editpost.php:109 -msgid "audio link" -msgstr "" - -#: include/conversation.php:1247 mod/editpost.php:110 -msgid "Set your location" -msgstr "" - -#: include/conversation.php:1248 mod/editpost.php:111 -msgid "set location" -msgstr "" - -#: include/conversation.php:1249 mod/editpost.php:112 -msgid "Clear browser location" -msgstr "" - -#: include/conversation.php:1250 mod/editpost.php:113 -msgid "clear location" -msgstr "" - -#: include/conversation.php:1252 mod/editpost.php:127 -msgid "Set title" -msgstr "" - -#: include/conversation.php:1254 mod/editpost.php:129 -msgid "Categories (comma-separated list)" -msgstr "" - -#: include/conversation.php:1256 mod/editpost.php:115 -msgid "Permission settings" -msgstr "" - -#: include/conversation.php:1257 mod/editpost.php:144 -msgid "permissions" -msgstr "" - -#: include/conversation.php:1265 mod/editpost.php:124 -msgid "Public post" -msgstr "" - -#: include/conversation.php:1270 mod/content.php:737 mod/editpost.php:135 -#: mod/events.php:511 mod/photos.php:1613 mod/photos.php:1661 -#: mod/photos.php:1747 object/Item.php:741 -msgid "Preview" -msgstr "" - -#: include/conversation.php:1274 include/items.php:1983 mod/follow.php:124 -#: mod/settings.php:682 mod/settings.php:708 mod/suggest.php:32 -#: mod/tagrm.php:11 mod/tagrm.php:96 mod/videos.php:132 mod/contacts.php:455 -#: mod/editpost.php:138 mod/fbrowser.php:100 mod/fbrowser.php:135 -#: mod/message.php:209 mod/photos.php:240 mod/photos.php:331 -#: mod/dfrn_request.php:889 -msgid "Cancel" -msgstr "" - -#: include/conversation.php:1280 -msgid "Post to Groups" -msgstr "" - -#: include/conversation.php:1281 -msgid "Post to Contacts" -msgstr "" - -#: include/conversation.php:1282 -msgid "Private post" -msgstr "" - -#: include/conversation.php:1287 include/identity.php:259 mod/editpost.php:142 -msgid "Message" -msgstr "" - -#: include/conversation.php:1288 mod/editpost.php:143 -msgid "Browser" -msgstr "" - -#: include/conversation.php:1444 -msgid "View all" -msgstr "" - -#: include/conversation.php:1466 -msgid "Like" -msgid_plural "Likes" -msgstr[0] "" -msgstr[1] "" - -#: include/conversation.php:1469 -msgid "Dislike" -msgid_plural "Dislikes" -msgstr[0] "" -msgstr[1] "" - -#: include/conversation.php:1475 -msgid "Not Attending" -msgid_plural "Not Attending" -msgstr[0] "" -msgstr[1] "" - -#: include/delivery.php:470 -msgid "(no subject)" -msgstr "" - -#: include/features.php:65 -msgid "General Features" -msgstr "" - -#: include/features.php:67 -msgid "Multiple Profiles" -msgstr "" - -#: include/features.php:67 -msgid "Ability to create multiple profiles" -msgstr "" - -#: include/features.php:68 -msgid "Photo Location" -msgstr "" - -#: include/features.php:68 -msgid "" -"Photo metadata is normally stripped. This extracts the location (if present) " -"prior to stripping metadata and links it to a map." -msgstr "" - -#: include/features.php:69 -msgid "Export Public Calendar" -msgstr "" - -#: include/features.php:69 -msgid "Ability for visitors to download the public calendar" -msgstr "" - -#: include/features.php:74 -msgid "Post Composition Features" -msgstr "" - -#: include/features.php:75 -msgid "Post Preview" -msgstr "" - -#: include/features.php:75 -msgid "Allow previewing posts and comments before publishing them" -msgstr "" - -#: include/features.php:76 -msgid "Auto-mention Forums" -msgstr "" - -#: include/features.php:76 -msgid "" -"Add/remove mention when a forum page is selected/deselected in ACL window." -msgstr "" - -#: include/features.php:81 -msgid "Network Sidebar Widgets" -msgstr "" - -#: include/features.php:82 -msgid "Search by Date" -msgstr "" - -#: include/features.php:82 -msgid "Ability to select posts by date ranges" -msgstr "" - -#: include/features.php:83 include/features.php:113 -msgid "List Forums" -msgstr "" - -#: include/features.php:83 -msgid "Enable widget to display the forums your are connected with" -msgstr "" - -#: include/features.php:84 -msgid "Group Filter" -msgstr "" - -#: include/features.php:84 -msgid "Enable widget to display Network posts only from selected group" -msgstr "" - -#: include/features.php:85 -msgid "Network Filter" -msgstr "" - -#: include/features.php:85 -msgid "Enable widget to display Network posts only from selected network" -msgstr "" - -#: include/features.php:86 mod/network.php:199 mod/search.php:34 -msgid "Saved Searches" -msgstr "" - -#: include/features.php:86 -msgid "Save search terms for re-use" -msgstr "" - -#: include/features.php:91 -msgid "Network Tabs" -msgstr "" - -#: include/features.php:92 -msgid "Network Personal Tab" -msgstr "" - -#: include/features.php:92 -msgid "Enable tab to display only Network posts that you've interacted on" -msgstr "" - -#: include/features.php:93 -msgid "Network New Tab" -msgstr "" - -#: include/features.php:93 -msgid "Enable tab to display only new Network posts (from the last 12 hours)" -msgstr "" - -#: include/features.php:94 -msgid "Network Shared Links Tab" -msgstr "" - -#: include/features.php:94 -msgid "Enable tab to display only Network posts with links in them" -msgstr "" - -#: include/features.php:99 -msgid "Post/Comment Tools" -msgstr "" - -#: include/features.php:100 -msgid "Multiple Deletion" -msgstr "" - -#: include/features.php:100 -msgid "Select and delete multiple posts/comments at once" -msgstr "" - -#: include/features.php:101 -msgid "Edit Sent Posts" -msgstr "" - -#: include/features.php:101 -msgid "Edit and correct posts and comments after sending" -msgstr "" - -#: include/features.php:102 -msgid "Tagging" -msgstr "" - -#: include/features.php:102 -msgid "Ability to tag existing posts" -msgstr "" - -#: include/features.php:103 -msgid "Post Categories" -msgstr "" - -#: include/features.php:103 -msgid "Add categories to your posts" -msgstr "" - -#: include/features.php:104 include/contact_widgets.php:150 -msgid "Saved Folders" -msgstr "" - -#: include/features.php:104 -msgid "Ability to file posts under folders" -msgstr "" - -#: include/features.php:105 -msgid "Dislike Posts" -msgstr "" - -#: include/features.php:105 -msgid "Ability to dislike posts/comments" -msgstr "" - -#: include/features.php:106 -msgid "Star Posts" -msgstr "" - -#: include/features.php:106 -msgid "Ability to mark special posts with a star indicator" -msgstr "" - -#: include/features.php:107 -msgid "Mute Post Notifications" -msgstr "" - -#: include/features.php:107 -msgid "Ability to mute notifications for a thread" -msgstr "" - -#: include/features.php:112 -msgid "Advanced Profile Settings" -msgstr "" - -#: include/features.php:113 -msgid "Show visitors public community forums at the Advanced Profile Page" -msgstr "" - -#: include/photos.php:57 include/photos.php:67 mod/fbrowser.php:40 -#: mod/fbrowser.php:61 mod/photos.php:182 mod/photos.php:1106 -#: mod/photos.php:1231 mod/photos.php:1252 mod/photos.php:1817 -#: mod/photos.php:1829 -msgid "Contact Photos" -msgstr "" - -#: include/datetime.php:58 include/datetime.php:60 mod/profiles.php:697 -msgid "Miscellaneous" -msgstr "" - -#: include/datetime.php:184 include/identity.php:641 -msgid "Birthday:" -msgstr "" - -#: include/datetime.php:186 mod/profiles.php:720 -msgid "Age: " -msgstr "" - -#: include/datetime.php:188 -msgid "YYYY-MM-DD or MM-DD" -msgstr "" - -#: include/datetime.php:343 -msgid "never" -msgstr "" - -#: include/datetime.php:349 -msgid "less than a second ago" -msgstr "" - -#: include/datetime.php:352 -msgid "year" -msgstr "" - -#: include/datetime.php:352 -msgid "years" -msgstr "" - -#: include/datetime.php:353 include/event.php:481 mod/cal.php:279 -#: mod/events.php:396 -msgid "month" -msgstr "" - -#: include/datetime.php:353 -msgid "months" -msgstr "" - -#: include/datetime.php:354 include/event.php:482 mod/cal.php:280 -#: mod/events.php:397 -msgid "week" -msgstr "" - -#: include/datetime.php:354 -msgid "weeks" -msgstr "" - -#: include/datetime.php:355 include/event.php:483 mod/cal.php:281 -#: mod/events.php:398 -msgid "day" -msgstr "" - -#: include/datetime.php:355 -msgid "days" -msgstr "" - -#: include/datetime.php:356 -msgid "hour" -msgstr "" - -#: include/datetime.php:356 -msgid "hours" -msgstr "" - -#: include/datetime.php:357 -msgid "minute" -msgstr "" - -#: include/datetime.php:357 -msgid "minutes" -msgstr "" - -#: include/datetime.php:358 -msgid "second" -msgstr "" - -#: include/datetime.php:358 -msgid "seconds" -msgstr "" - -#: include/datetime.php:367 -#, php-format -msgid "%1$d %2$s ago" -msgstr "" - -#: include/datetime.php:585 -#, php-format -msgid "%s's birthday" -msgstr "" - -#: include/datetime.php:586 include/dfrn.php:1122 -#, php-format -msgid "Happy Birthday %s" -msgstr "" - -#: include/event.php:16 include/bb2diaspora.php:199 mod/localtime.php:12 -msgid "l F d, Y \\@ g:i A" -msgstr "" - -#: include/event.php:33 include/event.php:51 include/event.php:488 -#: include/bb2diaspora.php:205 -msgid "Starts:" -msgstr "" - -#: include/event.php:36 include/event.php:57 include/event.php:489 -#: include/bb2diaspora.php:213 -msgid "Finishes:" -msgstr "" - -#: include/event.php:39 include/event.php:63 include/event.php:490 -#: include/bb2diaspora.php:221 include/identity.php:331 mod/directory.php:139 -#: mod/contacts.php:636 mod/events.php:501 mod/notifications.php:238 -msgid "Location:" -msgstr "" - #: include/event.php:442 msgid "Sun" msgstr "" @@ -2325,235 +1607,301 @@ msgstr "" msgid "Export calendar as csv" msgstr "" -#: include/dfrn.php:1121 -#, php-format -msgid "%s\\'s birthday" +#: include/features.php:65 +msgid "General Features" msgstr "" -#: include/contact_selectors.php:32 -msgid "Unknown | Not categorised" +#: include/features.php:67 +msgid "Multiple Profiles" msgstr "" -#: include/contact_selectors.php:33 -msgid "Block immediately" +#: include/features.php:67 +msgid "Ability to create multiple profiles" msgstr "" -#: include/contact_selectors.php:34 -msgid "Shady, spammer, self-marketer" +#: include/features.php:68 +msgid "Photo Location" msgstr "" -#: include/contact_selectors.php:35 -msgid "Known to me, but no opinion" +#: include/features.php:68 +msgid "" +"Photo metadata is normally stripped. This extracts the location (if present) " +"prior to stripping metadata and links it to a map." msgstr "" -#: include/contact_selectors.php:36 -msgid "OK, probably harmless" +#: include/features.php:69 +msgid "Export Public Calendar" msgstr "" -#: include/contact_selectors.php:37 -msgid "Reputable, has my trust" +#: include/features.php:69 +msgid "Ability for visitors to download the public calendar" msgstr "" -#: include/contact_selectors.php:56 mod/admin.php:901 -msgid "Frequently" +#: include/features.php:74 +msgid "Post Composition Features" msgstr "" -#: include/contact_selectors.php:57 mod/admin.php:902 -msgid "Hourly" +#: include/features.php:75 +msgid "Post Preview" msgstr "" -#: include/contact_selectors.php:58 mod/admin.php:903 -msgid "Twice daily" +#: include/features.php:75 +msgid "Allow previewing posts and comments before publishing them" msgstr "" -#: include/contact_selectors.php:59 mod/admin.php:904 -msgid "Daily" +#: include/features.php:76 +msgid "Auto-mention Forums" msgstr "" -#: include/contact_selectors.php:60 -msgid "Weekly" +#: include/features.php:76 +msgid "" +"Add/remove mention when a forum page is selected/deselected in ACL window." msgstr "" -#: include/contact_selectors.php:61 -msgid "Monthly" +#: include/features.php:81 +msgid "Network Sidebar Widgets" msgstr "" -#: include/contact_selectors.php:76 mod/dfrn_request.php:881 -msgid "Friendica" +#: include/features.php:82 +msgid "Search by Date" msgstr "" -#: include/contact_selectors.php:77 -msgid "OStatus" +#: include/features.php:82 +msgid "Ability to select posts by date ranges" msgstr "" -#: include/contact_selectors.php:78 -msgid "RSS/Atom" +#: include/features.php:83 include/features.php:113 +msgid "List Forums" msgstr "" -#: include/contact_selectors.php:79 include/contact_selectors.php:86 -#: mod/admin.php:1417 mod/admin.php:1430 mod/admin.php:1443 mod/admin.php:1461 -msgid "Email" +#: include/features.php:83 +msgid "Enable widget to display the forums your are connected with" msgstr "" -#: include/contact_selectors.php:80 mod/settings.php:848 -#: mod/dfrn_request.php:883 -msgid "Diaspora" +#: include/features.php:84 +msgid "Group Filter" msgstr "" -#: include/contact_selectors.php:81 -msgid "Facebook" +#: include/features.php:84 +msgid "Enable widget to display Network posts only from selected group" msgstr "" -#: include/contact_selectors.php:82 -msgid "Zot!" +#: include/features.php:85 +msgid "Network Filter" msgstr "" -#: include/contact_selectors.php:83 -msgid "LinkedIn" +#: include/features.php:85 +msgid "Enable widget to display Network posts only from selected network" msgstr "" -#: include/contact_selectors.php:84 -msgid "XMPP/IM" +#: include/features.php:86 mod/network.php:199 mod/search.php:34 +msgid "Saved Searches" msgstr "" -#: include/contact_selectors.php:85 -msgid "MySpace" +#: include/features.php:86 +msgid "Save search terms for re-use" msgstr "" -#: include/contact_selectors.php:87 -msgid "Google+" +#: include/features.php:91 +msgid "Network Tabs" msgstr "" -#: include/contact_selectors.php:88 -msgid "pump.io" +#: include/features.php:92 +msgid "Network Personal Tab" msgstr "" -#: include/contact_selectors.php:89 -msgid "Twitter" +#: include/features.php:92 +msgid "Enable tab to display only Network posts that you've interacted on" msgstr "" -#: include/contact_selectors.php:90 -msgid "Diaspora Connector" +#: include/features.php:93 +msgid "Network New Tab" msgstr "" -#: include/contact_selectors.php:91 -msgid "GNU Social" +#: include/features.php:93 +msgid "Enable tab to display only new Network posts (from the last 12 hours)" msgstr "" -#: include/contact_selectors.php:92 -msgid "pnut" +#: include/features.php:94 +msgid "Network Shared Links Tab" msgstr "" -#: include/contact_selectors.php:93 -msgid "App.net" +#: include/features.php:94 +msgid "Enable tab to display only Network posts with links in them" msgstr "" -#: include/contact_selectors.php:104 -msgid "Hubzilla/Redmatrix" +#: include/features.php:99 +msgid "Post/Comment Tools" msgstr "" -#: include/contact_widgets.php:6 -msgid "Add New Contact" +#: include/features.php:100 +msgid "Multiple Deletion" msgstr "" -#: include/contact_widgets.php:7 -msgid "Enter address or web location" +#: include/features.php:100 +msgid "Select and delete multiple posts/comments at once" msgstr "" -#: include/contact_widgets.php:8 -msgid "Example: bob@example.com, http://example.com/barbara" +#: include/features.php:101 +msgid "Edit Sent Posts" msgstr "" -#: include/contact_widgets.php:10 include/identity.php:219 -#: mod/allfriends.php:85 mod/dirfind.php:207 mod/match.php:89 -#: mod/suggest.php:101 -msgid "Connect" +#: include/features.php:101 +msgid "Edit and correct posts and comments after sending" msgstr "" -#: include/contact_widgets.php:24 -#, php-format -msgid "%d invitation available" -msgid_plural "%d invitations available" -msgstr[0] "" -msgstr[1] "" - -#: include/contact_widgets.php:30 -msgid "Find People" +#: include/features.php:102 +msgid "Tagging" msgstr "" -#: include/contact_widgets.php:31 -msgid "Enter name or interest" +#: include/features.php:102 +msgid "Ability to tag existing posts" msgstr "" -#: include/contact_widgets.php:33 -msgid "Examples: Robert Morgenstein, Fishing" +#: include/features.php:103 +msgid "Post Categories" msgstr "" -#: include/contact_widgets.php:34 mod/directory.php:206 mod/contacts.php:806 -msgid "Find" +#: include/features.php:103 +msgid "Add categories to your posts" msgstr "" -#: include/contact_widgets.php:35 mod/suggest.php:114 -#: view/theme/vier/theme.php:198 -msgid "Friend Suggestions" +#: include/features.php:104 +msgid "Ability to file posts under folders" msgstr "" -#: include/contact_widgets.php:36 view/theme/vier/theme.php:197 -msgid "Similar Interests" +#: include/features.php:105 +msgid "Dislike Posts" msgstr "" -#: include/contact_widgets.php:37 -msgid "Random Profile" +#: include/features.php:105 +msgid "Ability to dislike posts/comments" msgstr "" -#: include/contact_widgets.php:38 view/theme/vier/theme.php:199 -msgid "Invite Friends" +#: include/features.php:106 +msgid "Star Posts" msgstr "" -#: include/contact_widgets.php:115 -msgid "Networks" +#: include/features.php:106 +msgid "Ability to mark special posts with a star indicator" msgstr "" -#: include/contact_widgets.php:118 -msgid "All Networks" +#: include/features.php:107 +msgid "Mute Post Notifications" msgstr "" -#: include/contact_widgets.php:153 include/contact_widgets.php:187 -msgid "Everything" +#: include/features.php:107 +msgid "Ability to mute notifications for a thread" msgstr "" -#: include/contact_widgets.php:184 -msgid "Categories" +#: include/features.php:112 +msgid "Advanced Profile Settings" msgstr "" -#: include/contact_widgets.php:248 -#, php-format -msgid "%d contact in common" -msgid_plural "%d contacts in common" -msgstr[0] "" -msgstr[1] "" - -#: include/api.php:1021 -#, php-format -msgid "Daily posting limit of %d posts reached. The post was rejected." +#: include/features.php:113 +msgid "Show visitors public community forums at the Advanced Profile Page" msgstr "" -#: include/api.php:1041 -#, php-format -msgid "Weekly posting limit of %d posts reached. The post was rejected." +#: include/follow.php:81 mod/dfrn_request.php:512 +msgid "Disallowed profile URL." msgstr "" -#: include/api.php:1062 -#, php-format -msgid "Monthly posting limit of %d posts reached. The post was rejected." +#: include/follow.php:86 +msgid "Connect URL missing." msgstr "" -#: include/diaspora.php:2087 -msgid "Sharing notification from Diaspora network" +#: include/follow.php:114 +msgid "" +"This site is not configured to allow communications with other networks." msgstr "" -#: include/diaspora.php:3096 -msgid "Attachments:" +#: include/follow.php:115 include/follow.php:129 +msgid "No compatible communication protocols or feeds were discovered." +msgstr "" + +#: include/follow.php:127 +msgid "The profile address specified does not provide adequate information." +msgstr "" + +#: include/follow.php:132 +msgid "An author or name was not found." +msgstr "" + +#: include/follow.php:135 +msgid "No browser URL could be matched to this address." +msgstr "" + +#: include/follow.php:138 +msgid "" +"Unable to match @-style Identity Address with a known protocol or email " +"contact." +msgstr "" + +#: include/follow.php:139 +msgid "Use mailto: in front of address to force email check." +msgstr "" + +#: include/follow.php:145 +msgid "" +"The profile address specified belongs to a network which has been disabled " +"on this site." +msgstr "" + +#: include/follow.php:150 +msgid "" +"Limited profile. This person will be unable to receive direct/personal " +"notifications from you." +msgstr "" + +#: include/follow.php:251 +msgid "Unable to retrieve contact information." +msgstr "" + +#: include/group.php:25 +msgid "" +"A deleted group with this name was revived. Existing item permissions " +"may apply to this group and any future members. If this is " +"not what you intended, please create another group with a different name." +msgstr "" + +#: include/group.php:210 +msgid "Default privacy group for new contacts" +msgstr "" + +#: include/group.php:243 +msgid "Everybody" +msgstr "" + +#: include/group.php:266 +msgid "edit" +msgstr "" + +#: include/group.php:287 mod/newmember.php:61 +msgid "Groups" +msgstr "" + +#: include/group.php:289 +msgid "Edit groups" +msgstr "" + +#: include/group.php:291 +msgid "Edit group" +msgstr "" + +#: include/group.php:292 +msgid "Create a new group" +msgstr "" + +#: include/group.php:293 mod/group.php:98 mod/group.php:188 +msgid "Group Name: " +msgstr "" + +#: include/group.php:295 +msgid "Contacts not in any group" +msgstr "" + +#: include/group.php:297 mod/network.php:200 +msgid "add" msgstr "" #: include/identity.php:43 @@ -2572,6 +1920,10 @@ msgstr "" msgid "Atom feed" msgstr "" +#: include/identity.php:285 include/nav.php:189 +msgid "Profiles" +msgstr "" + #: include/identity.php:285 msgid "Manage/edit profiles" msgstr "" @@ -2609,8 +1961,8 @@ msgstr "" msgid "Homepage:" msgstr "" -#: include/identity.php:340 include/identity.php:684 mod/directory.php:147 -#: mod/contacts.php:640 mod/notifications.php:240 +#: include/identity.php:340 include/identity.php:684 mod/contacts.php:640 +#: mod/directory.php:147 mod/notifications.php:240 msgid "About:" msgstr "" @@ -2654,6 +2006,12 @@ msgstr "" msgid "Events this week:" msgstr "" +#: include/identity.php:617 include/identity.php:741 include/identity.php:774 +#: include/nav.php:82 mod/contacts.php:647 mod/contacts.php:849 +#: mod/newmember.php:32 mod/profperm.php:105 view/theme/frio/theme.php:247 +msgid "Profile" +msgstr "" + #: include/identity.php:626 mod/settings.php:1286 msgid "Full Name:" msgstr "" @@ -2683,7 +2041,7 @@ msgstr "" msgid "Hometown:" msgstr "" -#: include/identity.php:672 mod/follow.php:137 mod/contacts.php:642 +#: include/identity.php:672 mod/contacts.php:642 mod/follow.php:137 #: mod/notifications.php:242 msgid "Tags:" msgstr "" @@ -2748,12 +2106,17 @@ msgstr "" msgid "Basic" msgstr "" -#: include/identity.php:743 mod/contacts.php:878 mod/events.php:515 -#: mod/admin.php:980 +#: include/identity.php:743 mod/admin.php:972 mod/contacts.php:878 +#: mod/events.php:515 msgid "Advanced" msgstr "" -#: include/identity.php:769 mod/follow.php:145 mod/contacts.php:844 +#: include/identity.php:766 include/nav.php:81 mod/contacts.php:645 +#: mod/contacts.php:841 view/theme/frio/theme.php:246 +msgid "Status" +msgstr "" + +#: include/identity.php:769 mod/contacts.php:844 mod/follow.php:145 msgid "Status Messages and Posts" msgstr "" @@ -2761,10 +2124,31 @@ msgstr "" msgid "Profile Details" msgstr "" +#: include/identity.php:782 include/nav.php:83 mod/fbrowser.php:31 +#: view/theme/frio/theme.php:248 +msgid "Photos" +msgstr "" + #: include/identity.php:785 mod/photos.php:89 msgid "Photo Albums" msgstr "" +#: include/identity.php:790 include/identity.php:793 include/nav.php:84 +#: view/theme/frio/theme.php:249 +msgid "Videos" +msgstr "" + +#: include/identity.php:802 include/identity.php:813 include/nav.php:85 +#: include/nav.php:149 mod/cal.php:270 mod/events.php:386 +#: view/theme/frio/theme.php:250 view/theme/frio/theme.php:254 +msgid "Events" +msgstr "" + +#: include/identity.php:805 include/identity.php:816 include/nav.php:149 +#: view/theme/frio/theme.php:254 +msgid "Events and Calendar" +msgstr "" + #: include/identity.php:824 mod/notes.php:47 msgid "Personal Notes" msgstr "" @@ -2773,30 +2157,617 @@ msgstr "" msgid "Only You Can See This" msgstr "" -#: include/text.php:304 +#: include/identity.php:835 include/identity.php:838 include/nav.php:128 +#: include/nav.php:192 include/text.php:1024 mod/contacts.php:800 +#: mod/contacts.php:861 mod/viewcontacts.php:121 view/theme/frio/theme.php:257 +msgid "Contacts" +msgstr "" + +#: include/items.php:1584 mod/dfrn_confirm.php:735 mod/dfrn_request.php:754 +msgid "[Name Withheld]" +msgstr "" + +#: include/items.php:1939 mod/admin.php:240 mod/admin.php:1480 +#: mod/admin.php:1731 mod/display.php:103 mod/display.php:279 +#: mod/display.php:484 mod/notice.php:15 mod/viewsrc.php:15 +msgid "Item not found." +msgstr "" + +#: include/items.php:1978 +msgid "Do you really want to delete this item?" +msgstr "" + +#: include/items.php:1980 mod/api.php:105 mod/contacts.php:452 +#: mod/dfrn_request.php:875 mod/follow.php:113 mod/message.php:206 +#: mod/profiles.php:640 mod/profiles.php:643 mod/profiles.php:669 +#: mod/register.php:245 mod/settings.php:1171 mod/settings.php:1177 +#: mod/settings.php:1184 mod/settings.php:1188 mod/settings.php:1193 +#: mod/settings.php:1198 mod/settings.php:1203 mod/settings.php:1208 +#: mod/settings.php:1234 mod/settings.php:1235 mod/settings.php:1236 +#: mod/settings.php:1237 mod/settings.php:1238 mod/suggest.php:29 +msgid "Yes" +msgstr "" + +#: include/items.php:2143 index.php:407 mod/allfriends.php:12 mod/api.php:26 +#: mod/api.php:31 mod/attach.php:33 mod/cal.php:299 mod/common.php:18 +#: mod/contacts.php:360 mod/crepair.php:102 mod/delegate.php:12 +#: mod/dfrn_confirm.php:61 mod/dirfind.php:11 mod/display.php:481 +#: mod/editpost.php:10 mod/events.php:195 mod/follow.php:11 mod/follow.php:74 +#: mod/follow.php:158 mod/fsuggest.php:79 mod/group.php:19 mod/invite.php:15 +#: mod/invite.php:103 mod/item.php:193 mod/item.php:205 mod/manage.php:98 +#: mod/message.php:46 mod/message.php:171 mod/mood.php:115 mod/network.php:4 +#: mod/nogroup.php:27 mod/notes.php:23 mod/notifications.php:71 +#: mod/ostatus_subscribe.php:9 mod/photos.php:161 mod/photos.php:1092 +#: mod/poke.php:154 mod/profile_photo.php:19 mod/profile_photo.php:180 +#: mod/profile_photo.php:191 mod/profile_photo.php:204 mod/profiles.php:166 +#: mod/profiles.php:607 mod/register.php:42 mod/regmod.php:113 +#: mod/repair_ostatus.php:9 mod/settings.php:22 mod/settings.php:130 +#: mod/settings.php:668 mod/suggest.php:58 mod/uimport.php:24 +#: mod/viewcontacts.php:46 mod/wall_attach.php:67 mod/wall_attach.php:70 +#: mod/wall_upload.php:77 mod/wall_upload.php:80 mod/wallmessage.php:9 +#: mod/wallmessage.php:33 mod/wallmessage.php:73 mod/wallmessage.php:97 +msgid "Permission denied." +msgstr "" + +#: include/items.php:2248 +msgid "Archives" +msgstr "" + +#: include/like.php:41 +#, php-format +msgid "%1$s is attending %2$s's %3$s" +msgstr "" + +#: include/like.php:46 +#, php-format +msgid "%1$s is not attending %2$s's %3$s" +msgstr "" + +#: include/like.php:51 +#, php-format +msgid "%1$s may attend %2$s's %3$s" +msgstr "" + +#: include/message.php:15 include/message.php:169 +msgid "[no subject]" +msgstr "" + +#: include/nav.php:35 mod/navigation.php:19 +msgid "Nothing new here" +msgstr "" + +#: include/nav.php:39 mod/navigation.php:23 +msgid "Clear notifications" +msgstr "" + +#: include/nav.php:40 include/text.php:1017 +msgid "@name, !forum, #tags, content" +msgstr "" + +#: include/nav.php:78 view/theme/frio/theme.php:243 +msgid "End this session" +msgstr "" + +#: include/nav.php:81 include/nav.php:161 view/theme/frio/theme.php:246 +msgid "Your posts and conversations" +msgstr "" + +#: include/nav.php:82 view/theme/frio/theme.php:247 +msgid "Your profile page" +msgstr "" + +#: include/nav.php:83 view/theme/frio/theme.php:248 +msgid "Your photos" +msgstr "" + +#: include/nav.php:84 view/theme/frio/theme.php:249 +msgid "Your videos" +msgstr "" + +#: include/nav.php:85 view/theme/frio/theme.php:250 +msgid "Your events" +msgstr "" + +#: include/nav.php:86 +msgid "Personal notes" +msgstr "" + +#: include/nav.php:86 +msgid "Your personal notes" +msgstr "" + +#: include/nav.php:95 +msgid "Sign in" +msgstr "" + +#: include/nav.php:105 +msgid "Home Page" +msgstr "" + +#: include/nav.php:109 +msgid "Create an account" +msgstr "" + +#: include/nav.php:115 mod/help.php:47 view/theme/vier/theme.php:293 +msgid "Help" +msgstr "" + +#: include/nav.php:115 +msgid "Help and documentation" +msgstr "" + +#: include/nav.php:119 +msgid "Apps" +msgstr "" + +#: include/nav.php:119 +msgid "Addon applications, utilities, games" +msgstr "" + +#: include/nav.php:123 include/text.php:1014 mod/search.php:149 +msgid "Search" +msgstr "" + +#: include/nav.php:123 +msgid "Search site content" +msgstr "" + +#: include/nav.php:126 include/text.php:1022 +msgid "Full Text" +msgstr "" + +#: include/nav.php:127 include/text.php:1023 +msgid "Tags" +msgstr "" + +#: include/nav.php:143 include/nav.php:145 mod/community.php:36 +msgid "Community" +msgstr "" + +#: include/nav.php:143 +msgid "Conversations on this site" +msgstr "" + +#: include/nav.php:145 +msgid "Conversations on the network" +msgstr "" + +#: include/nav.php:152 +msgid "Directory" +msgstr "" + +#: include/nav.php:152 +msgid "People directory" +msgstr "" + +#: include/nav.php:154 +msgid "Information" +msgstr "" + +#: include/nav.php:154 +msgid "Information about this friendica instance" +msgstr "" + +#: include/nav.php:158 view/theme/frio/theme.php:253 +msgid "Conversations from your friends" +msgstr "" + +#: include/nav.php:159 +msgid "Network Reset" +msgstr "" + +#: include/nav.php:159 +msgid "Load Network page with no filters" +msgstr "" + +#: include/nav.php:166 +msgid "Friend Requests" +msgstr "" + +#: include/nav.php:169 mod/notifications.php:96 +msgid "Notifications" +msgstr "" + +#: include/nav.php:170 +msgid "See all notifications" +msgstr "" + +#: include/nav.php:171 mod/settings.php:906 +msgid "Mark as seen" +msgstr "" + +#: include/nav.php:171 +msgid "Mark all system notifications seen" +msgstr "" + +#: include/nav.php:175 mod/message.php:179 view/theme/frio/theme.php:255 +msgid "Messages" +msgstr "" + +#: include/nav.php:175 view/theme/frio/theme.php:255 +msgid "Private mail" +msgstr "" + +#: include/nav.php:176 +msgid "Inbox" +msgstr "" + +#: include/nav.php:177 +msgid "Outbox" +msgstr "" + +#: include/nav.php:178 mod/message.php:16 +msgid "New Message" +msgstr "" + +#: include/nav.php:181 +msgid "Manage" +msgstr "" + +#: include/nav.php:181 +msgid "Manage other pages" +msgstr "" + +#: include/nav.php:184 mod/settings.php:81 +msgid "Delegations" +msgstr "" + +#: include/nav.php:184 mod/delegate.php:130 +msgid "Delegate Page Management" +msgstr "" + +#: include/nav.php:186 mod/admin.php:1533 mod/admin.php:1809 +#: mod/newmember.php:22 mod/settings.php:111 view/theme/frio/theme.php:256 +msgid "Settings" +msgstr "" + +#: include/nav.php:186 view/theme/frio/theme.php:256 +msgid "Account settings" +msgstr "" + +#: include/nav.php:189 +msgid "Manage/Edit Profiles" +msgstr "" + +#: include/nav.php:192 view/theme/frio/theme.php:257 +msgid "Manage/edit friends and contacts" +msgstr "" + +#: include/nav.php:197 mod/admin.php:192 +msgid "Admin" +msgstr "" + +#: include/nav.php:197 +msgid "Site setup and configuration" +msgstr "" + +#: include/nav.php:200 +msgid "Navigation" +msgstr "" + +#: include/nav.php:200 +msgid "Site map" +msgstr "" + +#: include/network.php:622 +msgid "view full size" +msgstr "" + +#: include/oembed.php:266 +msgid "Embedded content" +msgstr "" + +#: include/oembed.php:274 +msgid "Embedding disabled" +msgstr "" + +#: include/ostatus.php:1832 +#, php-format +msgid "%s is now following %s." +msgstr "" + +#: include/ostatus.php:1833 +msgid "following" +msgstr "" + +#: include/ostatus.php:1836 +#, php-format +msgid "%s stopped following %s." +msgstr "" + +#: include/ostatus.php:1837 +msgid "stopped following" +msgstr "" + +#: include/photos.php:57 include/photos.php:67 mod/fbrowser.php:40 +#: mod/fbrowser.php:61 mod/photos.php:182 mod/photos.php:1106 +#: mod/photos.php:1231 mod/photos.php:1252 mod/photos.php:1817 +#: mod/photos.php:1829 +msgid "Contact Photos" +msgstr "" + +#: include/plugin.php:530 include/plugin.php:532 +msgid "Click here to upgrade." +msgstr "" + +#: include/plugin.php:538 +msgid "This action exceeds the limits set by your subscription plan." +msgstr "" + +#: include/plugin.php:543 +msgid "This action is not available under your subscription plan." +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Male" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Female" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Currently Male" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Currently Female" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Mostly Male" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Mostly Female" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Transgender" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Intersex" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Transsexual" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Hermaphrodite" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Neuter" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Non-specific" +msgstr "" + +#: include/profile_selectors.php:6 +msgid "Other" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Males" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Females" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Gay" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Lesbian" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "No Preference" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Bisexual" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Autosexual" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Abstinent" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Virgin" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Deviant" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Fetish" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Oodles" +msgstr "" + +#: include/profile_selectors.php:23 +msgid "Nonsexual" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Single" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Lonely" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Available" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Unavailable" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Has crush" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Infatuated" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Dating" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Unfaithful" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Sex Addict" +msgstr "" + +#: include/profile_selectors.php:42 include/user.php:280 include/user.php:284 +msgid "Friends" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Friends/Benefits" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Casual" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Engaged" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Married" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Imaginarily married" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Partners" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Cohabiting" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Common law" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Happy" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Not looking" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Swinger" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Betrayed" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Separated" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Unstable" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Divorced" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Imaginarily divorced" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Widowed" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Uncertain" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "It's complicated" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Don't care" +msgstr "" + +#: include/profile_selectors.php:42 +msgid "Ask me" +msgstr "" + +#: include/security.php:61 +msgid "Welcome " +msgstr "" + +#: include/security.php:62 +msgid "Please upload a profile photo." +msgstr "" + +#: include/security.php:65 +msgid "Welcome back " +msgstr "" + +#: include/security.php:429 +msgid "" +"The form security token was not correct. This probably happened because the " +"form has been opened for too long (>3 hours) before submitting it." +msgstr "" + +#: include/text.php:307 msgid "newer" msgstr "" -#: include/text.php:306 +#: include/text.php:308 msgid "older" msgstr "" -#: include/text.php:311 -msgid "prev" -msgstr "" - #: include/text.php:313 msgid "first" msgstr "" -#: include/text.php:345 -msgid "last" +#: include/text.php:314 +msgid "prev" msgstr "" #: include/text.php:348 msgid "next" msgstr "" +#: include/text.php:349 +msgid "last" +msgstr "" + #: include/text.php:403 msgid "Loading more entries..." msgstr "" @@ -2820,7 +2791,7 @@ msgstr[1] "" msgid "View Contacts" msgstr "" -#: include/text.php:1015 mod/filer.php:31 mod/notes.php:62 mod/editpost.php:99 +#: include/text.php:1015 mod/editpost.php:99 mod/filer.php:31 mod/notes.php:62 msgid "Save" msgstr "" @@ -2976,8 +2947,8 @@ msgstr "" msgid "activity" msgstr "" -#: include/text.php:1810 mod/content.php:623 object/Item.php:446 -#: object/Item.php:458 +#: include/text.php:1810 mod/content.php:623 object/Item.php:419 +#: object/Item.php:431 msgid "comment" msgid_plural "comments" msgstr[0] "" @@ -2991,103 +2962,1569 @@ msgstr "" msgid "Item filed" msgstr "" -#: include/Contact.php:450 -msgid "Drop Contact" +#: include/uimport.php:91 +msgid "Error decoding account file" msgstr "" -#: include/Contact.php:827 -msgid "Organisation" +#: include/uimport.php:97 +msgid "Error! No version data in file! This is not a Friendica account file?" msgstr "" -#: include/Contact.php:830 -msgid "News" +#: include/uimport.php:113 include/uimport.php:124 +msgid "Error! Cannot check nickname" msgstr "" -#: include/Contact.php:833 -msgid "Forum" +#: include/uimport.php:117 include/uimport.php:128 +#, php-format +msgid "User '%s' already exists on this server!" msgstr "" -#: include/items.php:1584 mod/dfrn_confirm.php:735 mod/dfrn_request.php:754 -msgid "[Name Withheld]" +#: include/uimport.php:150 +msgid "User creation error" msgstr "" -#: include/items.php:1939 mod/notice.php:15 mod/viewsrc.php:15 -#: mod/display.php:103 mod/display.php:279 mod/display.php:484 -#: mod/admin.php:235 mod/admin.php:1492 mod/admin.php:1738 -msgid "Item not found." +#: include/uimport.php:170 +msgid "User profile creation error" msgstr "" -#: include/items.php:1978 -msgid "Do you really want to delete this item?" +#: include/uimport.php:219 +#, php-format +msgid "%d contact not imported" +msgid_plural "%d contacts not imported" +msgstr[0] "" +msgstr[1] "" + +#: include/uimport.php:289 +msgid "Done. You can now login with your username and password" msgstr "" -#: include/items.php:1980 mod/api.php:105 mod/follow.php:113 -#: mod/register.php:245 mod/settings.php:1171 mod/settings.php:1177 -#: mod/settings.php:1184 mod/settings.php:1188 mod/settings.php:1193 -#: mod/settings.php:1198 mod/settings.php:1203 mod/settings.php:1208 -#: mod/settings.php:1234 mod/settings.php:1235 mod/settings.php:1236 -#: mod/settings.php:1237 mod/settings.php:1238 mod/suggest.php:29 -#: mod/contacts.php:452 mod/message.php:206 mod/dfrn_request.php:875 -#: mod/profiles.php:640 mod/profiles.php:643 mod/profiles.php:669 -msgid "Yes" +#: include/user.php:39 mod/settings.php:375 +msgid "Passwords do not match. Password unchanged." msgstr "" -#: include/items.php:2143 mod/allfriends.php:12 mod/api.php:26 mod/api.php:31 -#: mod/attach.php:33 mod/common.php:18 mod/crepair.php:102 mod/delegate.php:12 -#: mod/dirfind.php:11 mod/follow.php:11 mod/follow.php:74 mod/follow.php:158 -#: mod/fsuggest.php:79 mod/group.php:19 mod/invite.php:15 mod/invite.php:103 -#: mod/manage.php:98 mod/mood.php:115 mod/nogroup.php:27 mod/notes.php:23 -#: mod/ostatus_subscribe.php:9 mod/poke.php:154 mod/profile_photo.php:19 -#: mod/profile_photo.php:180 mod/profile_photo.php:191 -#: mod/profile_photo.php:204 mod/register.php:42 mod/regmod.php:113 -#: mod/repair_ostatus.php:9 mod/settings.php:22 mod/settings.php:130 -#: mod/settings.php:668 mod/suggest.php:58 mod/uimport.php:24 -#: mod/wall_attach.php:67 mod/wall_attach.php:70 mod/cal.php:299 -#: mod/contacts.php:360 mod/dfrn_confirm.php:61 mod/editpost.php:10 -#: mod/events.php:195 mod/item.php:193 mod/item.php:205 mod/message.php:46 -#: mod/message.php:171 mod/wall_upload.php:77 mod/wall_upload.php:80 -#: mod/wallmessage.php:9 mod/wallmessage.php:33 mod/wallmessage.php:73 -#: mod/wallmessage.php:97 mod/photos.php:161 mod/photos.php:1092 -#: mod/profiles.php:166 mod/profiles.php:607 mod/display.php:481 -#: mod/viewcontacts.php:46 mod/network.php:4 mod/notifications.php:71 -#: index.php:407 -msgid "Permission denied." +#: include/user.php:48 +msgid "An invitation is required." msgstr "" -#: include/items.php:2248 -msgid "Archives" +#: include/user.php:53 +msgid "Invitation could not be verified." msgstr "" -#: include/dbstructure.php:33 +#: include/user.php:61 +msgid "Invalid OpenID url" +msgstr "" + +#: include/user.php:82 +msgid "Please enter the required information." +msgstr "" + +#: include/user.php:96 +msgid "Please use a shorter name." +msgstr "" + +#: include/user.php:98 +msgid "Name too short." +msgstr "" + +#: include/user.php:113 +msgid "That doesn't appear to be your full (First Last) name." +msgstr "" + +#: include/user.php:118 +msgid "Your email domain is not among those allowed on this site." +msgstr "" + +#: include/user.php:121 +msgid "Not a valid email address." +msgstr "" + +#: include/user.php:134 +msgid "Cannot use that email." +msgstr "" + +#: include/user.php:140 +msgid "Your \"nickname\" can only contain \"a-z\", \"0-9\" and \"_\"." +msgstr "" + +#: include/user.php:147 include/user.php:245 +msgid "Nickname is already registered. Please choose another." +msgstr "" + +#: include/user.php:157 +msgid "" +"Nickname was once registered here and may not be re-used. Please choose " +"another." +msgstr "" + +#: include/user.php:173 +msgid "SERIOUS ERROR: Generation of security keys failed." +msgstr "" + +#: include/user.php:231 +msgid "An error occurred during registration. Please try again." +msgstr "" + +#: include/user.php:256 view/theme/duepuntozero/config.php:43 +msgid "default" +msgstr "" + +#: include/user.php:266 +msgid "An error occurred creating your default profile. Please try again." +msgstr "" + +#: include/user.php:326 include/user.php:334 include/user.php:342 +#: mod/photos.php:68 mod/photos.php:182 mod/photos.php:768 mod/photos.php:1231 +#: mod/photos.php:1252 mod/photos.php:1839 mod/profile_photo.php:74 +#: mod/profile_photo.php:82 mod/profile_photo.php:90 mod/profile_photo.php:215 +#: mod/profile_photo.php:310 mod/profile_photo.php:320 +msgid "Profile Photos" +msgstr "" + +#: include/user.php:417 #, php-format msgid "" "\n" -"\t\t\tThe friendica developers released update %s recently,\n" -"\t\t\tbut when I tried to install it, something went terribly wrong.\n" -"\t\t\tThis needs to be fixed soon and I can't do it alone. Please contact a\n" -"\t\t\tfriendica developer if you can not help me on your own. My database " -"might be invalid." +"\t\tDear %1$s,\n" +"\t\t\tThank you for registering at %2$s. Your account is pending for " +"approval by the administrator.\n" +"\t" msgstr "" -#: include/dbstructure.php:38 +#: include/user.php:427 +#, php-format +msgid "Registration at %s" +msgstr "" + +#: include/user.php:437 #, php-format msgid "" -"The error message is\n" -"[pre]%s[/pre]" +"\n" +"\t\tDear %1$s,\n" +"\t\t\tThank you for registering at %2$s. Your account has been created.\n" +"\t" msgstr "" -#: include/dbstructure.php:195 -msgid "Errors encountered creating database tables." +#: include/user.php:441 +#, php-format +msgid "" +"\n" +"\t\tThe login details are as follows:\n" +"\t\t\tSite Location:\t%3$s\n" +"\t\t\tLogin Name:\t%1$s\n" +"\t\t\tPassword:\t%5$s\n" +"\n" +"\t\tYou may change your password from your account \"Settings\" page after " +"logging\n" +"\t\tin.\n" +"\n" +"\t\tPlease take a few moments to review the other account settings on that " +"page.\n" +"\n" +"\t\tYou may also wish to add some basic information to your default profile\n" +"\t\t(on the \"Profiles\" page) so that other people can easily find you.\n" +"\n" +"\t\tWe recommend setting your full name, adding a profile photo,\n" +"\t\tadding some profile \"keywords\" (very useful in making new friends) - " +"and\n" +"\t\tperhaps what country you live in; if you do not wish to be more " +"specific\n" +"\t\tthan that.\n" +"\n" +"\t\tWe fully respect your right to privacy, and none of these items are " +"necessary.\n" +"\t\tIf you are new and do not know anybody here, they may help\n" +"\t\tyou to make some new and interesting friends.\n" +"\n" +"\n" +"\t\tThank you and welcome to %2$s." msgstr "" -#: include/dbstructure.php:329 include/dbstructure.php:337 -#: include/dbstructure.php:345 include/dbstructure.php:350 -#: include/dbstructure.php:355 -msgid "Errors encountered performing database changes." +#: include/user.php:473 mod/admin.php:1223 +#, php-format +msgid "Registration details for %s" msgstr "" -#: include/network.php:619 -msgid "view full size" +#: index.php:248 mod/apps.php:7 +msgid "You must be logged in to use addons. " +msgstr "" + +#: index.php:292 mod/fetch.php:12 mod/fetch.php:39 mod/fetch.php:48 +#: mod/help.php:53 mod/p.php:16 mod/p.php:43 mod/p.php:52 +msgid "Not Found" +msgstr "" + +#: index.php:295 mod/help.php:56 +msgid "Page not found." +msgstr "" + +#: index.php:406 mod/group.php:76 mod/profperm.php:20 +msgid "Permission denied" +msgstr "" + +#: index.php:457 +msgid "toggle mobile" +msgstr "" + +#: mod/admin.php:96 +msgid "Theme settings updated." +msgstr "" + +#: mod/admin.php:162 mod/admin.php:967 +msgid "Site" +msgstr "" + +#: mod/admin.php:163 mod/admin.php:901 mod/admin.php:1413 mod/admin.php:1429 +msgid "Users" +msgstr "" + +#: mod/admin.php:164 mod/admin.php:1531 mod/admin.php:1594 mod/settings.php:74 +msgid "Plugins" +msgstr "" + +#: mod/admin.php:165 mod/admin.php:1807 mod/admin.php:1857 +msgid "Themes" +msgstr "" + +#: mod/admin.php:166 mod/settings.php:52 +msgid "Additional features" +msgstr "" + +#: mod/admin.php:167 +msgid "DB updates" +msgstr "" + +#: mod/admin.php:168 mod/admin.php:416 +msgid "Inspect Queue" +msgstr "" + +#: mod/admin.php:169 mod/admin.php:382 +msgid "Federation Statistics" +msgstr "" + +#: mod/admin.php:183 mod/admin.php:194 mod/admin.php:1931 +msgid "Logs" +msgstr "" + +#: mod/admin.php:184 mod/admin.php:1999 +msgid "View Logs" +msgstr "" + +#: mod/admin.php:185 +msgid "probe address" +msgstr "" + +#: mod/admin.php:186 +msgid "check webfinger" +msgstr "" + +#: mod/admin.php:193 +msgid "Plugin Features" +msgstr "" + +#: mod/admin.php:195 +msgid "diagnostics" +msgstr "" + +#: mod/admin.php:196 +msgid "User registrations waiting for confirmation" +msgstr "" + +#: mod/admin.php:312 +msgid "unknown" +msgstr "" + +#: mod/admin.php:375 +msgid "" +"This page offers you some numbers to the known part of the federated social " +"network your Friendica node is part of. These numbers are not complete but " +"only reflect the part of the network your node is aware of." +msgstr "" + +#: mod/admin.php:376 +msgid "" +"The Auto Discovered Contact Directory feature is not enabled, it " +"will improve the data displayed here." +msgstr "" + +#: mod/admin.php:381 mod/admin.php:415 mod/admin.php:493 mod/admin.php:966 +#: mod/admin.php:1412 mod/admin.php:1530 mod/admin.php:1593 mod/admin.php:1806 +#: mod/admin.php:1856 mod/admin.php:1930 mod/admin.php:1998 +msgid "Administration" +msgstr "" + +#: mod/admin.php:388 +#, php-format +msgid "Currently this node is aware of %d nodes from the following platforms:" +msgstr "" + +#: mod/admin.php:418 +msgid "ID" +msgstr "" + +#: mod/admin.php:419 +msgid "Recipient Name" +msgstr "" + +#: mod/admin.php:420 +msgid "Recipient Profile" +msgstr "" + +#: mod/admin.php:422 +msgid "Created" +msgstr "" + +#: mod/admin.php:423 +msgid "Last Tried" +msgstr "" + +#: mod/admin.php:424 +msgid "" +"This page lists the content of the queue for outgoing postings. These are " +"postings the initial delivery failed for. They will be resend later and " +"eventually deleted if the delivery fails permanently." +msgstr "" + +#: mod/admin.php:449 +#, php-format +msgid "" +"Your DB still runs with MyISAM tables. You should change the engine type to " +"InnoDB. As Friendica will use InnoDB only features in the future, you should " +"change this! See here for a guide that may be helpful " +"converting the table engines. You may also use the convert_innodb.sql in the /util directory of your Friendica installation.
    " +msgstr "" + +#: mod/admin.php:454 +msgid "" +"You are using a MySQL version which does not support all features that " +"Friendica uses. You should consider switching to MariaDB." +msgstr "" + +#: mod/admin.php:458 mod/admin.php:1362 +msgid "Normal Account" +msgstr "" + +#: mod/admin.php:459 mod/admin.php:1363 +msgid "Soapbox Account" +msgstr "" + +#: mod/admin.php:460 mod/admin.php:1364 +msgid "Community/Celebrity Account" +msgstr "" + +#: mod/admin.php:461 mod/admin.php:1365 +msgid "Automatic Friend Account" +msgstr "" + +#: mod/admin.php:462 +msgid "Blog Account" +msgstr "" + +#: mod/admin.php:463 +msgid "Private Forum" +msgstr "" + +#: mod/admin.php:488 +msgid "Message queues" +msgstr "" + +#: mod/admin.php:494 +msgid "Summary" +msgstr "" + +#: mod/admin.php:496 +msgid "Registered users" +msgstr "" + +#: mod/admin.php:498 +msgid "Pending registrations" +msgstr "" + +#: mod/admin.php:499 +msgid "Version" +msgstr "" + +#: mod/admin.php:504 +msgid "Active plugins" +msgstr "" + +#: mod/admin.php:529 +msgid "Can not parse base url. Must have at least ://" +msgstr "" + +#: mod/admin.php:819 +msgid "RINO2 needs mcrypt php extension to work." +msgstr "" + +#: mod/admin.php:827 +msgid "Site settings updated." +msgstr "" + +#: mod/admin.php:855 mod/settings.php:943 +msgid "No special theme for mobile devices" +msgstr "" + +#: mod/admin.php:884 +msgid "No community page" +msgstr "" + +#: mod/admin.php:885 +msgid "Public postings from users of this site" +msgstr "" + +#: mod/admin.php:886 +msgid "Global community page" +msgstr "" + +#: mod/admin.php:891 mod/contacts.php:538 +msgid "Never" +msgstr "" + +#: mod/admin.php:892 +msgid "At post arrival" +msgstr "" + +#: mod/admin.php:900 mod/contacts.php:565 +msgid "Disabled" +msgstr "" + +#: mod/admin.php:902 +msgid "Users, Global Contacts" +msgstr "" + +#: mod/admin.php:903 +msgid "Users, Global Contacts/fallback" +msgstr "" + +#: mod/admin.php:907 +msgid "One month" +msgstr "" + +#: mod/admin.php:908 +msgid "Three months" +msgstr "" + +#: mod/admin.php:909 +msgid "Half a year" +msgstr "" + +#: mod/admin.php:910 +msgid "One year" +msgstr "" + +#: mod/admin.php:915 +msgid "Multi user instance" +msgstr "" + +#: mod/admin.php:938 +msgid "Closed" +msgstr "" + +#: mod/admin.php:939 +msgid "Requires approval" +msgstr "" + +#: mod/admin.php:940 +msgid "Open" +msgstr "" + +#: mod/admin.php:944 +msgid "No SSL policy, links will track page SSL state" +msgstr "" + +#: mod/admin.php:945 +msgid "Force all links to use SSL" +msgstr "" + +#: mod/admin.php:946 +msgid "Self-signed certificate, use SSL for local links only (discouraged)" +msgstr "" + +#: mod/admin.php:968 mod/admin.php:1595 mod/admin.php:1858 mod/admin.php:1932 +#: mod/admin.php:2085 mod/settings.php:681 mod/settings.php:792 +#: mod/settings.php:841 mod/settings.php:908 mod/settings.php:1005 +#: mod/settings.php:1271 +msgid "Save Settings" +msgstr "" + +#: mod/admin.php:969 mod/register.php:272 +msgid "Registration" +msgstr "" + +#: mod/admin.php:970 +msgid "File upload" +msgstr "" + +#: mod/admin.php:971 +msgid "Policies" +msgstr "" + +#: mod/admin.php:973 +msgid "Auto Discovered Contact Directory" +msgstr "" + +#: mod/admin.php:974 +msgid "Performance" +msgstr "" + +#: mod/admin.php:975 +msgid "Worker" +msgstr "" + +#: mod/admin.php:976 +msgid "" +"Relocate - WARNING: advanced function. Could make this server unreachable." +msgstr "" + +#: mod/admin.php:979 +msgid "Site name" +msgstr "" + +#: mod/admin.php:980 +msgid "Host name" +msgstr "" + +#: mod/admin.php:981 +msgid "Sender Email" +msgstr "" + +#: mod/admin.php:981 +msgid "" +"The email address your server shall use to send notification emails from." +msgstr "" + +#: mod/admin.php:982 +msgid "Banner/Logo" +msgstr "" + +#: mod/admin.php:983 +msgid "Shortcut icon" +msgstr "" + +#: mod/admin.php:983 +msgid "Link to an icon that will be used for browsers." +msgstr "" + +#: mod/admin.php:984 +msgid "Touch icon" +msgstr "" + +#: mod/admin.php:984 +msgid "Link to an icon that will be used for tablets and mobiles." +msgstr "" + +#: mod/admin.php:985 +msgid "Additional Info" +msgstr "" + +#: mod/admin.php:985 +#, php-format +msgid "" +"For public servers: you can add additional information here that will be " +"listed at %s/siteinfo." +msgstr "" + +#: mod/admin.php:986 +msgid "System language" +msgstr "" + +#: mod/admin.php:987 +msgid "System theme" +msgstr "" + +#: mod/admin.php:987 +msgid "" +"Default system theme - may be over-ridden by user profiles - change theme settings" +msgstr "" + +#: mod/admin.php:988 +msgid "Mobile system theme" +msgstr "" + +#: mod/admin.php:988 +msgid "Theme for mobile devices" +msgstr "" + +#: mod/admin.php:989 +msgid "SSL link policy" +msgstr "" + +#: mod/admin.php:989 +msgid "Determines whether generated links should be forced to use SSL" +msgstr "" + +#: mod/admin.php:990 +msgid "Force SSL" +msgstr "" + +#: mod/admin.php:990 +msgid "" +"Force all Non-SSL requests to SSL - Attention: on some systems it could lead " +"to endless loops." +msgstr "" + +#: mod/admin.php:991 +msgid "Hide help entry from navigation menu" +msgstr "" + +#: mod/admin.php:991 +msgid "" +"Hides the menu entry for the Help pages from the navigation menu. You can " +"still access it calling /help directly." +msgstr "" + +#: mod/admin.php:992 +msgid "Single user instance" +msgstr "" + +#: mod/admin.php:992 +msgid "Make this instance multi-user or single-user for the named user" +msgstr "" + +#: mod/admin.php:993 +msgid "Maximum image size" +msgstr "" + +#: mod/admin.php:993 +msgid "" +"Maximum size in bytes of uploaded images. Default is 0, which means no " +"limits." +msgstr "" + +#: mod/admin.php:994 +msgid "Maximum image length" +msgstr "" + +#: mod/admin.php:994 +msgid "" +"Maximum length in pixels of the longest side of uploaded images. Default is " +"-1, which means no limits." +msgstr "" + +#: mod/admin.php:995 +msgid "JPEG image quality" +msgstr "" + +#: mod/admin.php:995 +msgid "" +"Uploaded JPEGS will be saved at this quality setting [0-100]. Default is " +"100, which is full quality." +msgstr "" + +#: mod/admin.php:997 +msgid "Register policy" +msgstr "" + +#: mod/admin.php:998 +msgid "Maximum Daily Registrations" +msgstr "" + +#: mod/admin.php:998 +msgid "" +"If registration is permitted above, this sets the maximum number of new user " +"registrations to accept per day. If register is set to closed, this setting " +"has no effect." +msgstr "" + +#: mod/admin.php:999 +msgid "Register text" +msgstr "" + +#: mod/admin.php:999 +msgid "Will be displayed prominently on the registration page." +msgstr "" + +#: mod/admin.php:1000 +msgid "Accounts abandoned after x days" +msgstr "" + +#: mod/admin.php:1000 +msgid "" +"Will not waste system resources polling external sites for abandonded " +"accounts. Enter 0 for no time limit." +msgstr "" + +#: mod/admin.php:1001 +msgid "Allowed friend domains" +msgstr "" + +#: mod/admin.php:1001 +msgid "" +"Comma separated list of domains which are allowed to establish friendships " +"with this site. Wildcards are accepted. Empty to allow any domains" +msgstr "" + +#: mod/admin.php:1002 +msgid "Allowed email domains" +msgstr "" + +#: mod/admin.php:1002 +msgid "" +"Comma separated list of domains which are allowed in email addresses for " +"registrations to this site. Wildcards are accepted. Empty to allow any " +"domains" +msgstr "" + +#: mod/admin.php:1003 +msgid "Block public" +msgstr "" + +#: mod/admin.php:1003 +msgid "" +"Check to block public access to all otherwise public personal pages on this " +"site unless you are currently logged in." +msgstr "" + +#: mod/admin.php:1004 +msgid "Force publish" +msgstr "" + +#: mod/admin.php:1004 +msgid "" +"Check to force all profiles on this site to be listed in the site directory." +msgstr "" + +#: mod/admin.php:1005 +msgid "Global directory URL" +msgstr "" + +#: mod/admin.php:1005 +msgid "" +"URL to the global directory. If this is not set, the global directory is " +"completely unavailable to the application." +msgstr "" + +#: mod/admin.php:1006 +msgid "Allow threaded items" +msgstr "" + +#: mod/admin.php:1006 +msgid "Allow infinite level threading for items on this site." +msgstr "" + +#: mod/admin.php:1007 +msgid "Private posts by default for new users" +msgstr "" + +#: mod/admin.php:1007 +msgid "" +"Set default post permissions for all new members to the default privacy " +"group rather than public." +msgstr "" + +#: mod/admin.php:1008 +msgid "Don't include post content in email notifications" +msgstr "" + +#: mod/admin.php:1008 +msgid "" +"Don't include the content of a post/comment/private message/etc. in the " +"email notifications that are sent out from this site, as a privacy measure." +msgstr "" + +#: mod/admin.php:1009 +msgid "Disallow public access to addons listed in the apps menu." +msgstr "" + +#: mod/admin.php:1009 +msgid "" +"Checking this box will restrict addons listed in the apps menu to members " +"only." +msgstr "" + +#: mod/admin.php:1010 +msgid "Don't embed private images in posts" +msgstr "" + +#: mod/admin.php:1010 +msgid "" +"Don't replace locally-hosted private photos in posts with an embedded copy " +"of the image. This means that contacts who receive posts containing private " +"photos will have to authenticate and load each image, which may take a while." +msgstr "" + +#: mod/admin.php:1011 +msgid "Allow Users to set remote_self" +msgstr "" + +#: mod/admin.php:1011 +msgid "" +"With checking this, every user is allowed to mark every contact as a " +"remote_self in the repair contact dialog. Setting this flag on a contact " +"causes mirroring every posting of that contact in the users stream." +msgstr "" + +#: mod/admin.php:1012 +msgid "Block multiple registrations" +msgstr "" + +#: mod/admin.php:1012 +msgid "Disallow users to register additional accounts for use as pages." +msgstr "" + +#: mod/admin.php:1013 +msgid "OpenID support" +msgstr "" + +#: mod/admin.php:1013 +msgid "OpenID support for registration and logins." +msgstr "" + +#: mod/admin.php:1014 +msgid "Fullname check" +msgstr "" + +#: mod/admin.php:1014 +msgid "" +"Force users to register with a space between firstname and lastname in Full " +"name, as an antispam measure" +msgstr "" + +#: mod/admin.php:1015 +msgid "UTF-8 Regular expressions" +msgstr "" + +#: mod/admin.php:1015 +msgid "Use PHP UTF8 regular expressions" +msgstr "" + +#: mod/admin.php:1016 +msgid "Community Page Style" +msgstr "" + +#: mod/admin.php:1016 +msgid "" +"Type of community page to show. 'Global community' shows every public " +"posting from an open distributed network that arrived on this server." +msgstr "" + +#: mod/admin.php:1017 +msgid "Posts per user on community page" +msgstr "" + +#: mod/admin.php:1017 +msgid "" +"The maximum number of posts per user on the community page. (Not valid for " +"'Global Community')" +msgstr "" + +#: mod/admin.php:1018 +msgid "Enable OStatus support" +msgstr "" + +#: mod/admin.php:1018 +msgid "" +"Provide built-in OStatus (StatusNet, GNU Social etc.) compatibility. All " +"communications in OStatus are public, so privacy warnings will be " +"occasionally displayed." +msgstr "" + +#: mod/admin.php:1019 +msgid "OStatus conversation completion interval" +msgstr "" + +#: mod/admin.php:1019 +msgid "" +"How often shall the poller check for new entries in OStatus conversations? " +"This can be a very ressource task." +msgstr "" + +#: mod/admin.php:1020 +msgid "Only import OStatus threads from our contacts" +msgstr "" + +#: mod/admin.php:1020 +msgid "" +"Normally we import every content from our OStatus contacts. With this option " +"we only store threads that are started by a contact that is known on our " +"system." +msgstr "" + +#: mod/admin.php:1021 +msgid "OStatus support can only be enabled if threading is enabled." +msgstr "" + +#: mod/admin.php:1023 +msgid "" +"Diaspora support can't be enabled because Friendica was installed into a sub " +"directory." +msgstr "" + +#: mod/admin.php:1024 +msgid "Enable Diaspora support" +msgstr "" + +#: mod/admin.php:1024 +msgid "Provide built-in Diaspora network compatibility." +msgstr "" + +#: mod/admin.php:1025 +msgid "Only allow Friendica contacts" +msgstr "" + +#: mod/admin.php:1025 +msgid "" +"All contacts must use Friendica protocols. All other built-in communication " +"protocols disabled." +msgstr "" + +#: mod/admin.php:1026 +msgid "Verify SSL" +msgstr "" + +#: mod/admin.php:1026 +msgid "" +"If you wish, you can turn on strict certificate checking. This will mean you " +"cannot connect (at all) to self-signed SSL sites." +msgstr "" + +#: mod/admin.php:1027 +msgid "Proxy user" +msgstr "" + +#: mod/admin.php:1028 +msgid "Proxy URL" +msgstr "" + +#: mod/admin.php:1029 +msgid "Network timeout" +msgstr "" + +#: mod/admin.php:1029 +msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." +msgstr "" + +#: mod/admin.php:1030 +msgid "Maximum Load Average" +msgstr "" + +#: mod/admin.php:1030 +msgid "" +"Maximum system load before delivery and poll processes are deferred - " +"default 50." +msgstr "" + +#: mod/admin.php:1031 +msgid "Maximum Load Average (Frontend)" +msgstr "" + +#: mod/admin.php:1031 +msgid "Maximum system load before the frontend quits service - default 50." +msgstr "" + +#: mod/admin.php:1032 +msgid "Maximum table size for optimization" +msgstr "" + +#: mod/admin.php:1032 +msgid "" +"Maximum table size (in MB) for the automatic optimization - default 100 MB. " +"Enter -1 to disable it." +msgstr "" + +#: mod/admin.php:1033 +msgid "Minimum level of fragmentation" +msgstr "" + +#: mod/admin.php:1033 +msgid "" +"Minimum fragmenation level to start the automatic optimization - default " +"value is 30%." +msgstr "" + +#: mod/admin.php:1035 +msgid "Periodical check of global contacts" +msgstr "" + +#: mod/admin.php:1035 +msgid "" +"If enabled, the global contacts are checked periodically for missing or " +"outdated data and the vitality of the contacts and servers." +msgstr "" + +#: mod/admin.php:1036 +msgid "Days between requery" +msgstr "" + +#: mod/admin.php:1036 +msgid "Number of days after which a server is requeried for his contacts." +msgstr "" + +#: mod/admin.php:1037 +msgid "Discover contacts from other servers" +msgstr "" + +#: mod/admin.php:1037 +msgid "" +"Periodically query other servers for contacts. You can choose between " +"'users': the users on the remote system, 'Global Contacts': active contacts " +"that are known on the system. The fallback is meant for Redmatrix servers " +"and older friendica servers, where global contacts weren't available. The " +"fallback increases the server load, so the recommened setting is 'Users, " +"Global Contacts'." +msgstr "" + +#: mod/admin.php:1038 +msgid "Timeframe for fetching global contacts" +msgstr "" + +#: mod/admin.php:1038 +msgid "" +"When the discovery is activated, this value defines the timeframe for the " +"activity of the global contacts that are fetched from other servers." +msgstr "" + +#: mod/admin.php:1039 +msgid "Search the local directory" +msgstr "" + +#: mod/admin.php:1039 +msgid "" +"Search the local directory instead of the global directory. When searching " +"locally, every search will be executed on the global directory in the " +"background. This improves the search results when the search is repeated." +msgstr "" + +#: mod/admin.php:1041 +msgid "Publish server information" +msgstr "" + +#: mod/admin.php:1041 +msgid "" +"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 the-federation.info for details." +msgstr "" + +#: mod/admin.php:1043 +msgid "Use MySQL full text engine" +msgstr "" + +#: mod/admin.php:1043 +msgid "" +"Activates the full text engine. Speeds up search - but can only search for " +"four and more characters." +msgstr "" + +#: mod/admin.php:1044 +msgid "Suppress Tags" +msgstr "" + +#: mod/admin.php:1044 +msgid "Suppress showing a list of hashtags at the end of the posting." +msgstr "" + +#: mod/admin.php:1045 +msgid "Path to item cache" +msgstr "" + +#: mod/admin.php:1045 +msgid "The item caches buffers generated bbcode and external images." +msgstr "" + +#: mod/admin.php:1046 +msgid "Cache duration in seconds" +msgstr "" + +#: mod/admin.php:1046 +msgid "" +"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." +msgstr "" + +#: mod/admin.php:1047 +msgid "Maximum numbers of comments per post" +msgstr "" + +#: mod/admin.php:1047 +msgid "How much comments should be shown for each post? Default value is 100." +msgstr "" + +#: mod/admin.php:1048 +msgid "Temp path" +msgstr "" + +#: mod/admin.php:1048 +msgid "" +"If you have a restricted system where the webserver can't access the system " +"temp path, enter another path here." +msgstr "" + +#: mod/admin.php:1049 +msgid "Base path to installation" +msgstr "" + +#: mod/admin.php:1049 +msgid "" +"If the system cannot detect the correct path to your installation, enter the " +"correct path here. This setting should only be set if you are using a " +"restricted system and symbolic links to your webroot." +msgstr "" + +#: mod/admin.php:1050 +msgid "Disable picture proxy" +msgstr "" + +#: mod/admin.php:1050 +msgid "" +"The picture proxy increases performance and privacy. It shouldn't be used on " +"systems with very low bandwith." +msgstr "" + +#: mod/admin.php:1051 +msgid "Only search in tags" +msgstr "" + +#: mod/admin.php:1051 +msgid "On large systems the text search can slow down the system extremely." +msgstr "" + +#: mod/admin.php:1053 +msgid "New base url" +msgstr "" + +#: mod/admin.php:1053 +msgid "" +"Change base url for this server. Sends relocate message to all DFRN contacts " +"of all users." +msgstr "" + +#: mod/admin.php:1055 +msgid "RINO Encryption" +msgstr "" + +#: mod/admin.php:1055 +msgid "Encryption layer between nodes." +msgstr "" + +#: mod/admin.php:1056 +msgid "Embedly API key" +msgstr "" + +#: mod/admin.php:1056 +msgid "" +"Embedly is used to fetch additional data for " +"web pages. This is an optional parameter." +msgstr "" + +#: mod/admin.php:1058 +msgid "Maximum number of parallel workers" +msgstr "" + +#: mod/admin.php:1058 +msgid "" +"On shared hosters set this to 2. On larger systems, values of 10 are great. " +"Default value is 4." +msgstr "" + +#: mod/admin.php:1059 +msgid "Don't use 'proc_open' with the worker" +msgstr "" + +#: mod/admin.php:1059 +msgid "" +"Enable this if your system doesn't allow the use of 'proc_open'. This can " +"happen on shared hosters. If this is enabled you should increase the " +"frequency of poller calls in your crontab." +msgstr "" + +#: mod/admin.php:1060 +msgid "Enable fastlane" +msgstr "" + +#: mod/admin.php:1060 +msgid "" +"When enabed, the fastlane mechanism starts an additional worker if processes " +"with higher priority are blocked by processes of lower priority." +msgstr "" + +#: mod/admin.php:1061 +msgid "Enable frontend worker" +msgstr "" + +#: mod/admin.php:1061 +msgid "" +"When enabled the Worker process is triggered when backend access is " +"performed (e.g. messages being delivered). On smaller sites you might want " +"to call yourdomain.tld/worker on a regular basis via an external cron job. " +"You should only enable this option if you cannot utilize cron/scheduled jobs " +"on your server. The worker background process needs to be activated for this." +msgstr "" + +#: mod/admin.php:1091 +msgid "Update has been marked successful" +msgstr "" + +#: mod/admin.php:1099 +#, php-format +msgid "Database structure update %s was successfully applied." +msgstr "" + +#: mod/admin.php:1102 +#, php-format +msgid "Executing of database structure update %s failed with error: %s" +msgstr "" + +#: mod/admin.php:1116 +#, php-format +msgid "Executing %s failed with error: %s" +msgstr "" + +#: mod/admin.php:1119 +#, php-format +msgid "Update %s was successfully applied." +msgstr "" + +#: mod/admin.php:1122 +#, php-format +msgid "Update %s did not return a status. Unknown if it succeeded." +msgstr "" + +#: mod/admin.php:1125 +#, php-format +msgid "There was no additional update function %s that needed to be called." +msgstr "" + +#: mod/admin.php:1145 +msgid "No failed updates." +msgstr "" + +#: mod/admin.php:1146 +msgid "Check database structure" +msgstr "" + +#: mod/admin.php:1151 +msgid "Failed Updates" +msgstr "" + +#: mod/admin.php:1152 +msgid "" +"This does not include updates prior to 1139, which did not return a status." +msgstr "" + +#: mod/admin.php:1153 +msgid "Mark success (if update was manually applied)" +msgstr "" + +#: mod/admin.php:1154 +msgid "Attempt to execute this update step automatically" +msgstr "" + +#: mod/admin.php:1188 +#, php-format +msgid "" +"\n" +"\t\t\tDear %1$s,\n" +"\t\t\t\tthe administrator of %2$s has set up an account for you." +msgstr "" + +#: mod/admin.php:1191 +#, php-format +msgid "" +"\n" +"\t\t\tThe login details are as follows:\n" +"\n" +"\t\t\tSite Location:\t%1$s\n" +"\t\t\tLogin Name:\t\t%2$s\n" +"\t\t\tPassword:\t\t%3$s\n" +"\n" +"\t\t\tYou may change your password from your account \"Settings\" page after " +"logging\n" +"\t\t\tin.\n" +"\n" +"\t\t\tPlease take a few moments to review the other account settings on that " +"page.\n" +"\n" +"\t\t\tYou may also wish to add some basic information to your default " +"profile\n" +"\t\t\t(on the \"Profiles\" page) so that other people can easily find you.\n" +"\n" +"\t\t\tWe recommend setting your full name, adding a profile photo,\n" +"\t\t\tadding some profile \"keywords\" (very useful in making new friends) - " +"and\n" +"\t\t\tperhaps what country you live in; if you do not wish to be more " +"specific\n" +"\t\t\tthan that.\n" +"\n" +"\t\t\tWe fully respect your right to privacy, and none of these items are " +"necessary.\n" +"\t\t\tIf you are new and do not know anybody here, they may help\n" +"\t\t\tyou to make some new and interesting friends.\n" +"\n" +"\t\t\tThank you and welcome to %4$s." +msgstr "" + +#: mod/admin.php:1235 +#, php-format +msgid "%s user blocked/unblocked" +msgid_plural "%s users blocked/unblocked" +msgstr[0] "" +msgstr[1] "" + +#: mod/admin.php:1242 +#, php-format +msgid "%s user deleted" +msgid_plural "%s users deleted" +msgstr[0] "" +msgstr[1] "" + +#: mod/admin.php:1289 +#, php-format +msgid "User '%s' deleted" +msgstr "" + +#: mod/admin.php:1297 +#, php-format +msgid "User '%s' unblocked" +msgstr "" + +#: mod/admin.php:1297 +#, php-format +msgid "User '%s' blocked" +msgstr "" + +#: mod/admin.php:1405 mod/admin.php:1418 mod/admin.php:1431 mod/admin.php:1447 +#: mod/crepair.php:167 mod/settings.php:683 mod/settings.php:709 +msgid "Name" +msgstr "" + +#: mod/admin.php:1405 mod/admin.php:1431 +msgid "Register date" +msgstr "" + +#: mod/admin.php:1405 mod/admin.php:1431 +msgid "Last login" +msgstr "" + +#: mod/admin.php:1405 mod/admin.php:1431 +msgid "Last item" +msgstr "" + +#: mod/admin.php:1405 mod/settings.php:43 +msgid "Account" +msgstr "" + +#: mod/admin.php:1414 +msgid "Add User" +msgstr "" + +#: mod/admin.php:1415 +msgid "select all" +msgstr "" + +#: mod/admin.php:1416 +msgid "User registrations waiting for confirm" +msgstr "" + +#: mod/admin.php:1417 +msgid "User waiting for permanent deletion" +msgstr "" + +#: mod/admin.php:1418 +msgid "Request date" +msgstr "" + +#: mod/admin.php:1419 +msgid "No registrations." +msgstr "" + +#: mod/admin.php:1420 +msgid "Note from the user" +msgstr "" + +#: mod/admin.php:1421 mod/notifications.php:176 mod/notifications.php:255 +msgid "Approve" +msgstr "" + +#: mod/admin.php:1422 +msgid "Deny" +msgstr "" + +#: mod/admin.php:1424 mod/contacts.php:613 mod/contacts.php:813 +#: mod/contacts.php:991 +msgid "Block" +msgstr "" + +#: mod/admin.php:1425 mod/contacts.php:613 mod/contacts.php:813 +#: mod/contacts.php:991 +msgid "Unblock" +msgstr "" + +#: mod/admin.php:1426 +msgid "Site admin" +msgstr "" + +#: mod/admin.php:1427 +msgid "Account expired" +msgstr "" + +#: mod/admin.php:1430 +msgid "New User" +msgstr "" + +#: mod/admin.php:1431 +msgid "Deleted since" +msgstr "" + +#: mod/admin.php:1436 +msgid "" +"Selected users will be deleted!\\n\\nEverything these users had posted on " +"this site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" + +#: mod/admin.php:1437 +msgid "" +"The user {0} will be deleted!\\n\\nEverything this user has posted on this " +"site will be permanently deleted!\\n\\nAre you sure?" +msgstr "" + +#: mod/admin.php:1447 +msgid "Name of the new user." +msgstr "" + +#: mod/admin.php:1448 +msgid "Nickname" +msgstr "" + +#: mod/admin.php:1448 +msgid "Nickname of the new user." +msgstr "" + +#: mod/admin.php:1449 +msgid "Email address of the new user." +msgstr "" + +#: mod/admin.php:1492 +#, php-format +msgid "Plugin %s disabled." +msgstr "" + +#: mod/admin.php:1496 +#, php-format +msgid "Plugin %s enabled." +msgstr "" + +#: mod/admin.php:1507 mod/admin.php:1759 +msgid "Disable" +msgstr "" + +#: mod/admin.php:1509 mod/admin.php:1761 +msgid "Enable" +msgstr "" + +#: mod/admin.php:1532 mod/admin.php:1808 +msgid "Toggle" +msgstr "" + +#: mod/admin.php:1540 mod/admin.php:1817 +msgid "Author: " +msgstr "" + +#: mod/admin.php:1541 mod/admin.php:1818 +msgid "Maintainer: " +msgstr "" + +#: mod/admin.php:1596 +msgid "Reload active plugins" +msgstr "" + +#: mod/admin.php:1601 +#, php-format +msgid "" +"There are currently no plugins available on your node. You can find the " +"official plugin repository at %1$s and might find other interesting plugins " +"in the open plugin registry at %2$s" +msgstr "" + +#: mod/admin.php:1720 +msgid "No themes found." +msgstr "" + +#: mod/admin.php:1799 +msgid "Screenshot" +msgstr "" + +#: mod/admin.php:1859 +msgid "Reload active themes" +msgstr "" + +#: mod/admin.php:1864 +#, php-format +msgid "No themes found on the system. They should be paced in %1$s" +msgstr "" + +#: mod/admin.php:1865 +msgid "[Experimental]" +msgstr "" + +#: mod/admin.php:1866 +msgid "[Unsupported]" +msgstr "" + +#: mod/admin.php:1890 +msgid "Log settings updated." +msgstr "" + +#: mod/admin.php:1922 +msgid "PHP log currently enabled." +msgstr "" + +#: mod/admin.php:1924 +msgid "PHP log currently disabled." +msgstr "" + +#: mod/admin.php:1933 +msgid "Clear" +msgstr "" + +#: mod/admin.php:1938 +msgid "Enable Debugging" +msgstr "" + +#: mod/admin.php:1939 +msgid "Log file" +msgstr "" + +#: mod/admin.php:1939 +msgid "" +"Must be writable by web server. Relative to your Friendica top-level " +"directory." +msgstr "" + +#: mod/admin.php:1940 +msgid "Log level" +msgstr "" + +#: mod/admin.php:1943 +msgid "PHP logging" +msgstr "" + +#: mod/admin.php:1944 +msgid "" +"To enable logging of PHP errors and warnings you can add the following to " +"the .htconfig.php file of your installation. The filename set in the " +"'error_log' line is relative to the friendica top-level directory and must " +"be writeable by the web server. The option '1' for 'log_errors' and " +"'display_errors' is to enable these options, set to '0' to disable them." +msgstr "" + +#: mod/admin.php:2074 mod/admin.php:2075 mod/settings.php:782 +msgid "Off" +msgstr "" + +#: mod/admin.php:2074 mod/admin.php:2075 mod/settings.php:782 +msgid "On" +msgstr "" + +#: mod/admin.php:2075 +#, php-format +msgid "Lock feature %s" +msgstr "" + +#: mod/admin.php:2083 +msgid "Manage Additional Features" msgstr "" #: mod/allfriends.php:46 @@ -3112,20 +4549,16 @@ msgid "" "and/or create new posts for you?" msgstr "" -#: mod/api.php:106 mod/follow.php:113 mod/register.php:246 -#: mod/settings.php:1171 mod/settings.php:1177 mod/settings.php:1184 -#: mod/settings.php:1188 mod/settings.php:1193 mod/settings.php:1198 -#: mod/settings.php:1203 mod/settings.php:1208 mod/settings.php:1234 -#: mod/settings.php:1235 mod/settings.php:1236 mod/settings.php:1237 -#: mod/settings.php:1238 mod/dfrn_request.php:875 mod/profiles.php:640 -#: mod/profiles.php:644 mod/profiles.php:669 +#: mod/api.php:106 mod/dfrn_request.php:875 mod/follow.php:113 +#: mod/profiles.php:640 mod/profiles.php:644 mod/profiles.php:669 +#: mod/register.php:246 mod/settings.php:1171 mod/settings.php:1177 +#: mod/settings.php:1184 mod/settings.php:1188 mod/settings.php:1193 +#: mod/settings.php:1198 mod/settings.php:1203 mod/settings.php:1208 +#: mod/settings.php:1234 mod/settings.php:1235 mod/settings.php:1236 +#: mod/settings.php:1237 mod/settings.php:1238 msgid "No" msgstr "" -#: mod/apps.php:7 index.php:248 -msgid "You must be logged in to use addons. " -msgstr "" - #: mod/apps.php:11 msgid "Applications" msgstr "" @@ -3194,2229 +4627,10 @@ msgstr "" msgid "The post was created" msgstr "" -#: mod/common.php:91 -msgid "No contacts in common." -msgstr "" - -#: mod/common.php:141 mod/contacts.php:871 -msgid "Common Friends" -msgstr "" - -#: mod/community.php:22 mod/directory.php:37 mod/videos.php:198 -#: mod/photos.php:964 mod/dfrn_request.php:799 mod/display.php:200 -#: mod/viewcontacts.php:36 mod/search.php:93 mod/search.php:99 -msgid "Public access denied." -msgstr "" - -#: mod/community.php:27 -msgid "Not available." -msgstr "" - -#: mod/community.php:66 mod/community.php:75 mod/search.php:224 -msgid "No results." -msgstr "" - -#: mod/content.php:119 mod/network.php:468 -msgid "No such group" -msgstr "" - -#: mod/content.php:130 mod/group.php:203 mod/network.php:495 -msgid "Group is empty" -msgstr "" - -#: mod/content.php:135 mod/network.php:499 -#, php-format -msgid "Group: %s" -msgstr "" - -#: mod/content.php:325 object/Item.php:96 -msgid "This entry was edited" -msgstr "" - -#: mod/content.php:621 object/Item.php:444 -#, php-format -msgid "%d comment" -msgid_plural "%d comments" -msgstr[0] "" -msgstr[1] "" - -#: mod/content.php:638 mod/photos.php:1402 object/Item.php:117 -msgid "Private Message" -msgstr "" - -#: mod/content.php:702 mod/photos.php:1590 object/Item.php:274 -msgid "I like this (toggle)" -msgstr "" - -#: mod/content.php:702 object/Item.php:274 -msgid "like" -msgstr "" - -#: mod/content.php:703 mod/photos.php:1591 object/Item.php:275 -msgid "I don't like this (toggle)" -msgstr "" - -#: mod/content.php:703 object/Item.php:275 -msgid "dislike" -msgstr "" - -#: mod/content.php:705 object/Item.php:278 -msgid "Share this" -msgstr "" - -#: mod/content.php:705 object/Item.php:278 -msgid "share" -msgstr "" - -#: mod/content.php:725 mod/photos.php:1609 mod/photos.php:1657 -#: mod/photos.php:1743 object/Item.php:729 -msgid "This is you" -msgstr "" - -#: mod/content.php:727 mod/content.php:950 mod/photos.php:1611 -#: mod/photos.php:1659 mod/photos.php:1745 object/Item.php:418 -#: object/Item.php:731 -msgid "Comment" -msgstr "" - -#: mod/content.php:728 mod/crepair.php:156 mod/fsuggest.php:108 -#: mod/invite.php:142 mod/localtime.php:45 mod/manage.php:145 mod/mood.php:138 -#: mod/poke.php:203 mod/contacts.php:585 mod/events.php:513 -#: mod/message.php:338 mod/message.php:521 mod/photos.php:1124 -#: mod/photos.php:1246 mod/photos.php:1562 mod/photos.php:1612 -#: mod/photos.php:1660 mod/photos.php:1746 mod/install.php:276 -#: mod/install.php:316 mod/profiles.php:680 object/Item.php:732 -#: view/theme/quattro/config.php:67 view/theme/vier/config.php:112 -#: view/theme/duepuntozero/config.php:61 view/theme/clean/config.php:87 -#: view/theme/frio/config.php:64 -msgid "Submit" -msgstr "" - -#: mod/content.php:729 object/Item.php:733 -msgid "Bold" -msgstr "" - -#: mod/content.php:730 object/Item.php:734 -msgid "Italic" -msgstr "" - -#: mod/content.php:731 object/Item.php:735 -msgid "Underline" -msgstr "" - -#: mod/content.php:732 object/Item.php:736 -msgid "Quote" -msgstr "" - -#: mod/content.php:733 object/Item.php:737 -msgid "Code" -msgstr "" - -#: mod/content.php:734 object/Item.php:738 -msgid "Image" -msgstr "" - -#: mod/content.php:735 object/Item.php:739 -msgid "Link" -msgstr "" - -#: mod/content.php:736 object/Item.php:740 -msgid "Video" -msgstr "" - -#: mod/content.php:746 mod/settings.php:743 object/Item.php:122 -#: object/Item.php:124 -msgid "Edit" -msgstr "" - -#: mod/content.php:772 object/Item.php:238 -msgid "add star" -msgstr "" - -#: mod/content.php:773 object/Item.php:239 -msgid "remove star" -msgstr "" - -#: mod/content.php:774 object/Item.php:240 -msgid "toggle star status" -msgstr "" - -#: mod/content.php:777 object/Item.php:243 -msgid "starred" -msgstr "" - -#: mod/content.php:778 mod/content.php:800 object/Item.php:263 -msgid "add tag" -msgstr "" - -#: mod/content.php:789 object/Item.php:251 -msgid "ignore thread" -msgstr "" - -#: mod/content.php:790 object/Item.php:252 -msgid "unignore thread" -msgstr "" - -#: mod/content.php:791 object/Item.php:253 -msgid "toggle ignore status" -msgstr "" - -#: mod/content.php:794 mod/ostatus_subscribe.php:73 object/Item.php:256 -msgid "ignored" -msgstr "" - -#: mod/content.php:805 object/Item.php:141 -msgid "save to folder" -msgstr "" - -#: mod/content.php:853 object/Item.php:212 -msgid "I will attend" -msgstr "" - -#: mod/content.php:853 object/Item.php:212 -msgid "I will not attend" -msgstr "" - -#: mod/content.php:853 object/Item.php:212 -msgid "I might attend" -msgstr "" - -#: mod/content.php:917 object/Item.php:384 -msgid "to" -msgstr "" - -#: mod/content.php:918 object/Item.php:386 -msgid "Wall-to-Wall" -msgstr "" - -#: mod/content.php:919 object/Item.php:387 -msgid "via Wall-To-Wall:" -msgstr "" - -#: mod/credits.php:16 -msgid "Credits" -msgstr "" - -#: mod/credits.php:17 -msgid "" -"Friendica is a community project, that would not be possible without the " -"help of many people. Here is a list of those who have contributed to the " -"code or the translation of Friendica. Thank you all!" -msgstr "" - -#: mod/crepair.php:89 -msgid "Contact settings applied." -msgstr "" - -#: mod/crepair.php:91 -msgid "Contact update failed." -msgstr "" - -#: mod/crepair.php:116 mod/fsuggest.php:21 mod/fsuggest.php:93 -#: mod/dfrn_confirm.php:126 -msgid "Contact not found." -msgstr "" - -#: mod/crepair.php:122 -msgid "" -"WARNING: This is highly advanced and if you enter incorrect " -"information your communications with this contact may stop working." -msgstr "" - -#: mod/crepair.php:123 -msgid "" -"Please use your browser 'Back' button now if you are " -"uncertain what to do on this page." -msgstr "" - -#: mod/crepair.php:136 mod/crepair.php:138 -msgid "No mirroring" -msgstr "" - -#: mod/crepair.php:136 -msgid "Mirror as forwarded posting" -msgstr "" - -#: mod/crepair.php:136 mod/crepair.php:138 -msgid "Mirror as my own posting" -msgstr "" - -#: mod/crepair.php:152 -msgid "Return to contact editor" -msgstr "" - -#: mod/crepair.php:154 -msgid "Refetch contact data" -msgstr "" - -#: mod/crepair.php:158 -msgid "Remote Self" -msgstr "" - -#: mod/crepair.php:161 -msgid "Mirror postings from this contact" -msgstr "" - -#: mod/crepair.php:163 -msgid "" -"Mark this contact as remote_self, this will cause friendica to repost new " -"entries from this contact." -msgstr "" - -#: mod/crepair.php:167 mod/settings.php:683 mod/settings.php:709 -#: mod/admin.php:1417 mod/admin.php:1430 mod/admin.php:1443 mod/admin.php:1459 -msgid "Name" -msgstr "" - -#: mod/crepair.php:168 -msgid "Account Nickname" -msgstr "" - -#: mod/crepair.php:169 -msgid "@Tagname - overrides Name/Nickname" -msgstr "" - -#: mod/crepair.php:170 -msgid "Account URL" -msgstr "" - -#: mod/crepair.php:171 -msgid "Friend Request URL" -msgstr "" - -#: mod/crepair.php:172 -msgid "Friend Confirm URL" -msgstr "" - -#: mod/crepair.php:173 -msgid "Notification Endpoint URL" -msgstr "" - -#: mod/crepair.php:174 -msgid "Poll/Feed URL" -msgstr "" - -#: mod/crepair.php:175 -msgid "New photo from this URL" -msgstr "" - -#: mod/delegate.php:101 -msgid "No potential page delegates located." -msgstr "" - -#: mod/delegate.php:132 -msgid "" -"Delegates are able to manage all aspects of this account/page except for " -"basic account settings. Please do not delegate your personal account to " -"anybody that you do not trust completely." -msgstr "" - -#: mod/delegate.php:133 -msgid "Existing Page Managers" -msgstr "" - -#: mod/delegate.php:135 -msgid "Existing Page Delegates" -msgstr "" - -#: mod/delegate.php:137 -msgid "Potential Delegates" -msgstr "" - -#: mod/delegate.php:139 mod/tagrm.php:95 -msgid "Remove" -msgstr "" - -#: mod/delegate.php:140 -msgid "Add" -msgstr "" - -#: mod/delegate.php:141 -msgid "No entries." -msgstr "" - -#: mod/dfrn_poll.php:104 mod/dfrn_poll.php:539 -#, php-format -msgid "%1$s welcomes %2$s" -msgstr "" - -#: mod/directory.php:199 view/theme/vier/theme.php:196 -msgid "Global Directory" -msgstr "" - -#: mod/directory.php:201 -msgid "Find on this site" -msgstr "" - -#: mod/directory.php:203 -msgid "Results for:" -msgstr "" - -#: mod/directory.php:205 -msgid "Site Directory" -msgstr "" - -#: mod/directory.php:212 -msgid "No entries (some entries may be hidden)." -msgstr "" - -#: mod/dirfind.php:37 -#, php-format -msgid "People Search - %s" -msgstr "" - -#: mod/dirfind.php:48 -#, php-format -msgid "Forum Search - %s" -msgstr "" - -#: mod/dirfind.php:245 mod/match.php:109 -msgid "No matches" -msgstr "" - -#: mod/filer.php:30 -msgid "- select -" -msgstr "" - -#: mod/follow.php:19 mod/dfrn_request.php:888 -msgid "Submit Request" -msgstr "" - -#: mod/follow.php:30 -msgid "You already added this contact." -msgstr "" - -#: mod/follow.php:39 -msgid "Diaspora support isn't enabled. Contact can't be added." -msgstr "" - -#: mod/follow.php:46 -msgid "OStatus support is disabled. Contact can't be added." -msgstr "" - -#: mod/follow.php:53 -msgid "The network type couldn't be detected. Contact can't be added." -msgstr "" - -#: mod/follow.php:112 mod/dfrn_request.php:874 -msgid "Please answer the following:" -msgstr "" - -#: mod/follow.php:113 mod/dfrn_request.php:875 -#, php-format -msgid "Does %s know you?" -msgstr "" - -#: mod/follow.php:114 mod/dfrn_request.php:879 -msgid "Add a personal note:" -msgstr "" - -#: mod/follow.php:120 mod/dfrn_request.php:885 -msgid "Your Identity Address:" -msgstr "" - -#: mod/follow.php:129 mod/contacts.php:632 mod/notifications.php:249 -msgid "Profile URL" -msgstr "" - -#: mod/follow.php:186 -msgid "Contact added" -msgstr "" - -#: mod/fsuggest.php:64 -msgid "Friend suggestion sent." -msgstr "" - -#: mod/fsuggest.php:98 -msgid "Suggest Friends" -msgstr "" - -#: mod/fsuggest.php:100 -#, php-format -msgid "Suggest a friend for %s" -msgstr "" - -#: mod/group.php:29 -msgid "Group created." -msgstr "" - -#: mod/group.php:35 -msgid "Could not create group." -msgstr "" - -#: mod/group.php:49 mod/group.php:150 -msgid "Group not found." -msgstr "" - -#: mod/group.php:63 -msgid "Group name changed." -msgstr "" - -#: mod/group.php:76 mod/profperm.php:20 index.php:406 -msgid "Permission denied" -msgstr "" - -#: mod/group.php:91 -msgid "Save Group" -msgstr "" - -#: mod/group.php:97 -msgid "Create a group of contacts/friends." -msgstr "" - -#: mod/group.php:122 -msgid "Group removed." -msgstr "" - -#: mod/group.php:124 -msgid "Unable to remove group." -msgstr "" - -#: mod/group.php:187 -msgid "Group Editor" -msgstr "" - -#: mod/group.php:200 -msgid "Members" -msgstr "" - -#: mod/group.php:202 mod/contacts.php:700 -msgid "All Contacts" -msgstr "" - -#: mod/group.php:233 mod/profperm.php:107 -msgid "Click on a contact to add or remove." -msgstr "" - -#: mod/hcard.php:11 -msgid "No profile" -msgstr "" - -#: mod/help.php:41 -msgid "Help:" -msgstr "" - -#: mod/help.php:53 mod/fetch.php:12 mod/fetch.php:39 mod/fetch.php:48 -#: mod/p.php:16 mod/p.php:43 mod/p.php:52 index.php:292 -msgid "Not Found" -msgstr "" - -#: mod/help.php:56 index.php:295 -msgid "Page not found." -msgstr "" - -#: mod/home.php:39 -#, php-format -msgid "Welcome to %s" -msgstr "" - -#: mod/invite.php:28 -msgid "Total invitation limit exceeded." -msgstr "" - -#: mod/invite.php:51 -#, php-format -msgid "%s : Not a valid email address." -msgstr "" - -#: mod/invite.php:76 -msgid "Please join us on Friendica" -msgstr "" - -#: mod/invite.php:87 -msgid "Invitation limit exceeded. Please contact your site administrator." -msgstr "" - -#: mod/invite.php:91 -#, php-format -msgid "%s : Message delivery failed." -msgstr "" - -#: mod/invite.php:95 -#, php-format -msgid "%d message sent." -msgid_plural "%d messages sent." -msgstr[0] "" -msgstr[1] "" - -#: mod/invite.php:114 -msgid "You have no more invitations available" -msgstr "" - -#: mod/invite.php:122 -#, php-format -msgid "" -"Visit %s for a list of public sites that you can join. Friendica members on " -"other sites can all connect with each other, as well as with members of many " -"other social networks." -msgstr "" - -#: mod/invite.php:124 -#, php-format -msgid "" -"To accept this invitation, please visit and register at %s or any other " -"public Friendica website." -msgstr "" - -#: mod/invite.php:125 -#, php-format -msgid "" -"Friendica sites all inter-connect to create a huge privacy-enhanced social " -"web that is owned and controlled by its members. They can also connect with " -"many traditional social networks. See %s for a list of alternate Friendica " -"sites you can join." -msgstr "" - -#: mod/invite.php:128 -msgid "" -"Our apologies. This system is not currently configured to connect with other " -"public sites or invite members." -msgstr "" - -#: mod/invite.php:134 -msgid "Send invitations" -msgstr "" - -#: mod/invite.php:135 -msgid "Enter email addresses, one per line:" -msgstr "" - -#: mod/invite.php:136 mod/message.php:332 mod/message.php:515 -#: mod/wallmessage.php:135 -msgid "Your message:" -msgstr "" - -#: mod/invite.php:137 -msgid "" -"You are cordially invited to join me and other close friends on Friendica - " -"and help us to create a better social web." -msgstr "" - -#: mod/invite.php:139 -msgid "You will need to supply this invitation code: $invite_code" -msgstr "" - -#: mod/invite.php:139 -msgid "" -"Once you have registered, please connect with me via my profile page at:" -msgstr "" - -#: mod/invite.php:141 -msgid "" -"For more information about the Friendica project and why we feel it is " -"important, please visit http://friendica.com" -msgstr "" - -#: mod/localtime.php:24 -msgid "Time Conversion" -msgstr "" - -#: mod/localtime.php:26 -msgid "" -"Friendica provides this service for sharing events with other networks and " -"friends in unknown timezones." -msgstr "" - -#: mod/localtime.php:30 -#, php-format -msgid "UTC time: %s" -msgstr "" - -#: mod/localtime.php:33 -#, php-format -msgid "Current timezone: %s" -msgstr "" - -#: mod/localtime.php:36 -#, php-format -msgid "Converted localtime: %s" -msgstr "" - -#: mod/localtime.php:41 -msgid "Please select your timezone:" -msgstr "" - -#: mod/lockview.php:32 mod/lockview.php:40 -msgid "Remote privacy information not available." -msgstr "" - -#: mod/lockview.php:49 -msgid "Visible to:" -msgstr "" - -#: mod/lostpass.php:19 -msgid "No valid account found." -msgstr "" - -#: mod/lostpass.php:35 -msgid "Password reset request issued. Check your email." -msgstr "" - -#: mod/lostpass.php:41 -#, php-format -msgid "" -"\n" -"\t\tDear %1$s,\n" -"\t\t\tA request was recently received at \"%2$s\" to reset your account\n" -"\t\tpassword. In order to confirm this request, please select the " -"verification link\n" -"\t\tbelow or paste it into your web browser address bar.\n" -"\n" -"\t\tIf you did NOT request this change, please DO NOT follow the link\n" -"\t\tprovided and ignore and/or delete this email.\n" -"\n" -"\t\tYour password will not be changed unless we can verify that you\n" -"\t\tissued this request." -msgstr "" - -#: mod/lostpass.php:52 -#, php-format -msgid "" -"\n" -"\t\tFollow this link to verify your identity:\n" -"\n" -"\t\t%1$s\n" -"\n" -"\t\tYou will then receive a follow-up message containing the new password.\n" -"\t\tYou may change that password from your account settings page after " -"logging in.\n" -"\n" -"\t\tThe login details are as follows:\n" -"\n" -"\t\tSite Location:\t%2$s\n" -"\t\tLogin Name:\t%3$s" -msgstr "" - -#: mod/lostpass.php:71 -#, php-format -msgid "Password reset requested at %s" -msgstr "" - -#: mod/lostpass.php:91 -msgid "" -"Request could not be verified. (You may have previously submitted it.) " -"Password reset failed." -msgstr "" - -#: mod/lostpass.php:110 boot.php:1848 -msgid "Password Reset" -msgstr "" - -#: mod/lostpass.php:111 -msgid "Your password has been reset as requested." -msgstr "" - -#: mod/lostpass.php:112 -msgid "Your new password is" -msgstr "" - -#: mod/lostpass.php:113 -msgid "Save or copy your new password - and then" -msgstr "" - -#: mod/lostpass.php:114 -msgid "click here to login" -msgstr "" - -#: mod/lostpass.php:115 -msgid "" -"Your password may be changed from the Settings page after " -"successful login." -msgstr "" - -#: mod/lostpass.php:125 -#, php-format -msgid "" -"\n" -"\t\t\t\tDear %1$s,\n" -"\t\t\t\t\tYour password has been changed as requested. Please retain this\n" -"\t\t\t\tinformation for your records (or change your password immediately " -"to\n" -"\t\t\t\tsomething that you will remember).\n" -"\t\t\t" -msgstr "" - -#: mod/lostpass.php:131 -#, php-format -msgid "" -"\n" -"\t\t\t\tYour login details are as follows:\n" -"\n" -"\t\t\t\tSite Location:\t%1$s\n" -"\t\t\t\tLogin Name:\t%2$s\n" -"\t\t\t\tPassword:\t%3$s\n" -"\n" -"\t\t\t\tYou may change that password from your account settings page after " -"logging in.\n" -"\t\t\t" -msgstr "" - -#: mod/lostpass.php:147 -#, php-format -msgid "Your password has been changed at %s" -msgstr "" - -#: mod/lostpass.php:159 -msgid "Forgot your Password?" -msgstr "" - -#: mod/lostpass.php:160 -msgid "" -"Enter your email address and submit to have your password reset. Then check " -"your email for further instructions." -msgstr "" - -#: mod/lostpass.php:161 boot.php:1836 -msgid "Nickname or Email: " -msgstr "" - -#: mod/lostpass.php:162 -msgid "Reset" -msgstr "" - -#: mod/maintenance.php:9 -msgid "System down for maintenance" -msgstr "" - -#: mod/manage.php:141 -msgid "Manage Identities and/or Pages" -msgstr "" - -#: mod/manage.php:142 -msgid "" -"Toggle between different identities or community/group pages which share " -"your account details or which you have been granted \"manage\" permissions" -msgstr "" - -#: mod/manage.php:143 -msgid "Select an identity to manage: " -msgstr "" - -#: mod/match.php:35 -msgid "No keywords to match. Please add keywords to your default profile." -msgstr "" - -#: mod/match.php:88 -msgid "is interested in:" -msgstr "" - -#: mod/match.php:102 -msgid "Profile Match" -msgstr "" - -#: mod/mood.php:134 -msgid "Mood" -msgstr "" - -#: mod/mood.php:135 -msgid "Set your current mood and tell your friends" -msgstr "" - -#: mod/newmember.php:6 -msgid "Welcome to Friendica" -msgstr "" - -#: mod/newmember.php:8 -msgid "New Member Checklist" -msgstr "" - -#: mod/newmember.php:12 -msgid "" -"We would like to offer some tips and links to help make your experience " -"enjoyable. Click any item to visit the relevant page. A link to this page " -"will be visible from your home page for two weeks after your initial " -"registration and then will quietly disappear." -msgstr "" - -#: mod/newmember.php:14 -msgid "Getting Started" -msgstr "" - -#: mod/newmember.php:18 -msgid "Friendica Walk-Through" -msgstr "" - -#: mod/newmember.php:18 -msgid "" -"On your Quick Start page - find a brief introduction to your " -"profile and network tabs, make some new connections, and find some groups to " -"join." -msgstr "" - -#: mod/newmember.php:26 -msgid "Go to Your Settings" -msgstr "" - -#: mod/newmember.php:26 -msgid "" -"On your Settings page - change your initial password. Also make a " -"note of your Identity Address. This looks just like an email address - and " -"will be useful in making friends on the free social web." -msgstr "" - -#: mod/newmember.php:28 -msgid "" -"Review the other settings, particularly the privacy settings. An unpublished " -"directory listing is like having an unlisted phone number. In general, you " -"should probably publish your listing - unless all of your friends and " -"potential friends know exactly how to find you." -msgstr "" - -#: mod/newmember.php:36 mod/profile_photo.php:256 mod/profiles.php:699 -msgid "Upload Profile Photo" -msgstr "" - -#: mod/newmember.php:36 -msgid "" -"Upload a profile photo if you have not done so already. Studies have shown " -"that people with real photos of themselves are ten times more likely to make " -"friends than people who do not." -msgstr "" - -#: mod/newmember.php:38 -msgid "Edit Your Profile" -msgstr "" - -#: mod/newmember.php:38 -msgid "" -"Edit your default profile to your liking. Review the " -"settings for hiding your list of friends and hiding the profile from unknown " -"visitors." -msgstr "" - -#: mod/newmember.php:40 -msgid "Profile Keywords" -msgstr "" - -#: mod/newmember.php:40 -msgid "" -"Set some public keywords for your default profile which describe your " -"interests. We may be able to find other people with similar interests and " -"suggest friendships." -msgstr "" - -#: mod/newmember.php:44 -msgid "Connecting" -msgstr "" - -#: mod/newmember.php:51 -msgid "Importing Emails" -msgstr "" - -#: mod/newmember.php:51 -msgid "" -"Enter your email access information on your Connector Settings page if you " -"wish to import and interact with friends or mailing lists from your email " -"INBOX" -msgstr "" - -#: mod/newmember.php:53 -msgid "Go to Your Contacts Page" -msgstr "" - -#: mod/newmember.php:53 -msgid "" -"Your Contacts page is your gateway to managing friendships and connecting " -"with friends on other networks. Typically you enter their address or site " -"URL in the Add New Contact dialog." -msgstr "" - -#: mod/newmember.php:55 -msgid "Go to Your Site's Directory" -msgstr "" - -#: mod/newmember.php:55 -msgid "" -"The Directory page lets you find other people in this network or other " -"federated sites. Look for a Connect or Follow link on " -"their profile page. Provide your own Identity Address if requested." -msgstr "" - -#: mod/newmember.php:57 -msgid "Finding New People" -msgstr "" - -#: mod/newmember.php:57 -msgid "" -"On the side panel of the Contacts page are several tools to find new " -"friends. We can match people by interest, look up people by name or " -"interest, and provide suggestions based on network relationships. On a brand " -"new site, friend suggestions will usually begin to be populated within 24 " -"hours." -msgstr "" - -#: mod/newmember.php:65 -msgid "Group Your Contacts" -msgstr "" - -#: mod/newmember.php:65 -msgid "" -"Once you have made some friends, organize them into private conversation " -"groups from the sidebar of your Contacts page and then you can interact with " -"each group privately on your Network page." -msgstr "" - -#: mod/newmember.php:68 -msgid "Why Aren't My Posts Public?" -msgstr "" - -#: mod/newmember.php:68 -msgid "" -"Friendica respects your privacy. By default, your posts will only show up to " -"people you've added as friends. For more information, see the help section " -"from the link above." -msgstr "" - -#: mod/newmember.php:73 -msgid "Getting Help" -msgstr "" - -#: mod/newmember.php:77 -msgid "Go to the Help Section" -msgstr "" - -#: mod/newmember.php:77 -msgid "" -"Our help pages may be consulted for detail on other program " -"features and resources." -msgstr "" - -#: mod/nogroup.php:43 mod/contacts.php:594 mod/contacts.php:938 -#: mod/viewcontacts.php:102 -#, php-format -msgid "Visit %s's profile [%s]" -msgstr "" - -#: mod/nogroup.php:44 mod/contacts.php:939 -msgid "Edit contact" -msgstr "" - -#: mod/nogroup.php:65 -msgid "Contacts who are not members of a group" -msgstr "" - -#: mod/notify.php:65 -msgid "No more system notifications." -msgstr "" - -#: mod/notify.php:69 mod/notifications.php:111 -msgid "System Notifications" -msgstr "" - -#: mod/oexchange.php:21 -msgid "Post successful." -msgstr "" - -#: mod/openid.php:24 -msgid "OpenID protocol error. No ID returned." -msgstr "" - -#: mod/openid.php:60 -msgid "" -"Account not found and OpenID registration is not permitted on this site." -msgstr "" - -#: mod/ostatus_subscribe.php:14 -msgid "Subscribing to OStatus contacts" -msgstr "" - -#: mod/ostatus_subscribe.php:25 -msgid "No contact provided." -msgstr "" - -#: mod/ostatus_subscribe.php:31 -msgid "Couldn't fetch information for contact." -msgstr "" - -#: mod/ostatus_subscribe.php:40 -msgid "Couldn't fetch friends for contact." -msgstr "" - -#: mod/ostatus_subscribe.php:54 mod/repair_ostatus.php:44 -msgid "Done" -msgstr "" - -#: mod/ostatus_subscribe.php:68 -msgid "success" -msgstr "" - -#: mod/ostatus_subscribe.php:70 -msgid "failed" -msgstr "" - -#: mod/ostatus_subscribe.php:78 mod/repair_ostatus.php:50 -msgid "Keep this window open until done." -msgstr "" - -#: mod/poke.php:196 -msgid "Poke/Prod" -msgstr "" - -#: mod/poke.php:197 -msgid "poke, prod or do other things to somebody" -msgstr "" - -#: mod/poke.php:198 -msgid "Recipient" -msgstr "" - -#: mod/poke.php:199 -msgid "Choose what you wish to do to recipient" -msgstr "" - -#: mod/poke.php:202 -msgid "Make this post private" -msgstr "" - -#: mod/profile.php:154 mod/cal.php:143 mod/display.php:328 +#: mod/cal.php:143 mod/display.php:328 mod/profile.php:154 msgid "Access to this profile has been restricted." msgstr "" -#: mod/profile.php:174 -msgid "Tips for New Members" -msgstr "" - -#: mod/profile_photo.php:44 -msgid "Image uploaded but image cropping failed." -msgstr "" - -#: mod/profile_photo.php:77 mod/profile_photo.php:85 mod/profile_photo.php:93 -#: mod/profile_photo.php:323 -#, php-format -msgid "Image size reduction [%s] failed." -msgstr "" - -#: mod/profile_photo.php:127 -msgid "" -"Shift-reload the page or clear browser cache if the new photo does not " -"display immediately." -msgstr "" - -#: mod/profile_photo.php:137 -msgid "Unable to process image" -msgstr "" - -#: mod/profile_photo.php:156 mod/wall_upload.php:151 mod/photos.php:803 -#, php-format -msgid "Image exceeds size limit of %s" -msgstr "" - -#: mod/profile_photo.php:165 mod/wall_upload.php:186 mod/photos.php:844 -msgid "Unable to process image." -msgstr "" - -#: mod/profile_photo.php:254 -msgid "Upload File:" -msgstr "" - -#: mod/profile_photo.php:255 -msgid "Select a profile:" -msgstr "" - -#: mod/profile_photo.php:257 -msgid "Upload" -msgstr "" - -#: mod/profile_photo.php:260 -msgid "or" -msgstr "" - -#: mod/profile_photo.php:260 -msgid "skip this step" -msgstr "" - -#: mod/profile_photo.php:260 -msgid "select a photo from your photo albums" -msgstr "" - -#: mod/profile_photo.php:274 -msgid "Crop Image" -msgstr "" - -#: mod/profile_photo.php:275 -msgid "Please adjust the image cropping for optimum viewing." -msgstr "" - -#: mod/profile_photo.php:277 -msgid "Done Editing" -msgstr "" - -#: mod/profile_photo.php:313 -msgid "Image uploaded successfully." -msgstr "" - -#: mod/profile_photo.php:315 mod/wall_upload.php:219 mod/photos.php:871 -msgid "Image upload failed." -msgstr "" - -#: mod/profperm.php:26 mod/profperm.php:57 -msgid "Invalid profile identifier." -msgstr "" - -#: mod/profperm.php:103 -msgid "Profile Visibility Editor" -msgstr "" - -#: mod/profperm.php:116 -msgid "Visible To" -msgstr "" - -#: mod/profperm.php:132 -msgid "All Contacts (with secure profile access)" -msgstr "" - -#: mod/register.php:93 -msgid "" -"Registration successful. Please check your email for further instructions." -msgstr "" - -#: mod/register.php:98 -#, php-format -msgid "" -"Failed to send email message. Here your accout details:
    login: %s
    " -"password: %s

    You can change your password after login." -msgstr "" - -#: mod/register.php:105 -msgid "Registration successful." -msgstr "" - -#: mod/register.php:111 -msgid "Your registration can not be processed." -msgstr "" - -#: mod/register.php:160 -msgid "Your registration is pending approval by the site owner." -msgstr "" - -#: mod/register.php:198 mod/uimport.php:51 -msgid "" -"This site has exceeded the number of allowed daily account registrations. " -"Please try again tomorrow." -msgstr "" - -#: mod/register.php:226 -msgid "" -"You may (optionally) fill in this form via OpenID by supplying your OpenID " -"and clicking 'Register'." -msgstr "" - -#: mod/register.php:227 -msgid "" -"If you are not familiar with OpenID, please leave that field blank and fill " -"in the rest of the items." -msgstr "" - -#: mod/register.php:228 -msgid "Your OpenID (optional): " -msgstr "" - -#: mod/register.php:242 -msgid "Include your profile in member directory?" -msgstr "" - -#: mod/register.php:267 -msgid "Note for the admin" -msgstr "" - -#: mod/register.php:267 -msgid "Leave a message for the admin, why you want to join this node" -msgstr "" - -#: mod/register.php:268 -msgid "Membership on this site is by invitation only." -msgstr "" - -#: mod/register.php:269 -msgid "Your invitation ID: " -msgstr "" - -#: mod/register.php:272 mod/admin.php:977 -msgid "Registration" -msgstr "" - -#: mod/register.php:280 -msgid "Your Full Name (e.g. Joe Smith, real or real-looking): " -msgstr "" - -#: mod/register.php:281 -msgid "Your Email Address: " -msgstr "" - -#: mod/register.php:283 mod/settings.php:1278 -msgid "New Password:" -msgstr "" - -#: mod/register.php:283 -msgid "Leave empty for an auto generated password." -msgstr "" - -#: mod/register.php:284 mod/settings.php:1279 -msgid "Confirm:" -msgstr "" - -#: mod/register.php:285 -msgid "" -"Choose a profile nickname. This must begin with a text character. Your " -"profile address on this site will then be 'nickname@$sitename'." -msgstr "" - -#: mod/register.php:286 -msgid "Choose a nickname: " -msgstr "" - -#: mod/register.php:295 mod/uimport.php:66 -msgid "Import" -msgstr "" - -#: mod/register.php:296 -msgid "Import your profile to this friendica instance" -msgstr "" - -#: mod/regmod.php:58 -msgid "Account approved." -msgstr "" - -#: mod/regmod.php:95 -#, php-format -msgid "Registration revoked for %s" -msgstr "" - -#: mod/regmod.php:107 -msgid "Please login." -msgstr "" - -#: mod/removeme.php:52 mod/removeme.php:55 -msgid "Remove My Account" -msgstr "" - -#: mod/removeme.php:53 -msgid "" -"This will completely remove your account. Once this has been done it is not " -"recoverable." -msgstr "" - -#: mod/removeme.php:54 -msgid "Please enter your password for verification:" -msgstr "" - -#: mod/repair_ostatus.php:14 -msgid "Resubscribing to OStatus contacts" -msgstr "" - -#: mod/repair_ostatus.php:30 -msgid "Error" -msgstr "" - -#: mod/settings.php:36 mod/photos.php:107 -msgid "everybody" -msgstr "" - -#: mod/settings.php:43 mod/admin.php:1417 -msgid "Account" -msgstr "" - -#: mod/settings.php:52 mod/admin.php:161 -msgid "Additional features" -msgstr "" - -#: mod/settings.php:60 -msgid "Display" -msgstr "" - -#: mod/settings.php:67 mod/settings.php:890 -msgid "Social Networks" -msgstr "" - -#: mod/settings.php:74 mod/admin.php:159 mod/admin.php:1543 mod/admin.php:1606 -msgid "Plugins" -msgstr "" - -#: mod/settings.php:88 -msgid "Connected apps" -msgstr "" - -#: mod/settings.php:95 mod/uexport.php:45 -msgid "Export personal data" -msgstr "" - -#: mod/settings.php:102 -msgid "Remove account" -msgstr "" - -#: mod/settings.php:157 -msgid "Missing some important data!" -msgstr "" - -#: mod/settings.php:160 mod/settings.php:707 mod/contacts.php:812 -msgid "Update" -msgstr "" - -#: mod/settings.php:271 -msgid "Failed to connect with email account using the settings provided." -msgstr "" - -#: mod/settings.php:276 -msgid "Email settings updated." -msgstr "" - -#: mod/settings.php:291 -msgid "Features updated" -msgstr "" - -#: mod/settings.php:361 -msgid "Relocate message has been send to your contacts" -msgstr "" - -#: mod/settings.php:380 -msgid "Empty passwords are not allowed. Password unchanged." -msgstr "" - -#: mod/settings.php:388 -msgid "Wrong password." -msgstr "" - -#: mod/settings.php:399 -msgid "Password changed." -msgstr "" - -#: mod/settings.php:401 -msgid "Password update failed. Please try again." -msgstr "" - -#: mod/settings.php:481 -msgid " Please use a shorter name." -msgstr "" - -#: mod/settings.php:483 -msgid " Name too short." -msgstr "" - -#: mod/settings.php:492 -msgid "Wrong Password" -msgstr "" - -#: mod/settings.php:497 -msgid " Not valid email." -msgstr "" - -#: mod/settings.php:503 -msgid " Cannot change to that email." -msgstr "" - -#: mod/settings.php:559 -msgid "Private forum has no privacy permissions. Using default privacy group." -msgstr "" - -#: mod/settings.php:563 -msgid "Private forum has no privacy permissions and no default privacy group." -msgstr "" - -#: mod/settings.php:603 -msgid "Settings updated." -msgstr "" - -#: mod/settings.php:680 mod/settings.php:706 mod/settings.php:742 -msgid "Add application" -msgstr "" - -#: mod/settings.php:681 mod/settings.php:792 mod/settings.php:841 -#: mod/settings.php:908 mod/settings.php:1005 mod/settings.php:1271 -#: mod/admin.php:976 mod/admin.php:1607 mod/admin.php:1864 mod/admin.php:1938 -#: mod/admin.php:2088 -msgid "Save Settings" -msgstr "" - -#: mod/settings.php:684 mod/settings.php:710 -msgid "Consumer Key" -msgstr "" - -#: mod/settings.php:685 mod/settings.php:711 -msgid "Consumer Secret" -msgstr "" - -#: mod/settings.php:686 mod/settings.php:712 -msgid "Redirect" -msgstr "" - -#: mod/settings.php:687 mod/settings.php:713 -msgid "Icon url" -msgstr "" - -#: mod/settings.php:698 -msgid "You can't edit this application." -msgstr "" - -#: mod/settings.php:741 -msgid "Connected Apps" -msgstr "" - -#: mod/settings.php:745 -msgid "Client key starts with" -msgstr "" - -#: mod/settings.php:746 -msgid "No name" -msgstr "" - -#: mod/settings.php:747 -msgid "Remove authorization" -msgstr "" - -#: mod/settings.php:759 -msgid "No Plugin settings configured" -msgstr "" - -#: mod/settings.php:768 -msgid "Plugin Settings" -msgstr "" - -#: mod/settings.php:782 mod/admin.php:2077 mod/admin.php:2078 -msgid "Off" -msgstr "" - -#: mod/settings.php:782 mod/admin.php:2077 mod/admin.php:2078 -msgid "On" -msgstr "" - -#: mod/settings.php:790 -msgid "Additional Features" -msgstr "" - -#: mod/settings.php:800 mod/settings.php:804 -msgid "General Social Media Settings" -msgstr "" - -#: mod/settings.php:810 -msgid "Disable intelligent shortening" -msgstr "" - -#: mod/settings.php:812 -msgid "" -"Normally the system tries to find the best link to add to shortened posts. " -"If this option is enabled then every shortened post will always point to the " -"original friendica post." -msgstr "" - -#: mod/settings.php:818 -msgid "Automatically follow any GNU Social (OStatus) followers/mentioners" -msgstr "" - -#: mod/settings.php:820 -msgid "" -"If you receive a message from an unknown OStatus user, this option decides " -"what to do. If it is checked, a new contact will be created for every " -"unknown user." -msgstr "" - -#: mod/settings.php:826 -msgid "Default group for OStatus contacts" -msgstr "" - -#: mod/settings.php:834 -msgid "Your legacy GNU Social account" -msgstr "" - -#: mod/settings.php:836 -msgid "" -"If you enter your old GNU Social/Statusnet account name here (in the format " -"user@domain.tld), your contacts will be added automatically. The field will " -"be emptied when done." -msgstr "" - -#: mod/settings.php:839 -msgid "Repair OStatus subscriptions" -msgstr "" - -#: mod/settings.php:848 mod/settings.php:849 -#, php-format -msgid "Built-in support for %s connectivity is %s" -msgstr "" - -#: mod/settings.php:848 mod/settings.php:849 -msgid "enabled" -msgstr "" - -#: mod/settings.php:848 mod/settings.php:849 -msgid "disabled" -msgstr "" - -#: mod/settings.php:849 -msgid "GNU Social (OStatus)" -msgstr "" - -#: mod/settings.php:883 -msgid "Email access is disabled on this site." -msgstr "" - -#: mod/settings.php:895 -msgid "Email/Mailbox Setup" -msgstr "" - -#: mod/settings.php:896 -msgid "" -"If you wish to communicate with email contacts using this service " -"(optional), please specify how to connect to your mailbox." -msgstr "" - -#: mod/settings.php:897 -msgid "Last successful email check:" -msgstr "" - -#: mod/settings.php:899 -msgid "IMAP server name:" -msgstr "" - -#: mod/settings.php:900 -msgid "IMAP port:" -msgstr "" - -#: mod/settings.php:901 -msgid "Security:" -msgstr "" - -#: mod/settings.php:901 mod/settings.php:906 -msgid "None" -msgstr "" - -#: mod/settings.php:902 -msgid "Email login name:" -msgstr "" - -#: mod/settings.php:903 -msgid "Email password:" -msgstr "" - -#: mod/settings.php:904 -msgid "Reply-to address:" -msgstr "" - -#: mod/settings.php:905 -msgid "Send public posts to all email contacts:" -msgstr "" - -#: mod/settings.php:906 -msgid "Action after import:" -msgstr "" - -#: mod/settings.php:906 -msgid "Move to folder" -msgstr "" - -#: mod/settings.php:907 -msgid "Move to folder:" -msgstr "" - -#: mod/settings.php:943 mod/admin.php:863 -msgid "No special theme for mobile devices" -msgstr "" - -#: mod/settings.php:1003 -msgid "Display Settings" -msgstr "" - -#: mod/settings.php:1009 mod/settings.php:1032 -msgid "Display Theme:" -msgstr "" - -#: mod/settings.php:1010 -msgid "Mobile Theme:" -msgstr "" - -#: mod/settings.php:1011 -msgid "Suppress warning of insecure networks" -msgstr "" - -#: mod/settings.php:1011 -msgid "" -"Should the system suppress the warning that the current group contains " -"members of networks that can't receive non public postings." -msgstr "" - -#: mod/settings.php:1012 -msgid "Update browser every xx seconds" -msgstr "" - -#: mod/settings.php:1012 -msgid "Minimum of 10 seconds. Enter -1 to disable it." -msgstr "" - -#: mod/settings.php:1013 -msgid "Number of items to display per page:" -msgstr "" - -#: mod/settings.php:1013 mod/settings.php:1014 -msgid "Maximum of 100 items" -msgstr "" - -#: mod/settings.php:1014 -msgid "Number of items to display per page when viewed from mobile device:" -msgstr "" - -#: mod/settings.php:1015 -msgid "Don't show emoticons" -msgstr "" - -#: mod/settings.php:1016 -msgid "Calendar" -msgstr "" - -#: mod/settings.php:1017 -msgid "Beginning of week:" -msgstr "" - -#: mod/settings.php:1018 -msgid "Don't show notices" -msgstr "" - -#: mod/settings.php:1019 -msgid "Infinite scroll" -msgstr "" - -#: mod/settings.php:1020 -msgid "Automatic updates only at the top of the network page" -msgstr "" - -#: mod/settings.php:1021 -msgid "Bandwith Saver Mode" -msgstr "" - -#: mod/settings.php:1021 -msgid "" -"When enabled, embedded content is not displayed on automatic updates, they " -"only show on page reload." -msgstr "" - -#: mod/settings.php:1023 -msgid "General Theme Settings" -msgstr "" - -#: mod/settings.php:1024 -msgid "Custom Theme Settings" -msgstr "" - -#: mod/settings.php:1025 -msgid "Content Settings" -msgstr "" - -#: mod/settings.php:1026 view/theme/quattro/config.php:69 -#: view/theme/vier/config.php:114 view/theme/duepuntozero/config.php:63 -#: view/theme/clean/config.php:89 view/theme/frio/config.php:66 -msgid "Theme settings" -msgstr "" - -#: mod/settings.php:1110 -msgid "Account Types" -msgstr "" - -#: mod/settings.php:1111 -msgid "Personal Page Subtypes" -msgstr "" - -#: mod/settings.php:1112 -msgid "Community Forum Subtypes" -msgstr "" - -#: mod/settings.php:1119 -msgid "Personal Page" -msgstr "" - -#: mod/settings.php:1120 -msgid "This account is a regular personal profile" -msgstr "" - -#: mod/settings.php:1123 -msgid "Organisation Page" -msgstr "" - -#: mod/settings.php:1124 -msgid "This account is a profile for an organisation" -msgstr "" - -#: mod/settings.php:1127 -msgid "News Page" -msgstr "" - -#: mod/settings.php:1128 -msgid "This account is a news account/reflector" -msgstr "" - -#: mod/settings.php:1131 -msgid "Community Forum" -msgstr "" - -#: mod/settings.php:1132 -msgid "" -"This account is a community forum where people can discuss with each other" -msgstr "" - -#: mod/settings.php:1135 -msgid "Normal Account Page" -msgstr "" - -#: mod/settings.php:1136 -msgid "This account is a normal personal profile" -msgstr "" - -#: mod/settings.php:1139 -msgid "Soapbox Page" -msgstr "" - -#: mod/settings.php:1140 -msgid "Automatically approve all connection/friend requests as read-only fans" -msgstr "" - -#: mod/settings.php:1143 -msgid "Public Forum" -msgstr "" - -#: mod/settings.php:1144 -msgid "Automatically approve all contact requests" -msgstr "" - -#: mod/settings.php:1147 -msgid "Automatic Friend Page" -msgstr "" - -#: mod/settings.php:1148 -msgid "Automatically approve all connection/friend requests as friends" -msgstr "" - -#: mod/settings.php:1151 -msgid "Private Forum [Experimental]" -msgstr "" - -#: mod/settings.php:1152 -msgid "Private forum - approved members only" -msgstr "" - -#: mod/settings.php:1163 -msgid "OpenID:" -msgstr "" - -#: mod/settings.php:1163 -msgid "(Optional) Allow this OpenID to login to this account." -msgstr "" - -#: mod/settings.php:1171 -msgid "Publish your default profile in your local site directory?" -msgstr "" - -#: mod/settings.php:1177 -msgid "Publish your default profile in the global social directory?" -msgstr "" - -#: mod/settings.php:1184 -msgid "Hide your contact/friend list from viewers of your default profile?" -msgstr "" - -#: mod/settings.php:1188 -msgid "" -"If enabled, posting public messages to Diaspora and other networks isn't " -"possible." -msgstr "" - -#: mod/settings.php:1193 -msgid "Allow friends to post to your profile page?" -msgstr "" - -#: mod/settings.php:1198 -msgid "Allow friends to tag your posts?" -msgstr "" - -#: mod/settings.php:1203 -msgid "Allow us to suggest you as a potential friend to new members?" -msgstr "" - -#: mod/settings.php:1208 -msgid "Permit unknown people to send you private mail?" -msgstr "" - -#: mod/settings.php:1216 -msgid "Profile is not published." -msgstr "" - -#: mod/settings.php:1224 -#, php-format -msgid "Your Identity Address is '%s' or '%s'." -msgstr "" - -#: mod/settings.php:1231 -msgid "Automatically expire posts after this many days:" -msgstr "" - -#: mod/settings.php:1231 -msgid "If empty, posts will not expire. Expired posts will be deleted" -msgstr "" - -#: mod/settings.php:1232 -msgid "Advanced expiration settings" -msgstr "" - -#: mod/settings.php:1233 -msgid "Advanced Expiration" -msgstr "" - -#: mod/settings.php:1234 -msgid "Expire posts:" -msgstr "" - -#: mod/settings.php:1235 -msgid "Expire personal notes:" -msgstr "" - -#: mod/settings.php:1236 -msgid "Expire starred posts:" -msgstr "" - -#: mod/settings.php:1237 -msgid "Expire photos:" -msgstr "" - -#: mod/settings.php:1238 -msgid "Only expire posts by others:" -msgstr "" - -#: mod/settings.php:1269 -msgid "Account Settings" -msgstr "" - -#: mod/settings.php:1277 -msgid "Password Settings" -msgstr "" - -#: mod/settings.php:1279 -msgid "Leave password fields blank unless changing" -msgstr "" - -#: mod/settings.php:1280 -msgid "Current Password:" -msgstr "" - -#: mod/settings.php:1280 mod/settings.php:1281 -msgid "Your current password to confirm the changes" -msgstr "" - -#: mod/settings.php:1281 -msgid "Password:" -msgstr "" - -#: mod/settings.php:1285 -msgid "Basic Settings" -msgstr "" - -#: mod/settings.php:1287 -msgid "Email Address:" -msgstr "" - -#: mod/settings.php:1288 -msgid "Your Timezone:" -msgstr "" - -#: mod/settings.php:1289 -msgid "Your Language:" -msgstr "" - -#: mod/settings.php:1289 -msgid "" -"Set the language we use to show you friendica interface and to send you " -"emails" -msgstr "" - -#: mod/settings.php:1290 -msgid "Default Post Location:" -msgstr "" - -#: mod/settings.php:1291 -msgid "Use Browser Location:" -msgstr "" - -#: mod/settings.php:1294 -msgid "Security and Privacy Settings" -msgstr "" - -#: mod/settings.php:1296 -msgid "Maximum Friend Requests/Day:" -msgstr "" - -#: mod/settings.php:1296 mod/settings.php:1326 -msgid "(to prevent spam abuse)" -msgstr "" - -#: mod/settings.php:1297 -msgid "Default Post Permissions" -msgstr "" - -#: mod/settings.php:1298 -msgid "(click to open/close)" -msgstr "" - -#: mod/settings.php:1307 mod/photos.php:1185 mod/photos.php:1567 -msgid "Show to Groups" -msgstr "" - -#: mod/settings.php:1308 mod/photos.php:1186 mod/photos.php:1568 -msgid "Show to Contacts" -msgstr "" - -#: mod/settings.php:1309 -msgid "Default Private Post" -msgstr "" - -#: mod/settings.php:1310 -msgid "Default Public Post" -msgstr "" - -#: mod/settings.php:1314 -msgid "Default Permissions for New Posts" -msgstr "" - -#: mod/settings.php:1326 -msgid "Maximum private messages per day from unknown people:" -msgstr "" - -#: mod/settings.php:1329 -msgid "Notification Settings" -msgstr "" - -#: mod/settings.php:1330 -msgid "By default post a status message when:" -msgstr "" - -#: mod/settings.php:1331 -msgid "accepting a friend request" -msgstr "" - -#: mod/settings.php:1332 -msgid "joining a forum/community" -msgstr "" - -#: mod/settings.php:1333 -msgid "making an interesting profile change" -msgstr "" - -#: mod/settings.php:1334 -msgid "Send a notification email when:" -msgstr "" - -#: mod/settings.php:1335 -msgid "You receive an introduction" -msgstr "" - -#: mod/settings.php:1336 -msgid "Your introductions are confirmed" -msgstr "" - -#: mod/settings.php:1337 -msgid "Someone writes on your profile wall" -msgstr "" - -#: mod/settings.php:1338 -msgid "Someone writes a followup comment" -msgstr "" - -#: mod/settings.php:1339 -msgid "You receive a private message" -msgstr "" - -#: mod/settings.php:1340 -msgid "You receive a friend suggestion" -msgstr "" - -#: mod/settings.php:1341 -msgid "You are tagged in a post" -msgstr "" - -#: mod/settings.php:1342 -msgid "You are poked/prodded/etc. in a post" -msgstr "" - -#: mod/settings.php:1344 -msgid "Activate desktop notifications" -msgstr "" - -#: mod/settings.php:1344 -msgid "Show desktop popup on new notifications" -msgstr "" - -#: mod/settings.php:1346 -msgid "Text-only notification emails" -msgstr "" - -#: mod/settings.php:1348 -msgid "Send text only notification emails, without the html part" -msgstr "" - -#: mod/settings.php:1350 -msgid "Advanced Account/Page Type Settings" -msgstr "" - -#: mod/settings.php:1351 -msgid "Change the behaviour of this account for special situations" -msgstr "" - -#: mod/settings.php:1354 -msgid "Relocate" -msgstr "" - -#: mod/settings.php:1355 -msgid "" -"If you have moved this profile from another server, and some of your " -"contacts don't receive your updates, try pushing this button." -msgstr "" - -#: mod/settings.php:1356 -msgid "Resend relocate message to contacts" -msgstr "" - -#: mod/share.php:38 -msgid "link" -msgstr "" - -#: mod/subthread.php:104 -#, php-format -msgid "%1$s is following %2$s's %3$s" -msgstr "" - -#: mod/suggest.php:27 -msgid "Do you really want to delete this suggestion?" -msgstr "" - -#: mod/suggest.php:71 -msgid "" -"No suggestions available. If this is a new site, please try again in 24 " -"hours." -msgstr "" - -#: mod/suggest.php:84 mod/suggest.php:104 -msgid "Ignore/Hide" -msgstr "" - -#: mod/tagrm.php:43 -msgid "Tag removed" -msgstr "" - -#: mod/tagrm.php:82 -msgid "Remove Item Tag" -msgstr "" - -#: mod/tagrm.php:84 -msgid "Select a tag to remove: " -msgstr "" - -#: mod/uexport.php:37 -msgid "Export account" -msgstr "" - -#: mod/uexport.php:37 -msgid "" -"Export your account info and contacts. Use this to make a backup of your " -"account and/or to move it to another server." -msgstr "" - -#: mod/uexport.php:38 -msgid "Export all" -msgstr "" - -#: mod/uexport.php:38 -msgid "" -"Export your accout info, contacts and all your items as json. Could be a " -"very big file, and could take a lot of time. Use this to make a full backup " -"of your account (photos are not exported)" -msgstr "" - -#: mod/uimport.php:68 -msgid "Move account" -msgstr "" - -#: mod/uimport.php:69 -msgid "You can import an account from another Friendica server." -msgstr "" - -#: mod/uimport.php:70 -msgid "" -"You need to export your account from the old server and upload it here. We " -"will recreate your old account here with all your contacts. We will try also " -"to inform your friends that you moved here." -msgstr "" - -#: mod/uimport.php:71 -msgid "" -"This feature is experimental. We can't import contacts from the OStatus " -"network (GNU Social/Statusnet) or from Diaspora" -msgstr "" - -#: mod/uimport.php:72 -msgid "Account file" -msgstr "" - -#: mod/uimport.php:72 -msgid "" -"To export your account, go to \"Settings->Export your personal data\" and " -"select \"Export account\"" -msgstr "" - -#: mod/update_community.php:19 mod/update_display.php:23 -#: mod/update_network.php:27 mod/update_notes.php:36 mod/update_profile.php:35 -msgid "[Embedded content - reload page to view]" -msgstr "" - -#: mod/videos.php:124 -msgid "Do you really want to delete this video?" -msgstr "" - -#: mod/videos.php:129 -msgid "Delete Video" -msgstr "" - -#: mod/videos.php:208 -msgid "No videos selected" -msgstr "" - -#: mod/videos.php:309 mod/photos.php:1074 -msgid "Access to this item is restricted." -msgstr "" - -#: mod/videos.php:391 mod/photos.php:1867 -msgid "View Album" -msgstr "" - -#: mod/videos.php:400 -msgid "Recent Videos" -msgstr "" - -#: mod/videos.php:402 -msgid "Upload New Videos" -msgstr "" - -#: mod/viewsrc.php:7 -msgid "Access denied." -msgstr "" - -#: mod/wall_attach.php:17 mod/wall_attach.php:25 mod/wall_attach.php:76 -#: mod/wall_upload.php:20 mod/wall_upload.php:33 mod/wall_upload.php:86 -#: mod/wall_upload.php:122 mod/wall_upload.php:125 -msgid "Invalid request." -msgstr "" - -#: mod/wall_attach.php:94 -msgid "Sorry, maybe your upload is bigger than the PHP configuration allows" -msgstr "" - -#: mod/wall_attach.php:94 -msgid "Or - did you try to upload an empty file?" -msgstr "" - -#: mod/wall_attach.php:105 -#, php-format -msgid "File exceeds size limit of %s" -msgstr "" - -#: mod/wall_attach.php:158 mod/wall_attach.php:174 -msgid "File upload failed." -msgstr "" - #: mod/cal.php:271 mod/events.php:387 msgid "View" msgstr "" @@ -5449,6 +4663,28 @@ msgstr "" msgid "calendar" msgstr "" +#: mod/common.php:91 +msgid "No contacts in common." +msgstr "" + +#: mod/common.php:141 mod/contacts.php:871 +msgid "Common Friends" +msgstr "" + +#: mod/community.php:22 mod/dfrn_request.php:799 mod/directory.php:37 +#: mod/display.php:200 mod/photos.php:964 mod/search.php:93 mod/search.php:99 +#: mod/videos.php:198 mod/viewcontacts.php:36 +msgid "Public access denied." +msgstr "" + +#: mod/community.php:27 +msgid "Not available." +msgstr "" + +#: mod/community.php:54 mod/search.php:224 +msgid "No results." +msgstr "" + #: mod/contacts.php:134 #, php-format msgid "%d contact edited." @@ -5527,10 +4763,6 @@ msgstr "" msgid "Private communications are not available for this contact." msgstr "" -#: mod/contacts.php:538 mod/admin.php:899 -msgid "Never" -msgstr "" - #: mod/contacts.php:542 msgid "(Update was successful)" msgstr "" @@ -5556,10 +4788,6 @@ msgstr "" msgid "Fetch further information for feeds" msgstr "" -#: mod/contacts.php:565 mod/admin.php:908 -msgid "Disabled" -msgstr "" - #: mod/contacts.php:565 msgid "Fetch information" msgstr "" @@ -5572,6 +4800,18 @@ msgstr "" msgid "Contact" msgstr "" +#: mod/contacts.php:585 mod/content.php:728 mod/crepair.php:156 +#: mod/events.php:513 mod/fsuggest.php:108 mod/install.php:276 +#: mod/install.php:316 mod/invite.php:142 mod/localtime.php:45 +#: mod/manage.php:145 mod/message.php:338 mod/message.php:521 mod/mood.php:138 +#: mod/photos.php:1124 mod/photos.php:1246 mod/photos.php:1562 +#: mod/photos.php:1612 mod/photos.php:1660 mod/photos.php:1746 +#: mod/poke.php:203 mod/profiles.php:680 object/Item.php:705 +#: view/theme/duepuntozero/config.php:61 view/theme/frio/config.php:64 +#: view/theme/quattro/config.php:67 view/theme/vier/config.php:112 +msgid "Submit" +msgstr "" + #: mod/contacts.php:586 msgid "Profile Visibility" msgstr "" @@ -5591,6 +4831,12 @@ msgstr "" msgid "Edit contact notes" msgstr "" +#: mod/contacts.php:594 mod/contacts.php:938 mod/nogroup.php:43 +#: mod/viewcontacts.php:102 +#, php-format +msgid "Visit %s's profile [%s]" +msgstr "" + #: mod/contacts.php:595 msgid "Block/Unblock contact" msgstr "" @@ -5619,16 +4865,6 @@ msgstr "" msgid "Update now" msgstr "" -#: mod/contacts.php:613 mod/contacts.php:813 mod/contacts.php:991 -#: mod/admin.php:1437 -msgid "Unblock" -msgstr "" - -#: mod/contacts.php:613 mod/contacts.php:813 mod/contacts.php:991 -#: mod/admin.php:1436 -msgid "Block" -msgstr "" - #: mod/contacts.php:614 mod/contacts.php:814 mod/contacts.php:999 msgid "Unignore" msgstr "" @@ -5678,6 +4914,10 @@ msgid "" "when \"Fetch information and keywords\" is selected" msgstr "" +#: mod/contacts.php:632 mod/follow.php:129 mod/notifications.php:249 +msgid "Profile URL" +msgstr "" + #: mod/contacts.php:643 msgid "Actions" msgstr "" @@ -5694,6 +4934,10 @@ msgstr "" msgid "Suggest potential friends" msgstr "" +#: mod/contacts.php:700 mod/group.php:202 +msgid "All Contacts" +msgstr "" + #: mod/contacts.php:703 msgid "Show all contacts" msgstr "" @@ -5747,6 +4991,10 @@ msgstr "" msgid "Results for: %s" msgstr "" +#: mod/contacts.php:812 mod/settings.php:160 mod/settings.php:707 +msgid "Update" +msgstr "" + #: mod/contacts.php:815 mod/contacts.php:1007 msgid "Archive" msgstr "" @@ -5783,6 +5031,10 @@ msgstr "" msgid "you are a fan of" msgstr "" +#: mod/contacts.php:939 mod/nogroup.php:44 +msgid "Edit contact" +msgstr "" + #: mod/contacts.php:993 msgid "Toggle Blocked status" msgstr "" @@ -5799,6 +5051,307 @@ msgstr "" msgid "Delete contact" msgstr "" +#: mod/content.php:119 mod/network.php:468 +msgid "No such group" +msgstr "" + +#: mod/content.php:130 mod/group.php:203 mod/network.php:495 +msgid "Group is empty" +msgstr "" + +#: mod/content.php:135 mod/network.php:499 +#, php-format +msgid "Group: %s" +msgstr "" + +#: mod/content.php:325 object/Item.php:96 +msgid "This entry was edited" +msgstr "" + +#: mod/content.php:621 object/Item.php:417 +#, php-format +msgid "%d comment" +msgid_plural "%d comments" +msgstr[0] "" +msgstr[1] "" + +#: mod/content.php:638 mod/photos.php:1402 object/Item.php:117 +msgid "Private Message" +msgstr "" + +#: mod/content.php:702 mod/photos.php:1590 object/Item.php:274 +msgid "I like this (toggle)" +msgstr "" + +#: mod/content.php:702 object/Item.php:274 +msgid "like" +msgstr "" + +#: mod/content.php:703 mod/photos.php:1591 object/Item.php:275 +msgid "I don't like this (toggle)" +msgstr "" + +#: mod/content.php:703 object/Item.php:275 +msgid "dislike" +msgstr "" + +#: mod/content.php:705 object/Item.php:278 +msgid "Share this" +msgstr "" + +#: mod/content.php:705 object/Item.php:278 +msgid "share" +msgstr "" + +#: mod/content.php:725 mod/photos.php:1609 mod/photos.php:1657 +#: mod/photos.php:1743 object/Item.php:702 +msgid "This is you" +msgstr "" + +#: mod/content.php:727 mod/content.php:950 mod/photos.php:1611 +#: mod/photos.php:1659 mod/photos.php:1745 object/Item.php:392 +#: object/Item.php:704 +msgid "Comment" +msgstr "" + +#: mod/content.php:729 object/Item.php:706 +msgid "Bold" +msgstr "" + +#: mod/content.php:730 object/Item.php:707 +msgid "Italic" +msgstr "" + +#: mod/content.php:731 object/Item.php:708 +msgid "Underline" +msgstr "" + +#: mod/content.php:732 object/Item.php:709 +msgid "Quote" +msgstr "" + +#: mod/content.php:733 object/Item.php:710 +msgid "Code" +msgstr "" + +#: mod/content.php:734 object/Item.php:711 +msgid "Image" +msgstr "" + +#: mod/content.php:735 object/Item.php:712 +msgid "Link" +msgstr "" + +#: mod/content.php:736 object/Item.php:713 +msgid "Video" +msgstr "" + +#: mod/content.php:746 mod/settings.php:743 object/Item.php:122 +#: object/Item.php:124 +msgid "Edit" +msgstr "" + +#: mod/content.php:772 object/Item.php:238 +msgid "add star" +msgstr "" + +#: mod/content.php:773 object/Item.php:239 +msgid "remove star" +msgstr "" + +#: mod/content.php:774 object/Item.php:240 +msgid "toggle star status" +msgstr "" + +#: mod/content.php:777 object/Item.php:243 +msgid "starred" +msgstr "" + +#: mod/content.php:778 mod/content.php:800 object/Item.php:263 +msgid "add tag" +msgstr "" + +#: mod/content.php:789 object/Item.php:251 +msgid "ignore thread" +msgstr "" + +#: mod/content.php:790 object/Item.php:252 +msgid "unignore thread" +msgstr "" + +#: mod/content.php:791 object/Item.php:253 +msgid "toggle ignore status" +msgstr "" + +#: mod/content.php:794 mod/ostatus_subscribe.php:73 object/Item.php:256 +msgid "ignored" +msgstr "" + +#: mod/content.php:805 object/Item.php:141 +msgid "save to folder" +msgstr "" + +#: mod/content.php:853 object/Item.php:212 +msgid "I will attend" +msgstr "" + +#: mod/content.php:853 object/Item.php:212 +msgid "I will not attend" +msgstr "" + +#: mod/content.php:853 object/Item.php:212 +msgid "I might attend" +msgstr "" + +#: mod/content.php:917 object/Item.php:358 +msgid "to" +msgstr "" + +#: mod/content.php:918 object/Item.php:360 +msgid "Wall-to-Wall" +msgstr "" + +#: mod/content.php:919 object/Item.php:361 +msgid "via Wall-To-Wall:" +msgstr "" + +#: mod/credits.php:16 +msgid "Credits" +msgstr "" + +#: mod/credits.php:17 +msgid "" +"Friendica is a community project, that would not be possible without the " +"help of many people. Here is a list of those who have contributed to the " +"code or the translation of Friendica. Thank you all!" +msgstr "" + +#: mod/crepair.php:89 +msgid "Contact settings applied." +msgstr "" + +#: mod/crepair.php:91 +msgid "Contact update failed." +msgstr "" + +#: mod/crepair.php:116 mod/dfrn_confirm.php:126 mod/fsuggest.php:21 +#: mod/fsuggest.php:93 +msgid "Contact not found." +msgstr "" + +#: mod/crepair.php:122 +msgid "" +"WARNING: This is highly advanced and if you enter incorrect " +"information your communications with this contact may stop working." +msgstr "" + +#: mod/crepair.php:123 +msgid "" +"Please use your browser 'Back' button now if you are " +"uncertain what to do on this page." +msgstr "" + +#: mod/crepair.php:136 mod/crepair.php:138 +msgid "No mirroring" +msgstr "" + +#: mod/crepair.php:136 +msgid "Mirror as forwarded posting" +msgstr "" + +#: mod/crepair.php:136 mod/crepair.php:138 +msgid "Mirror as my own posting" +msgstr "" + +#: mod/crepair.php:152 +msgid "Return to contact editor" +msgstr "" + +#: mod/crepair.php:154 +msgid "Refetch contact data" +msgstr "" + +#: mod/crepair.php:158 +msgid "Remote Self" +msgstr "" + +#: mod/crepair.php:161 +msgid "Mirror postings from this contact" +msgstr "" + +#: mod/crepair.php:163 +msgid "" +"Mark this contact as remote_self, this will cause friendica to repost new " +"entries from this contact." +msgstr "" + +#: mod/crepair.php:168 +msgid "Account Nickname" +msgstr "" + +#: mod/crepair.php:169 +msgid "@Tagname - overrides Name/Nickname" +msgstr "" + +#: mod/crepair.php:170 +msgid "Account URL" +msgstr "" + +#: mod/crepair.php:171 +msgid "Friend Request URL" +msgstr "" + +#: mod/crepair.php:172 +msgid "Friend Confirm URL" +msgstr "" + +#: mod/crepair.php:173 +msgid "Notification Endpoint URL" +msgstr "" + +#: mod/crepair.php:174 +msgid "Poll/Feed URL" +msgstr "" + +#: mod/crepair.php:175 +msgid "New photo from this URL" +msgstr "" + +#: mod/delegate.php:101 +msgid "No potential page delegates located." +msgstr "" + +#: mod/delegate.php:132 +msgid "" +"Delegates are able to manage all aspects of this account/page except for " +"basic account settings. Please do not delegate your personal account to " +"anybody that you do not trust completely." +msgstr "" + +#: mod/delegate.php:133 +msgid "Existing Page Managers" +msgstr "" + +#: mod/delegate.php:135 +msgid "Existing Page Delegates" +msgstr "" + +#: mod/delegate.php:137 +msgid "Potential Delegates" +msgstr "" + +#: mod/delegate.php:139 mod/tagrm.php:95 +msgid "Remove" +msgstr "" + +#: mod/delegate.php:140 +msgid "Add" +msgstr "" + +#: mod/delegate.php:141 +msgid "No entries." +msgstr "" + #: mod/dfrn_confirm.php:70 mod/profiles.php:19 mod/profiles.php:134 #: mod/profiles.php:180 mod/profiles.php:619 msgid "Profile not found." @@ -5879,436 +5432,9 @@ msgstr "" msgid "%1$s has joined %2$s" msgstr "" -#: mod/editpost.php:17 mod/editpost.php:27 -msgid "Item not found" -msgstr "" - -#: mod/editpost.php:32 -msgid "Edit post" -msgstr "" - -#: mod/events.php:100 mod/events.php:102 -msgid "Event can not end before it has started." -msgstr "" - -#: mod/events.php:109 mod/events.php:111 -msgid "Event title and start time are required." -msgstr "" - -#: mod/events.php:388 -msgid "Create New Event" -msgstr "" - -#: mod/events.php:489 -msgid "Event details" -msgstr "" - -#: mod/events.php:490 -msgid "Starting date and Title are required." -msgstr "" - -#: mod/events.php:491 mod/events.php:492 -msgid "Event Starts:" -msgstr "" - -#: mod/events.php:491 mod/events.php:503 mod/profiles.php:708 -msgid "Required" -msgstr "" - -#: mod/events.php:493 mod/events.php:509 -msgid "Finish date/time is not known or not relevant" -msgstr "" - -#: mod/events.php:495 mod/events.php:496 -msgid "Event Finishes:" -msgstr "" - -#: mod/events.php:497 mod/events.php:510 -msgid "Adjust for viewer timezone" -msgstr "" - -#: mod/events.php:499 -msgid "Description:" -msgstr "" - -#: mod/events.php:503 mod/events.php:505 -msgid "Title:" -msgstr "" - -#: mod/events.php:506 mod/events.php:507 -msgid "Share this event" -msgstr "" - -#: mod/fbrowser.php:132 -msgid "Files" -msgstr "" - -#: mod/friendica.php:72 -msgid "This is Friendica, version" -msgstr "" - -#: mod/friendica.php:73 -msgid "running at web location" -msgstr "" - -#: mod/friendica.php:75 -msgid "" -"Please visit Friendica.com to learn " -"more about the Friendica project." -msgstr "" - -#: mod/friendica.php:77 -msgid "Bug reports and issues: please visit" -msgstr "" - -#: mod/friendica.php:77 -msgid "the bugtracker at github" -msgstr "" - -#: mod/friendica.php:78 -msgid "" -"Suggestions, praise, donations, etc. - please email \"Info\" at Friendica - " -"dot com" -msgstr "" - -#: mod/friendica.php:92 -msgid "Installed plugins/addons/apps:" -msgstr "" - -#: mod/friendica.php:105 -msgid "No installed plugins/addons/apps" -msgstr "" - -#: mod/item.php:118 -msgid "Unable to locate original post." -msgstr "" - -#: mod/item.php:336 -msgid "Empty post discarded." -msgstr "" - -#: mod/item.php:889 -msgid "System error. Post not saved." -msgstr "" - -#: mod/item.php:979 +#: mod/dfrn_poll.php:104 mod/dfrn_poll.php:539 #, php-format -msgid "" -"This message was sent to you by %s, a member of the Friendica social network." -msgstr "" - -#: mod/item.php:981 -#, php-format -msgid "You may visit them online at %s" -msgstr "" - -#: mod/item.php:982 -msgid "" -"Please contact the sender by replying to this post if you do not wish to " -"receive these messages." -msgstr "" - -#: mod/item.php:986 -#, php-format -msgid "%s posted an update." -msgstr "" - -#: mod/message.php:60 mod/wallmessage.php:50 -msgid "No recipient selected." -msgstr "" - -#: mod/message.php:64 -msgid "Unable to locate contact information." -msgstr "" - -#: mod/message.php:67 mod/wallmessage.php:56 -msgid "Message could not be sent." -msgstr "" - -#: mod/message.php:70 mod/wallmessage.php:59 -msgid "Message collection failure." -msgstr "" - -#: mod/message.php:73 mod/wallmessage.php:62 -msgid "Message sent." -msgstr "" - -#: mod/message.php:204 -msgid "Do you really want to delete this message?" -msgstr "" - -#: mod/message.php:224 -msgid "Message deleted." -msgstr "" - -#: mod/message.php:255 -msgid "Conversation removed." -msgstr "" - -#: mod/message.php:322 mod/wallmessage.php:126 -msgid "Send Private Message" -msgstr "" - -#: mod/message.php:323 mod/message.php:510 mod/wallmessage.php:128 -msgid "To:" -msgstr "" - -#: mod/message.php:328 mod/message.php:512 mod/wallmessage.php:129 -msgid "Subject:" -msgstr "" - -#: mod/message.php:364 -msgid "No messages." -msgstr "" - -#: mod/message.php:403 -msgid "Message not available." -msgstr "" - -#: mod/message.php:477 -msgid "Delete message" -msgstr "" - -#: mod/message.php:503 mod/message.php:583 -msgid "Delete conversation" -msgstr "" - -#: mod/message.php:505 -msgid "" -"No secure communications available. You may be able to " -"respond from the sender's profile page." -msgstr "" - -#: mod/message.php:509 -msgid "Send Reply" -msgstr "" - -#: mod/message.php:553 -#, php-format -msgid "Unknown sender - %s" -msgstr "" - -#: mod/message.php:555 -#, php-format -msgid "You and %s" -msgstr "" - -#: mod/message.php:557 -#, php-format -msgid "%s and You" -msgstr "" - -#: mod/message.php:586 -msgid "D, d M Y - g:i A" -msgstr "" - -#: mod/message.php:589 -#, php-format -msgid "%d message" -msgid_plural "%d messages" -msgstr[0] "" -msgstr[1] "" - -#: mod/p.php:9 -msgid "Not Extended" -msgstr "" - -#: mod/ping.php:270 -msgid "{0} wants to be your friend" -msgstr "" - -#: mod/ping.php:285 -msgid "{0} sent you a message" -msgstr "" - -#: mod/ping.php:300 -msgid "{0} requested registration" -msgstr "" - -#: mod/wallmessage.php:42 mod/wallmessage.php:106 -#, php-format -msgid "Number of daily wall messages for %s exceeded. Message failed." -msgstr "" - -#: mod/wallmessage.php:53 -msgid "Unable to check your home location." -msgstr "" - -#: mod/wallmessage.php:80 mod/wallmessage.php:89 -msgid "No recipient." -msgstr "" - -#: mod/wallmessage.php:127 -#, php-format -msgid "" -"If you wish for %s to respond, please check that the privacy settings on " -"your site allow private mail from unknown senders." -msgstr "" - -#: mod/photos.php:90 mod/photos.php:1876 -msgid "Recent Photos" -msgstr "" - -#: mod/photos.php:93 mod/photos.php:1303 mod/photos.php:1878 -msgid "Upload New Photos" -msgstr "" - -#: mod/photos.php:171 -msgid "Contact information unavailable" -msgstr "" - -#: mod/photos.php:192 -msgid "Album not found." -msgstr "" - -#: mod/photos.php:225 mod/photos.php:237 mod/photos.php:1247 -msgid "Delete Album" -msgstr "" - -#: mod/photos.php:235 -msgid "Do you really want to delete this photo album and all its photos?" -msgstr "" - -#: mod/photos.php:317 mod/photos.php:328 mod/photos.php:1563 -msgid "Delete Photo" -msgstr "" - -#: mod/photos.php:326 -msgid "Do you really want to delete this photo?" -msgstr "" - -#: mod/photos.php:705 -#, php-format -msgid "%1$s was tagged in %2$s by %3$s" -msgstr "" - -#: mod/photos.php:705 -msgid "a photo" -msgstr "" - -#: mod/photos.php:811 -msgid "Image file is empty." -msgstr "" - -#: mod/photos.php:974 -msgid "No photos selected" -msgstr "" - -#: mod/photos.php:1134 -#, php-format -msgid "You have used %1$.2f Mbytes of %2$.2f Mbytes photo storage." -msgstr "" - -#: mod/photos.php:1168 -msgid "Upload Photos" -msgstr "" - -#: mod/photos.php:1172 mod/photos.php:1242 -msgid "New album name: " -msgstr "" - -#: mod/photos.php:1173 -msgid "or existing album name: " -msgstr "" - -#: mod/photos.php:1174 -msgid "Do not show a status post for this upload" -msgstr "" - -#: mod/photos.php:1187 -msgid "Private Photo" -msgstr "" - -#: mod/photos.php:1188 -msgid "Public Photo" -msgstr "" - -#: mod/photos.php:1254 -msgid "Edit Album" -msgstr "" - -#: mod/photos.php:1260 -msgid "Show Newest First" -msgstr "" - -#: mod/photos.php:1262 -msgid "Show Oldest First" -msgstr "" - -#: mod/photos.php:1289 mod/photos.php:1861 -msgid "View Photo" -msgstr "" - -#: mod/photos.php:1335 -msgid "Permission denied. Access to this item may be restricted." -msgstr "" - -#: mod/photos.php:1337 -msgid "Photo not available" -msgstr "" - -#: mod/photos.php:1395 -msgid "View photo" -msgstr "" - -#: mod/photos.php:1395 -msgid "Edit photo" -msgstr "" - -#: mod/photos.php:1396 -msgid "Use as profile photo" -msgstr "" - -#: mod/photos.php:1421 -msgid "View Full Size" -msgstr "" - -#: mod/photos.php:1507 -msgid "Tags: " -msgstr "" - -#: mod/photos.php:1510 -msgid "[Remove any tag]" -msgstr "" - -#: mod/photos.php:1549 -msgid "New album name" -msgstr "" - -#: mod/photos.php:1550 -msgid "Caption" -msgstr "" - -#: mod/photos.php:1551 -msgid "Add a Tag" -msgstr "" - -#: mod/photos.php:1551 -msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping" -msgstr "" - -#: mod/photos.php:1552 -msgid "Do not rotate" -msgstr "" - -#: mod/photos.php:1553 -msgid "Rotate CW (right)" -msgstr "" - -#: mod/photos.php:1554 -msgid "Rotate CCW (left)" -msgstr "" - -#: mod/photos.php:1569 -msgid "Private photo" -msgstr "" - -#: mod/photos.php:1570 -msgid "Public photo" -msgstr "" - -#: mod/photos.php:1792 -msgid "Map" +msgid "%1$s welcomes %2$s" msgstr "" #: mod/dfrn_request.php:101 @@ -6445,6 +5571,19 @@ msgid "" "testuser@identi.ca" msgstr "" +#: mod/dfrn_request.php:874 mod/follow.php:112 +msgid "Please answer the following:" +msgstr "" + +#: mod/dfrn_request.php:875 mod/follow.php:113 +#, php-format +msgid "Does %s know you?" +msgstr "" + +#: mod/dfrn_request.php:879 mod/follow.php:114 +msgid "Add a personal note:" +msgstr "" + #: mod/dfrn_request.php:882 msgid "StatusNet/Federated Social Web" msgstr "" @@ -6456,6 +5595,246 @@ msgid "" "bar." msgstr "" +#: mod/dfrn_request.php:885 mod/follow.php:120 +msgid "Your Identity Address:" +msgstr "" + +#: mod/dfrn_request.php:888 mod/follow.php:19 +msgid "Submit Request" +msgstr "" + +#: mod/directory.php:199 view/theme/vier/theme.php:196 +msgid "Global Directory" +msgstr "" + +#: mod/directory.php:201 +msgid "Find on this site" +msgstr "" + +#: mod/directory.php:203 +msgid "Results for:" +msgstr "" + +#: mod/directory.php:205 +msgid "Site Directory" +msgstr "" + +#: mod/directory.php:212 +msgid "No entries (some entries may be hidden)." +msgstr "" + +#: mod/dirfind.php:37 +#, php-format +msgid "People Search - %s" +msgstr "" + +#: mod/dirfind.php:48 +#, php-format +msgid "Forum Search - %s" +msgstr "" + +#: mod/dirfind.php:245 mod/match.php:109 +msgid "No matches" +msgstr "" + +#: mod/display.php:479 +msgid "Item has been removed." +msgstr "" + +#: mod/editpost.php:17 mod/editpost.php:27 +msgid "Item not found" +msgstr "" + +#: mod/editpost.php:32 +msgid "Edit post" +msgstr "" + +#: mod/events.php:100 mod/events.php:102 +msgid "Event can not end before it has started." +msgstr "" + +#: mod/events.php:109 mod/events.php:111 +msgid "Event title and start time are required." +msgstr "" + +#: mod/events.php:388 +msgid "Create New Event" +msgstr "" + +#: mod/events.php:489 +msgid "Event details" +msgstr "" + +#: mod/events.php:490 +msgid "Starting date and Title are required." +msgstr "" + +#: mod/events.php:491 mod/events.php:492 +msgid "Event Starts:" +msgstr "" + +#: mod/events.php:491 mod/events.php:503 mod/profiles.php:708 +msgid "Required" +msgstr "" + +#: mod/events.php:493 mod/events.php:509 +msgid "Finish date/time is not known or not relevant" +msgstr "" + +#: mod/events.php:495 mod/events.php:496 +msgid "Event Finishes:" +msgstr "" + +#: mod/events.php:497 mod/events.php:510 +msgid "Adjust for viewer timezone" +msgstr "" + +#: mod/events.php:499 +msgid "Description:" +msgstr "" + +#: mod/events.php:503 mod/events.php:505 +msgid "Title:" +msgstr "" + +#: mod/events.php:506 mod/events.php:507 +msgid "Share this event" +msgstr "" + +#: mod/fbrowser.php:132 +msgid "Files" +msgstr "" + +#: mod/filer.php:30 +msgid "- select -" +msgstr "" + +#: mod/follow.php:30 +msgid "You already added this contact." +msgstr "" + +#: mod/follow.php:39 +msgid "Diaspora support isn't enabled. Contact can't be added." +msgstr "" + +#: mod/follow.php:46 +msgid "OStatus support is disabled. Contact can't be added." +msgstr "" + +#: mod/follow.php:53 +msgid "The network type couldn't be detected. Contact can't be added." +msgstr "" + +#: mod/follow.php:186 +msgid "Contact added" +msgstr "" + +#: mod/friendica.php:72 +msgid "This is Friendica, version" +msgstr "" + +#: mod/friendica.php:73 +msgid "running at web location" +msgstr "" + +#: mod/friendica.php:75 +msgid "" +"Please visit Friendica.com to learn " +"more about the Friendica project." +msgstr "" + +#: mod/friendica.php:77 +msgid "Bug reports and issues: please visit" +msgstr "" + +#: mod/friendica.php:77 +msgid "the bugtracker at github" +msgstr "" + +#: mod/friendica.php:78 +msgid "" +"Suggestions, praise, donations, etc. - please email \"Info\" at Friendica - " +"dot com" +msgstr "" + +#: mod/friendica.php:92 +msgid "Installed plugins/addons/apps:" +msgstr "" + +#: mod/friendica.php:105 +msgid "No installed plugins/addons/apps" +msgstr "" + +#: mod/fsuggest.php:64 +msgid "Friend suggestion sent." +msgstr "" + +#: mod/fsuggest.php:98 +msgid "Suggest Friends" +msgstr "" + +#: mod/fsuggest.php:100 +#, php-format +msgid "Suggest a friend for %s" +msgstr "" + +#: mod/group.php:29 +msgid "Group created." +msgstr "" + +#: mod/group.php:35 +msgid "Could not create group." +msgstr "" + +#: mod/group.php:49 mod/group.php:150 +msgid "Group not found." +msgstr "" + +#: mod/group.php:63 +msgid "Group name changed." +msgstr "" + +#: mod/group.php:91 +msgid "Save Group" +msgstr "" + +#: mod/group.php:97 +msgid "Create a group of contacts/friends." +msgstr "" + +#: mod/group.php:122 +msgid "Group removed." +msgstr "" + +#: mod/group.php:124 +msgid "Unable to remove group." +msgstr "" + +#: mod/group.php:187 +msgid "Group Editor" +msgstr "" + +#: mod/group.php:200 +msgid "Members" +msgstr "" + +#: mod/group.php:233 mod/profperm.php:107 +msgid "Click on a contact to add or remove." +msgstr "" + +#: mod/hcard.php:11 +msgid "No profile" +msgstr "" + +#: mod/help.php:41 +msgid "Help:" +msgstr "" + +#: mod/home.php:39 +#, php-format +msgid "Welcome to %s" +msgstr "" + #: mod/install.php:140 msgid "Friendica Communications Server - Setup" msgstr "" @@ -6816,6 +6195,1138 @@ msgid "" "IMPORTANT: You will need to [manually] setup a scheduled task for the poller." msgstr "" +#: mod/invite.php:28 +msgid "Total invitation limit exceeded." +msgstr "" + +#: mod/invite.php:51 +#, php-format +msgid "%s : Not a valid email address." +msgstr "" + +#: mod/invite.php:76 +msgid "Please join us on Friendica" +msgstr "" + +#: mod/invite.php:87 +msgid "Invitation limit exceeded. Please contact your site administrator." +msgstr "" + +#: mod/invite.php:91 +#, php-format +msgid "%s : Message delivery failed." +msgstr "" + +#: mod/invite.php:95 +#, php-format +msgid "%d message sent." +msgid_plural "%d messages sent." +msgstr[0] "" +msgstr[1] "" + +#: mod/invite.php:114 +msgid "You have no more invitations available" +msgstr "" + +#: mod/invite.php:122 +#, php-format +msgid "" +"Visit %s for a list of public sites that you can join. Friendica members on " +"other sites can all connect with each other, as well as with members of many " +"other social networks." +msgstr "" + +#: mod/invite.php:124 +#, php-format +msgid "" +"To accept this invitation, please visit and register at %s or any other " +"public Friendica website." +msgstr "" + +#: mod/invite.php:125 +#, php-format +msgid "" +"Friendica sites all inter-connect to create a huge privacy-enhanced social " +"web that is owned and controlled by its members. They can also connect with " +"many traditional social networks. See %s for a list of alternate Friendica " +"sites you can join." +msgstr "" + +#: mod/invite.php:128 +msgid "" +"Our apologies. This system is not currently configured to connect with other " +"public sites or invite members." +msgstr "" + +#: mod/invite.php:134 +msgid "Send invitations" +msgstr "" + +#: mod/invite.php:135 +msgid "Enter email addresses, one per line:" +msgstr "" + +#: mod/invite.php:136 mod/message.php:332 mod/message.php:515 +#: mod/wallmessage.php:135 +msgid "Your message:" +msgstr "" + +#: mod/invite.php:137 +msgid "" +"You are cordially invited to join me and other close friends on Friendica - " +"and help us to create a better social web." +msgstr "" + +#: mod/invite.php:139 +msgid "You will need to supply this invitation code: $invite_code" +msgstr "" + +#: mod/invite.php:139 +msgid "" +"Once you have registered, please connect with me via my profile page at:" +msgstr "" + +#: mod/invite.php:141 +msgid "" +"For more information about the Friendica project and why we feel it is " +"important, please visit http://friendica.com" +msgstr "" + +#: mod/item.php:118 +msgid "Unable to locate original post." +msgstr "" + +#: mod/item.php:336 +msgid "Empty post discarded." +msgstr "" + +#: mod/item.php:889 +msgid "System error. Post not saved." +msgstr "" + +#: mod/item.php:979 +#, php-format +msgid "" +"This message was sent to you by %s, a member of the Friendica social network." +msgstr "" + +#: mod/item.php:981 +#, php-format +msgid "You may visit them online at %s" +msgstr "" + +#: mod/item.php:982 +msgid "" +"Please contact the sender by replying to this post if you do not wish to " +"receive these messages." +msgstr "" + +#: mod/item.php:986 +#, php-format +msgid "%s posted an update." +msgstr "" + +#: mod/localtime.php:24 +msgid "Time Conversion" +msgstr "" + +#: mod/localtime.php:26 +msgid "" +"Friendica provides this service for sharing events with other networks and " +"friends in unknown timezones." +msgstr "" + +#: mod/localtime.php:30 +#, php-format +msgid "UTC time: %s" +msgstr "" + +#: mod/localtime.php:33 +#, php-format +msgid "Current timezone: %s" +msgstr "" + +#: mod/localtime.php:36 +#, php-format +msgid "Converted localtime: %s" +msgstr "" + +#: mod/localtime.php:41 +msgid "Please select your timezone:" +msgstr "" + +#: mod/lockview.php:32 mod/lockview.php:40 +msgid "Remote privacy information not available." +msgstr "" + +#: mod/lockview.php:49 +msgid "Visible to:" +msgstr "" + +#: mod/lostpass.php:19 +msgid "No valid account found." +msgstr "" + +#: mod/lostpass.php:35 +msgid "Password reset request issued. Check your email." +msgstr "" + +#: mod/lostpass.php:41 +#, php-format +msgid "" +"\n" +"\t\tDear %1$s,\n" +"\t\t\tA request was recently received at \"%2$s\" to reset your account\n" +"\t\tpassword. In order to confirm this request, please select the " +"verification link\n" +"\t\tbelow or paste it into your web browser address bar.\n" +"\n" +"\t\tIf you did NOT request this change, please DO NOT follow the link\n" +"\t\tprovided and ignore and/or delete this email.\n" +"\n" +"\t\tYour password will not be changed unless we can verify that you\n" +"\t\tissued this request." +msgstr "" + +#: mod/lostpass.php:52 +#, php-format +msgid "" +"\n" +"\t\tFollow this link to verify your identity:\n" +"\n" +"\t\t%1$s\n" +"\n" +"\t\tYou will then receive a follow-up message containing the new password.\n" +"\t\tYou may change that password from your account settings page after " +"logging in.\n" +"\n" +"\t\tThe login details are as follows:\n" +"\n" +"\t\tSite Location:\t%2$s\n" +"\t\tLogin Name:\t%3$s" +msgstr "" + +#: mod/lostpass.php:71 +#, php-format +msgid "Password reset requested at %s" +msgstr "" + +#: mod/lostpass.php:91 +msgid "" +"Request could not be verified. (You may have previously submitted it.) " +"Password reset failed." +msgstr "" + +#: mod/lostpass.php:111 +msgid "Your password has been reset as requested." +msgstr "" + +#: mod/lostpass.php:112 +msgid "Your new password is" +msgstr "" + +#: mod/lostpass.php:113 +msgid "Save or copy your new password - and then" +msgstr "" + +#: mod/lostpass.php:114 +msgid "click here to login" +msgstr "" + +#: mod/lostpass.php:115 +msgid "" +"Your password may be changed from the Settings page after " +"successful login." +msgstr "" + +#: mod/lostpass.php:125 +#, php-format +msgid "" +"\n" +"\t\t\t\tDear %1$s,\n" +"\t\t\t\t\tYour password has been changed as requested. Please retain this\n" +"\t\t\t\tinformation for your records (or change your password immediately " +"to\n" +"\t\t\t\tsomething that you will remember).\n" +"\t\t\t" +msgstr "" + +#: mod/lostpass.php:131 +#, php-format +msgid "" +"\n" +"\t\t\t\tYour login details are as follows:\n" +"\n" +"\t\t\t\tSite Location:\t%1$s\n" +"\t\t\t\tLogin Name:\t%2$s\n" +"\t\t\t\tPassword:\t%3$s\n" +"\n" +"\t\t\t\tYou may change that password from your account settings page after " +"logging in.\n" +"\t\t\t" +msgstr "" + +#: mod/lostpass.php:147 +#, php-format +msgid "Your password has been changed at %s" +msgstr "" + +#: mod/lostpass.php:159 +msgid "Forgot your Password?" +msgstr "" + +#: mod/lostpass.php:160 +msgid "" +"Enter your email address and submit to have your password reset. Then check " +"your email for further instructions." +msgstr "" + +#: mod/lostpass.php:162 +msgid "Reset" +msgstr "" + +#: mod/maintenance.php:20 +msgid "System down for maintenance" +msgstr "" + +#: mod/manage.php:141 +msgid "Manage Identities and/or Pages" +msgstr "" + +#: mod/manage.php:142 +msgid "" +"Toggle between different identities or community/group pages which share " +"your account details or which you have been granted \"manage\" permissions" +msgstr "" + +#: mod/manage.php:143 +msgid "Select an identity to manage: " +msgstr "" + +#: mod/match.php:35 +msgid "No keywords to match. Please add keywords to your default profile." +msgstr "" + +#: mod/match.php:88 +msgid "is interested in:" +msgstr "" + +#: mod/match.php:102 +msgid "Profile Match" +msgstr "" + +#: mod/message.php:60 mod/wallmessage.php:50 +msgid "No recipient selected." +msgstr "" + +#: mod/message.php:64 +msgid "Unable to locate contact information." +msgstr "" + +#: mod/message.php:67 mod/wallmessage.php:56 +msgid "Message could not be sent." +msgstr "" + +#: mod/message.php:70 mod/wallmessage.php:59 +msgid "Message collection failure." +msgstr "" + +#: mod/message.php:73 mod/wallmessage.php:62 +msgid "Message sent." +msgstr "" + +#: mod/message.php:204 +msgid "Do you really want to delete this message?" +msgstr "" + +#: mod/message.php:224 +msgid "Message deleted." +msgstr "" + +#: mod/message.php:255 +msgid "Conversation removed." +msgstr "" + +#: mod/message.php:322 mod/wallmessage.php:126 +msgid "Send Private Message" +msgstr "" + +#: mod/message.php:323 mod/message.php:510 mod/wallmessage.php:128 +msgid "To:" +msgstr "" + +#: mod/message.php:328 mod/message.php:512 mod/wallmessage.php:129 +msgid "Subject:" +msgstr "" + +#: mod/message.php:364 +msgid "No messages." +msgstr "" + +#: mod/message.php:403 +msgid "Message not available." +msgstr "" + +#: mod/message.php:477 +msgid "Delete message" +msgstr "" + +#: mod/message.php:503 mod/message.php:583 +msgid "Delete conversation" +msgstr "" + +#: mod/message.php:505 +msgid "" +"No secure communications available. You may be able to " +"respond from the sender's profile page." +msgstr "" + +#: mod/message.php:509 +msgid "Send Reply" +msgstr "" + +#: mod/message.php:553 +#, php-format +msgid "Unknown sender - %s" +msgstr "" + +#: mod/message.php:555 +#, php-format +msgid "You and %s" +msgstr "" + +#: mod/message.php:557 +#, php-format +msgid "%s and You" +msgstr "" + +#: mod/message.php:586 +msgid "D, d M Y - g:i A" +msgstr "" + +#: mod/message.php:589 +#, php-format +msgid "%d message" +msgid_plural "%d messages" +msgstr[0] "" +msgstr[1] "" + +#: mod/mood.php:134 +msgid "Mood" +msgstr "" + +#: mod/mood.php:135 +msgid "Set your current mood and tell your friends" +msgstr "" + +#: mod/network.php:190 mod/search.php:25 +msgid "Remove term" +msgstr "" + +#: mod/network.php:397 +#, php-format +msgid "" +"Warning: This group contains %s member from a network that doesn't allow non " +"public messages." +msgid_plural "" +"Warning: This group contains %s members from a network that doesn't allow " +"non public messages." +msgstr[0] "" +msgstr[1] "" + +#: mod/network.php:400 +msgid "Messages in this group won't be send to these receivers." +msgstr "" + +#: mod/network.php:528 +msgid "Private messages to this person are at risk of public disclosure." +msgstr "" + +#: mod/network.php:533 +msgid "Invalid contact." +msgstr "" + +#: mod/network.php:810 +msgid "Commented Order" +msgstr "" + +#: mod/network.php:813 +msgid "Sort by Comment Date" +msgstr "" + +#: mod/network.php:818 +msgid "Posted Order" +msgstr "" + +#: mod/network.php:821 +msgid "Sort by Post Date" +msgstr "" + +#: mod/network.php:832 +msgid "Posts that mention or involve you" +msgstr "" + +#: mod/network.php:840 +msgid "New" +msgstr "" + +#: mod/network.php:843 +msgid "Activity Stream - by date" +msgstr "" + +#: mod/network.php:851 +msgid "Shared Links" +msgstr "" + +#: mod/network.php:854 +msgid "Interesting Links" +msgstr "" + +#: mod/network.php:862 +msgid "Starred" +msgstr "" + +#: mod/network.php:865 +msgid "Favourite Posts" +msgstr "" + +#: mod/newmember.php:6 +msgid "Welcome to Friendica" +msgstr "" + +#: mod/newmember.php:8 +msgid "New Member Checklist" +msgstr "" + +#: mod/newmember.php:12 +msgid "" +"We would like to offer some tips and links to help make your experience " +"enjoyable. Click any item to visit the relevant page. A link to this page " +"will be visible from your home page for two weeks after your initial " +"registration and then will quietly disappear." +msgstr "" + +#: mod/newmember.php:14 +msgid "Getting Started" +msgstr "" + +#: mod/newmember.php:18 +msgid "Friendica Walk-Through" +msgstr "" + +#: mod/newmember.php:18 +msgid "" +"On your Quick Start page - find a brief introduction to your " +"profile and network tabs, make some new connections, and find some groups to " +"join." +msgstr "" + +#: mod/newmember.php:26 +msgid "Go to Your Settings" +msgstr "" + +#: mod/newmember.php:26 +msgid "" +"On your Settings page - change your initial password. Also make a " +"note of your Identity Address. This looks just like an email address - and " +"will be useful in making friends on the free social web." +msgstr "" + +#: mod/newmember.php:28 +msgid "" +"Review the other settings, particularly the privacy settings. An unpublished " +"directory listing is like having an unlisted phone number. In general, you " +"should probably publish your listing - unless all of your friends and " +"potential friends know exactly how to find you." +msgstr "" + +#: mod/newmember.php:36 mod/profile_photo.php:256 mod/profiles.php:699 +msgid "Upload Profile Photo" +msgstr "" + +#: mod/newmember.php:36 +msgid "" +"Upload a profile photo if you have not done so already. Studies have shown " +"that people with real photos of themselves are ten times more likely to make " +"friends than people who do not." +msgstr "" + +#: mod/newmember.php:38 +msgid "Edit Your Profile" +msgstr "" + +#: mod/newmember.php:38 +msgid "" +"Edit your default profile to your liking. Review the " +"settings for hiding your list of friends and hiding the profile from unknown " +"visitors." +msgstr "" + +#: mod/newmember.php:40 +msgid "Profile Keywords" +msgstr "" + +#: mod/newmember.php:40 +msgid "" +"Set some public keywords for your default profile which describe your " +"interests. We may be able to find other people with similar interests and " +"suggest friendships." +msgstr "" + +#: mod/newmember.php:44 +msgid "Connecting" +msgstr "" + +#: mod/newmember.php:51 +msgid "Importing Emails" +msgstr "" + +#: mod/newmember.php:51 +msgid "" +"Enter your email access information on your Connector Settings page if you " +"wish to import and interact with friends or mailing lists from your email " +"INBOX" +msgstr "" + +#: mod/newmember.php:53 +msgid "Go to Your Contacts Page" +msgstr "" + +#: mod/newmember.php:53 +msgid "" +"Your Contacts page is your gateway to managing friendships and connecting " +"with friends on other networks. Typically you enter their address or site " +"URL in the Add New Contact dialog." +msgstr "" + +#: mod/newmember.php:55 +msgid "Go to Your Site's Directory" +msgstr "" + +#: mod/newmember.php:55 +msgid "" +"The Directory page lets you find other people in this network or other " +"federated sites. Look for a Connect or Follow link on " +"their profile page. Provide your own Identity Address if requested." +msgstr "" + +#: mod/newmember.php:57 +msgid "Finding New People" +msgstr "" + +#: mod/newmember.php:57 +msgid "" +"On the side panel of the Contacts page are several tools to find new " +"friends. We can match people by interest, look up people by name or " +"interest, and provide suggestions based on network relationships. On a brand " +"new site, friend suggestions will usually begin to be populated within 24 " +"hours." +msgstr "" + +#: mod/newmember.php:65 +msgid "Group Your Contacts" +msgstr "" + +#: mod/newmember.php:65 +msgid "" +"Once you have made some friends, organize them into private conversation " +"groups from the sidebar of your Contacts page and then you can interact with " +"each group privately on your Network page." +msgstr "" + +#: mod/newmember.php:68 +msgid "Why Aren't My Posts Public?" +msgstr "" + +#: mod/newmember.php:68 +msgid "" +"Friendica respects your privacy. By default, your posts will only show up to " +"people you've added as friends. For more information, see the help section " +"from the link above." +msgstr "" + +#: mod/newmember.php:73 +msgid "Getting Help" +msgstr "" + +#: mod/newmember.php:77 +msgid "Go to the Help Section" +msgstr "" + +#: mod/newmember.php:77 +msgid "" +"Our help pages may be consulted for detail on other program " +"features and resources." +msgstr "" + +#: mod/nogroup.php:65 +msgid "Contacts who are not members of a group" +msgstr "" + +#: mod/notifications.php:35 +msgid "Invalid request identifier." +msgstr "" + +#: mod/notifications.php:44 mod/notifications.php:180 +#: mod/notifications.php:258 +msgid "Discard" +msgstr "" + +#: mod/notifications.php:105 +msgid "Network Notifications" +msgstr "" + +#: mod/notifications.php:111 mod/notify.php:69 +msgid "System Notifications" +msgstr "" + +#: mod/notifications.php:117 +msgid "Personal Notifications" +msgstr "" + +#: mod/notifications.php:123 +msgid "Home Notifications" +msgstr "" + +#: mod/notifications.php:152 +msgid "Show Ignored Requests" +msgstr "" + +#: mod/notifications.php:152 +msgid "Hide Ignored Requests" +msgstr "" + +#: mod/notifications.php:164 mod/notifications.php:228 +msgid "Notification type: " +msgstr "" + +#: mod/notifications.php:167 +#, php-format +msgid "suggested by %s" +msgstr "" + +#: mod/notifications.php:173 mod/notifications.php:246 +msgid "Post a new friend activity" +msgstr "" + +#: mod/notifications.php:173 mod/notifications.php:246 +msgid "if applicable" +msgstr "" + +#: mod/notifications.php:195 +msgid "Claims to be known to you: " +msgstr "" + +#: mod/notifications.php:196 +msgid "yes" +msgstr "" + +#: mod/notifications.php:196 +msgid "no" +msgstr "" + +#: mod/notifications.php:197 mod/notifications.php:202 +msgid "Shall your connection be bidirectional or not?" +msgstr "" + +#: mod/notifications.php:198 mod/notifications.php:203 +#, php-format +msgid "" +"Accepting %s as a friend allows %s to subscribe to your posts, and you will " +"also receive updates from them in your news feed." +msgstr "" + +#: mod/notifications.php:199 +#, php-format +msgid "" +"Accepting %s as a subscriber allows them to subscribe to your posts, but you " +"will not receive updates from them in your news feed." +msgstr "" + +#: mod/notifications.php:204 +#, php-format +msgid "" +"Accepting %s as a sharer allows them to subscribe to your posts, but you " +"will not receive updates from them in your news feed." +msgstr "" + +#: mod/notifications.php:215 +msgid "Friend" +msgstr "" + +#: mod/notifications.php:216 +msgid "Sharer" +msgstr "" + +#: mod/notifications.php:216 +msgid "Subscriber" +msgstr "" + +#: mod/notifications.php:266 +msgid "No introductions." +msgstr "" + +#: mod/notifications.php:307 +msgid "Show unread" +msgstr "" + +#: mod/notifications.php:307 +msgid "Show all" +msgstr "" + +#: mod/notifications.php:313 +#, php-format +msgid "No more %s notifications." +msgstr "" + +#: mod/notify.php:65 +msgid "No more system notifications." +msgstr "" + +#: mod/oexchange.php:21 +msgid "Post successful." +msgstr "" + +#: mod/openid.php:24 +msgid "OpenID protocol error. No ID returned." +msgstr "" + +#: mod/openid.php:60 +msgid "" +"Account not found and OpenID registration is not permitted on this site." +msgstr "" + +#: mod/ostatus_subscribe.php:14 +msgid "Subscribing to OStatus contacts" +msgstr "" + +#: mod/ostatus_subscribe.php:25 +msgid "No contact provided." +msgstr "" + +#: mod/ostatus_subscribe.php:31 +msgid "Couldn't fetch information for contact." +msgstr "" + +#: mod/ostatus_subscribe.php:40 +msgid "Couldn't fetch friends for contact." +msgstr "" + +#: mod/ostatus_subscribe.php:54 mod/repair_ostatus.php:44 +msgid "Done" +msgstr "" + +#: mod/ostatus_subscribe.php:68 +msgid "success" +msgstr "" + +#: mod/ostatus_subscribe.php:70 +msgid "failed" +msgstr "" + +#: mod/ostatus_subscribe.php:78 mod/repair_ostatus.php:50 +msgid "Keep this window open until done." +msgstr "" + +#: mod/p.php:9 +msgid "Not Extended" +msgstr "" + +#: mod/photos.php:90 mod/photos.php:1876 +msgid "Recent Photos" +msgstr "" + +#: mod/photos.php:93 mod/photos.php:1303 mod/photos.php:1878 +msgid "Upload New Photos" +msgstr "" + +#: mod/photos.php:107 mod/settings.php:36 +msgid "everybody" +msgstr "" + +#: mod/photos.php:171 +msgid "Contact information unavailable" +msgstr "" + +#: mod/photos.php:192 +msgid "Album not found." +msgstr "" + +#: mod/photos.php:225 mod/photos.php:237 mod/photos.php:1247 +msgid "Delete Album" +msgstr "" + +#: mod/photos.php:235 +msgid "Do you really want to delete this photo album and all its photos?" +msgstr "" + +#: mod/photos.php:317 mod/photos.php:328 mod/photos.php:1563 +msgid "Delete Photo" +msgstr "" + +#: mod/photos.php:326 +msgid "Do you really want to delete this photo?" +msgstr "" + +#: mod/photos.php:705 +#, php-format +msgid "%1$s was tagged in %2$s by %3$s" +msgstr "" + +#: mod/photos.php:705 +msgid "a photo" +msgstr "" + +#: mod/photos.php:803 mod/profile_photo.php:156 mod/wall_upload.php:151 +#, php-format +msgid "Image exceeds size limit of %s" +msgstr "" + +#: mod/photos.php:811 +msgid "Image file is empty." +msgstr "" + +#: mod/photos.php:844 mod/profile_photo.php:165 mod/wall_upload.php:186 +msgid "Unable to process image." +msgstr "" + +#: mod/photos.php:871 mod/profile_photo.php:315 mod/wall_upload.php:219 +msgid "Image upload failed." +msgstr "" + +#: mod/photos.php:974 +msgid "No photos selected" +msgstr "" + +#: mod/photos.php:1074 mod/videos.php:309 +msgid "Access to this item is restricted." +msgstr "" + +#: mod/photos.php:1134 +#, php-format +msgid "You have used %1$.2f Mbytes of %2$.2f Mbytes photo storage." +msgstr "" + +#: mod/photos.php:1168 +msgid "Upload Photos" +msgstr "" + +#: mod/photos.php:1172 mod/photos.php:1242 +msgid "New album name: " +msgstr "" + +#: mod/photos.php:1173 +msgid "or existing album name: " +msgstr "" + +#: mod/photos.php:1174 +msgid "Do not show a status post for this upload" +msgstr "" + +#: mod/photos.php:1185 mod/photos.php:1567 mod/settings.php:1307 +msgid "Show to Groups" +msgstr "" + +#: mod/photos.php:1186 mod/photos.php:1568 mod/settings.php:1308 +msgid "Show to Contacts" +msgstr "" + +#: mod/photos.php:1187 +msgid "Private Photo" +msgstr "" + +#: mod/photos.php:1188 +msgid "Public Photo" +msgstr "" + +#: mod/photos.php:1254 +msgid "Edit Album" +msgstr "" + +#: mod/photos.php:1260 +msgid "Show Newest First" +msgstr "" + +#: mod/photos.php:1262 +msgid "Show Oldest First" +msgstr "" + +#: mod/photos.php:1289 mod/photos.php:1861 +msgid "View Photo" +msgstr "" + +#: mod/photos.php:1335 +msgid "Permission denied. Access to this item may be restricted." +msgstr "" + +#: mod/photos.php:1337 +msgid "Photo not available" +msgstr "" + +#: mod/photos.php:1395 +msgid "View photo" +msgstr "" + +#: mod/photos.php:1395 +msgid "Edit photo" +msgstr "" + +#: mod/photos.php:1396 +msgid "Use as profile photo" +msgstr "" + +#: mod/photos.php:1421 +msgid "View Full Size" +msgstr "" + +#: mod/photos.php:1507 +msgid "Tags: " +msgstr "" + +#: mod/photos.php:1510 +msgid "[Remove any tag]" +msgstr "" + +#: mod/photos.php:1549 +msgid "New album name" +msgstr "" + +#: mod/photos.php:1550 +msgid "Caption" +msgstr "" + +#: mod/photos.php:1551 +msgid "Add a Tag" +msgstr "" + +#: mod/photos.php:1551 +msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping" +msgstr "" + +#: mod/photos.php:1552 +msgid "Do not rotate" +msgstr "" + +#: mod/photos.php:1553 +msgid "Rotate CW (right)" +msgstr "" + +#: mod/photos.php:1554 +msgid "Rotate CCW (left)" +msgstr "" + +#: mod/photos.php:1569 +msgid "Private photo" +msgstr "" + +#: mod/photos.php:1570 +msgid "Public photo" +msgstr "" + +#: mod/photos.php:1792 +msgid "Map" +msgstr "" + +#: mod/photos.php:1867 mod/videos.php:391 +msgid "View Album" +msgstr "" + +#: mod/ping.php:270 +msgid "{0} wants to be your friend" +msgstr "" + +#: mod/ping.php:285 +msgid "{0} sent you a message" +msgstr "" + +#: mod/ping.php:300 +msgid "{0} requested registration" +msgstr "" + +#: mod/poke.php:196 +msgid "Poke/Prod" +msgstr "" + +#: mod/poke.php:197 +msgid "poke, prod or do other things to somebody" +msgstr "" + +#: mod/poke.php:198 +msgid "Recipient" +msgstr "" + +#: mod/poke.php:199 +msgid "Choose what you wish to do to recipient" +msgstr "" + +#: mod/poke.php:202 +msgid "Make this post private" +msgstr "" + +#: mod/profile.php:174 +msgid "Tips for New Members" +msgstr "" + +#: mod/profile_photo.php:44 +msgid "Image uploaded but image cropping failed." +msgstr "" + +#: mod/profile_photo.php:77 mod/profile_photo.php:85 mod/profile_photo.php:93 +#: mod/profile_photo.php:323 +#, php-format +msgid "Image size reduction [%s] failed." +msgstr "" + +#: mod/profile_photo.php:127 +msgid "" +"Shift-reload the page or clear browser cache if the new photo does not " +"display immediately." +msgstr "" + +#: mod/profile_photo.php:137 +msgid "Unable to process image" +msgstr "" + +#: mod/profile_photo.php:254 +msgid "Upload File:" +msgstr "" + +#: mod/profile_photo.php:255 +msgid "Select a profile:" +msgstr "" + +#: mod/profile_photo.php:257 +msgid "Upload" +msgstr "" + +#: mod/profile_photo.php:260 +msgid "or" +msgstr "" + +#: mod/profile_photo.php:260 +msgid "skip this step" +msgstr "" + +#: mod/profile_photo.php:260 +msgid "select a photo from your photo albums" +msgstr "" + +#: mod/profile_photo.php:274 +msgid "Crop Image" +msgstr "" + +#: mod/profile_photo.php:275 +msgid "Please adjust the image cropping for optimum viewing." +msgstr "" + +#: mod/profile_photo.php:277 +msgid "Done Editing" +msgstr "" + +#: mod/profile_photo.php:313 +msgid "Image uploaded successfully." +msgstr "" + #: mod/profiles.php:38 msgid "Profile deleted." msgstr "" @@ -7115,1453 +7626,160 @@ msgstr "" msgid "Edit/Manage Profiles" msgstr "" -#: mod/display.php:479 -msgid "Item has been removed." +#: mod/profperm.php:26 mod/profperm.php:57 +msgid "Invalid profile identifier." msgstr "" -#: mod/admin.php:92 -msgid "Theme settings updated." +#: mod/profperm.php:103 +msgid "Profile Visibility Editor" msgstr "" -#: mod/admin.php:157 mod/admin.php:975 -msgid "Site" +#: mod/profperm.php:116 +msgid "Visible To" msgstr "" -#: mod/admin.php:158 mod/admin.php:909 mod/admin.php:1425 mod/admin.php:1441 -msgid "Users" +#: mod/profperm.php:132 +msgid "All Contacts (with secure profile access)" msgstr "" -#: mod/admin.php:160 mod/admin.php:1813 mod/admin.php:1863 -msgid "Themes" -msgstr "" - -#: mod/admin.php:162 -msgid "DB updates" -msgstr "" - -#: mod/admin.php:163 mod/admin.php:407 -msgid "Inspect Queue" -msgstr "" - -#: mod/admin.php:164 mod/admin.php:373 -msgid "Federation Statistics" -msgstr "" - -#: mod/admin.php:178 mod/admin.php:189 mod/admin.php:1937 -msgid "Logs" -msgstr "" - -#: mod/admin.php:179 mod/admin.php:2005 -msgid "View Logs" -msgstr "" - -#: mod/admin.php:180 -msgid "probe address" -msgstr "" - -#: mod/admin.php:181 -msgid "check webfinger" -msgstr "" - -#: mod/admin.php:188 -msgid "Plugin Features" -msgstr "" - -#: mod/admin.php:190 -msgid "diagnostics" -msgstr "" - -#: mod/admin.php:191 -msgid "User registrations waiting for confirmation" -msgstr "" - -#: mod/admin.php:307 -msgid "unknown" -msgstr "" - -#: mod/admin.php:366 +#: mod/register.php:93 msgid "" -"This page offers you some numbers to the known part of the federated social " -"network your Friendica node is part of. These numbers are not complete but " -"only reflect the part of the network your node is aware of." +"Registration successful. Please check your email for further instructions." msgstr "" -#: mod/admin.php:367 -msgid "" -"The Auto Discovered Contact Directory feature is not enabled, it " -"will improve the data displayed here." -msgstr "" - -#: mod/admin.php:372 mod/admin.php:406 mod/admin.php:485 mod/admin.php:974 -#: mod/admin.php:1424 mod/admin.php:1542 mod/admin.php:1605 mod/admin.php:1812 -#: mod/admin.php:1862 mod/admin.php:1936 mod/admin.php:2004 -msgid "Administration" -msgstr "" - -#: mod/admin.php:379 -#, php-format -msgid "Currently this node is aware of %d nodes from the following platforms:" -msgstr "" - -#: mod/admin.php:409 -msgid "ID" -msgstr "" - -#: mod/admin.php:410 -msgid "Recipient Name" -msgstr "" - -#: mod/admin.php:411 -msgid "Recipient Profile" -msgstr "" - -#: mod/admin.php:413 -msgid "Created" -msgstr "" - -#: mod/admin.php:414 -msgid "Last Tried" -msgstr "" - -#: mod/admin.php:415 -msgid "" -"This page lists the content of the queue for outgoing postings. These are " -"postings the initial delivery failed for. They will be resend later and " -"eventually deleted if the delivery fails permanently." -msgstr "" - -#: mod/admin.php:440 +#: mod/register.php:98 #, php-format msgid "" -"Your DB still runs with MyISAM tables. You should change the engine type to " -"InnoDB. As Friendica will use InnoDB only features in the future, you should " -"change this! See here for a guide that may be helpful " -"converting the table engines. You may also use the convert_innodb.sql in the /util directory of your Friendica installation.
    " +"Failed to send email message. Here your accout details:
    login: %s
    " +"password: %s

    You can change your password after login." msgstr "" -#: mod/admin.php:445 +#: mod/register.php:105 +msgid "Registration successful." +msgstr "" + +#: mod/register.php:111 +msgid "Your registration can not be processed." +msgstr "" + +#: mod/register.php:160 +msgid "Your registration is pending approval by the site owner." +msgstr "" + +#: mod/register.php:198 mod/uimport.php:51 msgid "" -"You are using a MySQL version which does not support all features that " -"Friendica uses. You should consider switching to MariaDB." +"This site has exceeded the number of allowed daily account registrations. " +"Please try again tomorrow." msgstr "" -#: mod/admin.php:449 mod/admin.php:1373 -msgid "Normal Account" -msgstr "" - -#: mod/admin.php:450 mod/admin.php:1374 -msgid "Soapbox Account" -msgstr "" - -#: mod/admin.php:451 mod/admin.php:1375 -msgid "Community/Celebrity Account" -msgstr "" - -#: mod/admin.php:452 mod/admin.php:1376 -msgid "Automatic Friend Account" -msgstr "" - -#: mod/admin.php:453 -msgid "Blog Account" -msgstr "" - -#: mod/admin.php:454 -msgid "Private Forum" -msgstr "" - -#: mod/admin.php:480 -msgid "Message queues" -msgstr "" - -#: mod/admin.php:486 -msgid "Summary" -msgstr "" - -#: mod/admin.php:489 -msgid "Registered users" -msgstr "" - -#: mod/admin.php:491 -msgid "Pending registrations" -msgstr "" - -#: mod/admin.php:492 -msgid "Version" -msgstr "" - -#: mod/admin.php:497 -msgid "Active plugins" -msgstr "" - -#: mod/admin.php:522 -msgid "Can not parse base url. Must have at least ://" -msgstr "" - -#: mod/admin.php:827 -msgid "RINO2 needs mcrypt php extension to work." -msgstr "" - -#: mod/admin.php:835 -msgid "Site settings updated." -msgstr "" - -#: mod/admin.php:892 -msgid "No community page" -msgstr "" - -#: mod/admin.php:893 -msgid "Public postings from users of this site" -msgstr "" - -#: mod/admin.php:894 -msgid "Global community page" -msgstr "" - -#: mod/admin.php:900 -msgid "At post arrival" -msgstr "" - -#: mod/admin.php:910 -msgid "Users, Global Contacts" -msgstr "" - -#: mod/admin.php:911 -msgid "Users, Global Contacts/fallback" -msgstr "" - -#: mod/admin.php:915 -msgid "One month" -msgstr "" - -#: mod/admin.php:916 -msgid "Three months" -msgstr "" - -#: mod/admin.php:917 -msgid "Half a year" -msgstr "" - -#: mod/admin.php:918 -msgid "One year" -msgstr "" - -#: mod/admin.php:923 -msgid "Multi user instance" -msgstr "" - -#: mod/admin.php:946 -msgid "Closed" -msgstr "" - -#: mod/admin.php:947 -msgid "Requires approval" -msgstr "" - -#: mod/admin.php:948 -msgid "Open" -msgstr "" - -#: mod/admin.php:952 -msgid "No SSL policy, links will track page SSL state" -msgstr "" - -#: mod/admin.php:953 -msgid "Force all links to use SSL" -msgstr "" - -#: mod/admin.php:954 -msgid "Self-signed certificate, use SSL for local links only (discouraged)" -msgstr "" - -#: mod/admin.php:978 -msgid "File upload" -msgstr "" - -#: mod/admin.php:979 -msgid "Policies" -msgstr "" - -#: mod/admin.php:981 -msgid "Auto Discovered Contact Directory" -msgstr "" - -#: mod/admin.php:982 -msgid "Performance" -msgstr "" - -#: mod/admin.php:983 -msgid "Worker" -msgstr "" - -#: mod/admin.php:984 +#: mod/register.php:226 msgid "" -"Relocate - WARNING: advanced function. Could make this server unreachable." +"You may (optionally) fill in this form via OpenID by supplying your OpenID " +"and clicking 'Register'." msgstr "" -#: mod/admin.php:987 -msgid "Site name" -msgstr "" - -#: mod/admin.php:988 -msgid "Host name" -msgstr "" - -#: mod/admin.php:989 -msgid "Sender Email" -msgstr "" - -#: mod/admin.php:989 +#: mod/register.php:227 msgid "" -"The email address your server shall use to send notification emails from." +"If you are not familiar with OpenID, please leave that field blank and fill " +"in the rest of the items." msgstr "" -#: mod/admin.php:990 -msgid "Banner/Logo" +#: mod/register.php:228 +msgid "Your OpenID (optional): " msgstr "" -#: mod/admin.php:991 -msgid "Shortcut icon" +#: mod/register.php:242 +msgid "Include your profile in member directory?" msgstr "" -#: mod/admin.php:991 -msgid "Link to an icon that will be used for browsers." +#: mod/register.php:267 +msgid "Note for the admin" msgstr "" -#: mod/admin.php:992 -msgid "Touch icon" +#: mod/register.php:267 +msgid "Leave a message for the admin, why you want to join this node" msgstr "" -#: mod/admin.php:992 -msgid "Link to an icon that will be used for tablets and mobiles." +#: mod/register.php:268 +msgid "Membership on this site is by invitation only." msgstr "" -#: mod/admin.php:993 -msgid "Additional Info" +#: mod/register.php:269 +msgid "Your invitation ID: " msgstr "" -#: mod/admin.php:993 +#: mod/register.php:280 +msgid "Your Full Name (e.g. Joe Smith, real or real-looking): " +msgstr "" + +#: mod/register.php:281 +msgid "Your Email Address: " +msgstr "" + +#: mod/register.php:283 mod/settings.php:1278 +msgid "New Password:" +msgstr "" + +#: mod/register.php:283 +msgid "Leave empty for an auto generated password." +msgstr "" + +#: mod/register.php:284 mod/settings.php:1279 +msgid "Confirm:" +msgstr "" + +#: mod/register.php:285 +msgid "" +"Choose a profile nickname. This must begin with a text character. Your " +"profile address on this site will then be 'nickname@$sitename'." +msgstr "" + +#: mod/register.php:286 +msgid "Choose a nickname: " +msgstr "" + +#: mod/register.php:295 mod/uimport.php:66 +msgid "Import" +msgstr "" + +#: mod/register.php:296 +msgid "Import your profile to this friendica instance" +msgstr "" + +#: mod/regmod.php:58 +msgid "Account approved." +msgstr "" + +#: mod/regmod.php:95 #, php-format +msgid "Registration revoked for %s" +msgstr "" + +#: mod/regmod.php:107 +msgid "Please login." +msgstr "" + +#: mod/removeme.php:52 mod/removeme.php:55 +msgid "Remove My Account" +msgstr "" + +#: mod/removeme.php:53 msgid "" -"For public servers: you can add additional information here that will be " -"listed at %s/siteinfo." +"This will completely remove your account. Once this has been done it is not " +"recoverable." msgstr "" -#: mod/admin.php:994 -msgid "System language" +#: mod/removeme.php:54 +msgid "Please enter your password for verification:" msgstr "" -#: mod/admin.php:995 -msgid "System theme" +#: mod/repair_ostatus.php:14 +msgid "Resubscribing to OStatus contacts" msgstr "" -#: mod/admin.php:995 -msgid "" -"Default system theme - may be over-ridden by user profiles - change theme settings" -msgstr "" - -#: mod/admin.php:996 -msgid "Mobile system theme" -msgstr "" - -#: mod/admin.php:996 -msgid "Theme for mobile devices" -msgstr "" - -#: mod/admin.php:997 -msgid "SSL link policy" -msgstr "" - -#: mod/admin.php:997 -msgid "Determines whether generated links should be forced to use SSL" -msgstr "" - -#: mod/admin.php:998 -msgid "Force SSL" -msgstr "" - -#: mod/admin.php:998 -msgid "" -"Force all Non-SSL requests to SSL - Attention: on some systems it could lead " -"to endless loops." -msgstr "" - -#: mod/admin.php:999 -msgid "Old style 'Share'" -msgstr "" - -#: mod/admin.php:999 -msgid "Deactivates the bbcode element 'share' for repeating items." -msgstr "" - -#: mod/admin.php:1000 -msgid "Hide help entry from navigation menu" -msgstr "" - -#: mod/admin.php:1000 -msgid "" -"Hides the menu entry for the Help pages from the navigation menu. You can " -"still access it calling /help directly." -msgstr "" - -#: mod/admin.php:1001 -msgid "Single user instance" -msgstr "" - -#: mod/admin.php:1001 -msgid "Make this instance multi-user or single-user for the named user" -msgstr "" - -#: mod/admin.php:1002 -msgid "Maximum image size" -msgstr "" - -#: mod/admin.php:1002 -msgid "" -"Maximum size in bytes of uploaded images. Default is 0, which means no " -"limits." -msgstr "" - -#: mod/admin.php:1003 -msgid "Maximum image length" -msgstr "" - -#: mod/admin.php:1003 -msgid "" -"Maximum length in pixels of the longest side of uploaded images. Default is " -"-1, which means no limits." -msgstr "" - -#: mod/admin.php:1004 -msgid "JPEG image quality" -msgstr "" - -#: mod/admin.php:1004 -msgid "" -"Uploaded JPEGS will be saved at this quality setting [0-100]. Default is " -"100, which is full quality." -msgstr "" - -#: mod/admin.php:1006 -msgid "Register policy" -msgstr "" - -#: mod/admin.php:1007 -msgid "Maximum Daily Registrations" -msgstr "" - -#: mod/admin.php:1007 -msgid "" -"If registration is permitted above, this sets the maximum number of new user " -"registrations to accept per day. If register is set to closed, this setting " -"has no effect." -msgstr "" - -#: mod/admin.php:1008 -msgid "Register text" -msgstr "" - -#: mod/admin.php:1008 -msgid "Will be displayed prominently on the registration page." -msgstr "" - -#: mod/admin.php:1009 -msgid "Accounts abandoned after x days" -msgstr "" - -#: mod/admin.php:1009 -msgid "" -"Will not waste system resources polling external sites for abandonded " -"accounts. Enter 0 for no time limit." -msgstr "" - -#: mod/admin.php:1010 -msgid "Allowed friend domains" -msgstr "" - -#: mod/admin.php:1010 -msgid "" -"Comma separated list of domains which are allowed to establish friendships " -"with this site. Wildcards are accepted. Empty to allow any domains" -msgstr "" - -#: mod/admin.php:1011 -msgid "Allowed email domains" -msgstr "" - -#: mod/admin.php:1011 -msgid "" -"Comma separated list of domains which are allowed in email addresses for " -"registrations to this site. Wildcards are accepted. Empty to allow any " -"domains" -msgstr "" - -#: mod/admin.php:1012 -msgid "Block public" -msgstr "" - -#: mod/admin.php:1012 -msgid "" -"Check to block public access to all otherwise public personal pages on this " -"site unless you are currently logged in." -msgstr "" - -#: mod/admin.php:1013 -msgid "Force publish" -msgstr "" - -#: mod/admin.php:1013 -msgid "" -"Check to force all profiles on this site to be listed in the site directory." -msgstr "" - -#: mod/admin.php:1014 -msgid "Global directory URL" -msgstr "" - -#: mod/admin.php:1014 -msgid "" -"URL to the global directory. If this is not set, the global directory is " -"completely unavailable to the application." -msgstr "" - -#: mod/admin.php:1015 -msgid "Allow threaded items" -msgstr "" - -#: mod/admin.php:1015 -msgid "Allow infinite level threading for items on this site." -msgstr "" - -#: mod/admin.php:1016 -msgid "Private posts by default for new users" -msgstr "" - -#: mod/admin.php:1016 -msgid "" -"Set default post permissions for all new members to the default privacy " -"group rather than public." -msgstr "" - -#: mod/admin.php:1017 -msgid "Don't include post content in email notifications" -msgstr "" - -#: mod/admin.php:1017 -msgid "" -"Don't include the content of a post/comment/private message/etc. in the " -"email notifications that are sent out from this site, as a privacy measure." -msgstr "" - -#: mod/admin.php:1018 -msgid "Disallow public access to addons listed in the apps menu." -msgstr "" - -#: mod/admin.php:1018 -msgid "" -"Checking this box will restrict addons listed in the apps menu to members " -"only." -msgstr "" - -#: mod/admin.php:1019 -msgid "Don't embed private images in posts" -msgstr "" - -#: mod/admin.php:1019 -msgid "" -"Don't replace locally-hosted private photos in posts with an embedded copy " -"of the image. This means that contacts who receive posts containing private " -"photos will have to authenticate and load each image, which may take a while." -msgstr "" - -#: mod/admin.php:1020 -msgid "Allow Users to set remote_self" -msgstr "" - -#: mod/admin.php:1020 -msgid "" -"With checking this, every user is allowed to mark every contact as a " -"remote_self in the repair contact dialog. Setting this flag on a contact " -"causes mirroring every posting of that contact in the users stream." -msgstr "" - -#: mod/admin.php:1021 -msgid "Block multiple registrations" -msgstr "" - -#: mod/admin.php:1021 -msgid "Disallow users to register additional accounts for use as pages." -msgstr "" - -#: mod/admin.php:1022 -msgid "OpenID support" -msgstr "" - -#: mod/admin.php:1022 -msgid "OpenID support for registration and logins." -msgstr "" - -#: mod/admin.php:1023 -msgid "Fullname check" -msgstr "" - -#: mod/admin.php:1023 -msgid "" -"Force users to register with a space between firstname and lastname in Full " -"name, as an antispam measure" -msgstr "" - -#: mod/admin.php:1024 -msgid "UTF-8 Regular expressions" -msgstr "" - -#: mod/admin.php:1024 -msgid "Use PHP UTF8 regular expressions" -msgstr "" - -#: mod/admin.php:1025 -msgid "Community Page Style" -msgstr "" - -#: mod/admin.php:1025 -msgid "" -"Type of community page to show. 'Global community' shows every public " -"posting from an open distributed network that arrived on this server." -msgstr "" - -#: mod/admin.php:1026 -msgid "Posts per user on community page" -msgstr "" - -#: mod/admin.php:1026 -msgid "" -"The maximum number of posts per user on the community page. (Not valid for " -"'Global Community')" -msgstr "" - -#: mod/admin.php:1027 -msgid "Enable OStatus support" -msgstr "" - -#: mod/admin.php:1027 -msgid "" -"Provide built-in OStatus (StatusNet, GNU Social etc.) compatibility. All " -"communications in OStatus are public, so privacy warnings will be " -"occasionally displayed." -msgstr "" - -#: mod/admin.php:1028 -msgid "OStatus conversation completion interval" -msgstr "" - -#: mod/admin.php:1028 -msgid "" -"How often shall the poller check for new entries in OStatus conversations? " -"This can be a very ressource task." -msgstr "" - -#: mod/admin.php:1029 -msgid "Only import OStatus threads from our contacts" -msgstr "" - -#: mod/admin.php:1029 -msgid "" -"Normally we import every content from our OStatus contacts. With this option " -"we only store threads that are started by a contact that is known on our " -"system." -msgstr "" - -#: mod/admin.php:1030 -msgid "OStatus support can only be enabled if threading is enabled." -msgstr "" - -#: mod/admin.php:1032 -msgid "" -"Diaspora support can't be enabled because Friendica was installed into a sub " -"directory." -msgstr "" - -#: mod/admin.php:1033 -msgid "Enable Diaspora support" -msgstr "" - -#: mod/admin.php:1033 -msgid "Provide built-in Diaspora network compatibility." -msgstr "" - -#: mod/admin.php:1034 -msgid "Only allow Friendica contacts" -msgstr "" - -#: mod/admin.php:1034 -msgid "" -"All contacts must use Friendica protocols. All other built-in communication " -"protocols disabled." -msgstr "" - -#: mod/admin.php:1035 -msgid "Verify SSL" -msgstr "" - -#: mod/admin.php:1035 -msgid "" -"If you wish, you can turn on strict certificate checking. This will mean you " -"cannot connect (at all) to self-signed SSL sites." -msgstr "" - -#: mod/admin.php:1036 -msgid "Proxy user" -msgstr "" - -#: mod/admin.php:1037 -msgid "Proxy URL" -msgstr "" - -#: mod/admin.php:1038 -msgid "Network timeout" -msgstr "" - -#: mod/admin.php:1038 -msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." -msgstr "" - -#: mod/admin.php:1039 -msgid "Delivery interval" -msgstr "" - -#: mod/admin.php:1039 -msgid "" -"Delay background delivery processes by this many seconds to reduce system " -"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 " -"for large dedicated servers." -msgstr "" - -#: mod/admin.php:1040 -msgid "Poll interval" -msgstr "" - -#: mod/admin.php:1040 -msgid "" -"Delay background polling processes by this many seconds to reduce system " -"load. If 0, use delivery interval." -msgstr "" - -#: mod/admin.php:1041 -msgid "Maximum Load Average" -msgstr "" - -#: mod/admin.php:1041 -msgid "" -"Maximum system load before delivery and poll processes are deferred - " -"default 50." -msgstr "" - -#: mod/admin.php:1042 -msgid "Maximum Load Average (Frontend)" -msgstr "" - -#: mod/admin.php:1042 -msgid "Maximum system load before the frontend quits service - default 50." -msgstr "" - -#: mod/admin.php:1043 -msgid "Maximum table size for optimization" -msgstr "" - -#: mod/admin.php:1043 -msgid "" -"Maximum table size (in MB) for the automatic optimization - default 100 MB. " -"Enter -1 to disable it." -msgstr "" - -#: mod/admin.php:1044 -msgid "Minimum level of fragmentation" -msgstr "" - -#: mod/admin.php:1044 -msgid "" -"Minimum fragmenation level to start the automatic optimization - default " -"value is 30%." -msgstr "" - -#: mod/admin.php:1046 -msgid "Periodical check of global contacts" -msgstr "" - -#: mod/admin.php:1046 -msgid "" -"If enabled, the global contacts are checked periodically for missing or " -"outdated data and the vitality of the contacts and servers." -msgstr "" - -#: mod/admin.php:1047 -msgid "Days between requery" -msgstr "" - -#: mod/admin.php:1047 -msgid "Number of days after which a server is requeried for his contacts." -msgstr "" - -#: mod/admin.php:1048 -msgid "Discover contacts from other servers" -msgstr "" - -#: mod/admin.php:1048 -msgid "" -"Periodically query other servers for contacts. You can choose between " -"'users': the users on the remote system, 'Global Contacts': active contacts " -"that are known on the system. The fallback is meant for Redmatrix servers " -"and older friendica servers, where global contacts weren't available. The " -"fallback increases the server load, so the recommened setting is 'Users, " -"Global Contacts'." -msgstr "" - -#: mod/admin.php:1049 -msgid "Timeframe for fetching global contacts" -msgstr "" - -#: mod/admin.php:1049 -msgid "" -"When the discovery is activated, this value defines the timeframe for the " -"activity of the global contacts that are fetched from other servers." -msgstr "" - -#: mod/admin.php:1050 -msgid "Search the local directory" -msgstr "" - -#: mod/admin.php:1050 -msgid "" -"Search the local directory instead of the global directory. When searching " -"locally, every search will be executed on the global directory in the " -"background. This improves the search results when the search is repeated." -msgstr "" - -#: mod/admin.php:1052 -msgid "Publish server information" -msgstr "" - -#: mod/admin.php:1052 -msgid "" -"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 the-federation.info for details." -msgstr "" - -#: mod/admin.php:1054 -msgid "Use MySQL full text engine" -msgstr "" - -#: mod/admin.php:1054 -msgid "" -"Activates the full text engine. Speeds up search - but can only search for " -"four and more characters." -msgstr "" - -#: mod/admin.php:1055 -msgid "Suppress Language" -msgstr "" - -#: mod/admin.php:1055 -msgid "Suppress language information in meta information about a posting." -msgstr "" - -#: mod/admin.php:1056 -msgid "Suppress Tags" -msgstr "" - -#: mod/admin.php:1056 -msgid "Suppress showing a list of hashtags at the end of the posting." -msgstr "" - -#: mod/admin.php:1057 -msgid "Path to item cache" -msgstr "" - -#: mod/admin.php:1057 -msgid "The item caches buffers generated bbcode and external images." -msgstr "" - -#: mod/admin.php:1058 -msgid "Cache duration in seconds" -msgstr "" - -#: mod/admin.php:1058 -msgid "" -"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." -msgstr "" - -#: mod/admin.php:1059 -msgid "Maximum numbers of comments per post" -msgstr "" - -#: mod/admin.php:1059 -msgid "How much comments should be shown for each post? Default value is 100." -msgstr "" - -#: mod/admin.php:1060 -msgid "Path for lock file" -msgstr "" - -#: mod/admin.php:1060 -msgid "" -"The lock file is used to avoid multiple pollers at one time. Only define a " -"folder here." -msgstr "" - -#: mod/admin.php:1061 -msgid "Temp path" -msgstr "" - -#: mod/admin.php:1061 -msgid "" -"If you have a restricted system where the webserver can't access the system " -"temp path, enter another path here." -msgstr "" - -#: mod/admin.php:1062 -msgid "Base path to installation" -msgstr "" - -#: mod/admin.php:1062 -msgid "" -"If the system cannot detect the correct path to your installation, enter the " -"correct path here. This setting should only be set if you are using a " -"restricted system and symbolic links to your webroot." -msgstr "" - -#: mod/admin.php:1063 -msgid "Disable picture proxy" -msgstr "" - -#: mod/admin.php:1063 -msgid "" -"The picture proxy increases performance and privacy. It shouldn't be used on " -"systems with very low bandwith." -msgstr "" - -#: mod/admin.php:1064 -msgid "Enable old style pager" -msgstr "" - -#: mod/admin.php:1064 -msgid "" -"The old style pager has page numbers but slows down massively the page speed." -msgstr "" - -#: mod/admin.php:1065 -msgid "Only search in tags" -msgstr "" - -#: mod/admin.php:1065 -msgid "On large systems the text search can slow down the system extremely." -msgstr "" - -#: mod/admin.php:1067 -msgid "New base url" -msgstr "" - -#: mod/admin.php:1067 -msgid "" -"Change base url for this server. Sends relocate message to all DFRN contacts " -"of all users." -msgstr "" - -#: mod/admin.php:1069 -msgid "RINO Encryption" -msgstr "" - -#: mod/admin.php:1069 -msgid "Encryption layer between nodes." -msgstr "" - -#: mod/admin.php:1070 -msgid "Embedly API key" -msgstr "" - -#: mod/admin.php:1070 -msgid "" -"Embedly is used to fetch additional data for " -"web pages. This is an optional parameter." -msgstr "" - -#: mod/admin.php:1072 -msgid "Enable 'worker' background processing" -msgstr "" - -#: mod/admin.php:1072 -msgid "" -"The worker background processing limits the number of parallel background " -"jobs to a maximum number and respects the system load." -msgstr "" - -#: mod/admin.php:1073 -msgid "Maximum number of parallel workers" -msgstr "" - -#: mod/admin.php:1073 -msgid "" -"On shared hosters set this to 2. On larger systems, values of 10 are great. " -"Default value is 4." -msgstr "" - -#: mod/admin.php:1074 -msgid "Don't use 'proc_open' with the worker" -msgstr "" - -#: mod/admin.php:1074 -msgid "" -"Enable this if your system doesn't allow the use of 'proc_open'. This can " -"happen on shared hosters. If this is enabled you should increase the " -"frequency of poller calls in your crontab." -msgstr "" - -#: mod/admin.php:1075 -msgid "Enable fastlane" -msgstr "" - -#: mod/admin.php:1075 -msgid "" -"When enabed, the fastlane mechanism starts an additional worker if processes " -"with higher priority are blocked by processes of lower priority." -msgstr "" - -#: mod/admin.php:1076 -msgid "Enable frontend worker" -msgstr "" - -#: mod/admin.php:1076 -msgid "" -"When enabled the Worker process is triggered when backend access is " -"performed (e.g. messages being delivered). On smaller sites you might want " -"to call yourdomain.tld/worker on a regular basis via an external cron job. " -"You should only enable this option if you cannot utilize cron/scheduled jobs " -"on your server. The worker background process needs to be activated for this." -msgstr "" - -#: mod/admin.php:1105 -msgid "Update has been marked successful" -msgstr "" - -#: mod/admin.php:1113 -#, php-format -msgid "Database structure update %s was successfully applied." -msgstr "" - -#: mod/admin.php:1116 -#, php-format -msgid "Executing of database structure update %s failed with error: %s" -msgstr "" - -#: mod/admin.php:1128 -#, php-format -msgid "Executing %s failed with error: %s" -msgstr "" - -#: mod/admin.php:1131 -#, php-format -msgid "Update %s was successfully applied." -msgstr "" - -#: mod/admin.php:1135 -#, php-format -msgid "Update %s did not return a status. Unknown if it succeeded." -msgstr "" - -#: mod/admin.php:1137 -#, php-format -msgid "There was no additional update function %s that needed to be called." -msgstr "" - -#: mod/admin.php:1156 -msgid "No failed updates." -msgstr "" - -#: mod/admin.php:1157 -msgid "Check database structure" -msgstr "" - -#: mod/admin.php:1162 -msgid "Failed Updates" -msgstr "" - -#: mod/admin.php:1163 -msgid "" -"This does not include updates prior to 1139, which did not return a status." -msgstr "" - -#: mod/admin.php:1164 -msgid "Mark success (if update was manually applied)" -msgstr "" - -#: mod/admin.php:1165 -msgid "Attempt to execute this update step automatically" -msgstr "" - -#: mod/admin.php:1199 -#, php-format -msgid "" -"\n" -"\t\t\tDear %1$s,\n" -"\t\t\t\tthe administrator of %2$s has set up an account for you." -msgstr "" - -#: mod/admin.php:1202 -#, php-format -msgid "" -"\n" -"\t\t\tThe login details are as follows:\n" -"\n" -"\t\t\tSite Location:\t%1$s\n" -"\t\t\tLogin Name:\t\t%2$s\n" -"\t\t\tPassword:\t\t%3$s\n" -"\n" -"\t\t\tYou may change your password from your account \"Settings\" page after " -"logging\n" -"\t\t\tin.\n" -"\n" -"\t\t\tPlease take a few moments to review the other account settings on that " -"page.\n" -"\n" -"\t\t\tYou may also wish to add some basic information to your default " -"profile\n" -"\t\t\t(on the \"Profiles\" page) so that other people can easily find you.\n" -"\n" -"\t\t\tWe recommend setting your full name, adding a profile photo,\n" -"\t\t\tadding some profile \"keywords\" (very useful in making new friends) - " -"and\n" -"\t\t\tperhaps what country you live in; if you do not wish to be more " -"specific\n" -"\t\t\tthan that.\n" -"\n" -"\t\t\tWe fully respect your right to privacy, and none of these items are " -"necessary.\n" -"\t\t\tIf you are new and do not know anybody here, they may help\n" -"\t\t\tyou to make some new and interesting friends.\n" -"\n" -"\t\t\tThank you and welcome to %4$s." -msgstr "" - -#: mod/admin.php:1246 -#, php-format -msgid "%s user blocked/unblocked" -msgid_plural "%s users blocked/unblocked" -msgstr[0] "" -msgstr[1] "" - -#: mod/admin.php:1253 -#, php-format -msgid "%s user deleted" -msgid_plural "%s users deleted" -msgstr[0] "" -msgstr[1] "" - -#: mod/admin.php:1300 -#, php-format -msgid "User '%s' deleted" -msgstr "" - -#: mod/admin.php:1308 -#, php-format -msgid "User '%s' unblocked" -msgstr "" - -#: mod/admin.php:1308 -#, php-format -msgid "User '%s' blocked" -msgstr "" - -#: mod/admin.php:1417 mod/admin.php:1443 -msgid "Register date" -msgstr "" - -#: mod/admin.php:1417 mod/admin.php:1443 -msgid "Last login" -msgstr "" - -#: mod/admin.php:1417 mod/admin.php:1443 -msgid "Last item" -msgstr "" - -#: mod/admin.php:1426 -msgid "Add User" -msgstr "" - -#: mod/admin.php:1427 -msgid "select all" -msgstr "" - -#: mod/admin.php:1428 -msgid "User registrations waiting for confirm" -msgstr "" - -#: mod/admin.php:1429 -msgid "User waiting for permanent deletion" -msgstr "" - -#: mod/admin.php:1430 -msgid "Request date" -msgstr "" - -#: mod/admin.php:1431 -msgid "No registrations." -msgstr "" - -#: mod/admin.php:1432 -msgid "Note from the user" -msgstr "" - -#: mod/admin.php:1433 mod/notifications.php:176 mod/notifications.php:255 -msgid "Approve" -msgstr "" - -#: mod/admin.php:1434 -msgid "Deny" -msgstr "" - -#: mod/admin.php:1438 -msgid "Site admin" -msgstr "" - -#: mod/admin.php:1439 -msgid "Account expired" -msgstr "" - -#: mod/admin.php:1442 -msgid "New User" -msgstr "" - -#: mod/admin.php:1443 -msgid "Deleted since" -msgstr "" - -#: mod/admin.php:1448 -msgid "" -"Selected users will be deleted!\\n\\nEverything these users had posted on " -"this site will be permanently deleted!\\n\\nAre you sure?" -msgstr "" - -#: mod/admin.php:1449 -msgid "" -"The user {0} will be deleted!\\n\\nEverything this user has posted on this " -"site will be permanently deleted!\\n\\nAre you sure?" -msgstr "" - -#: mod/admin.php:1459 -msgid "Name of the new user." -msgstr "" - -#: mod/admin.php:1460 -msgid "Nickname" -msgstr "" - -#: mod/admin.php:1460 -msgid "Nickname of the new user." -msgstr "" - -#: mod/admin.php:1461 -msgid "Email address of the new user." -msgstr "" - -#: mod/admin.php:1504 -#, php-format -msgid "Plugin %s disabled." -msgstr "" - -#: mod/admin.php:1508 -#, php-format -msgid "Plugin %s enabled." -msgstr "" - -#: mod/admin.php:1519 mod/admin.php:1767 -msgid "Disable" -msgstr "" - -#: mod/admin.php:1521 mod/admin.php:1769 -msgid "Enable" -msgstr "" - -#: mod/admin.php:1544 mod/admin.php:1814 -msgid "Toggle" -msgstr "" - -#: mod/admin.php:1552 mod/admin.php:1823 -msgid "Author: " -msgstr "" - -#: mod/admin.php:1553 mod/admin.php:1824 -msgid "Maintainer: " -msgstr "" - -#: mod/admin.php:1608 -msgid "Reload active plugins" -msgstr "" - -#: mod/admin.php:1613 -#, php-format -msgid "" -"There are currently no plugins available on your node. You can find the " -"official plugin repository at %1$s and might find other interesting plugins " -"in the open plugin registry at %2$s" -msgstr "" - -#: mod/admin.php:1727 -msgid "No themes found." -msgstr "" - -#: mod/admin.php:1805 -msgid "Screenshot" -msgstr "" - -#: mod/admin.php:1865 -msgid "Reload active themes" -msgstr "" - -#: mod/admin.php:1870 -#, php-format -msgid "No themes found on the system. They should be paced in %1$s" -msgstr "" - -#: mod/admin.php:1871 -msgid "[Experimental]" -msgstr "" - -#: mod/admin.php:1872 -msgid "[Unsupported]" -msgstr "" - -#: mod/admin.php:1896 -msgid "Log settings updated." -msgstr "" - -#: mod/admin.php:1928 -msgid "PHP log currently enabled." -msgstr "" - -#: mod/admin.php:1930 -msgid "PHP log currently disabled." -msgstr "" - -#: mod/admin.php:1939 -msgid "Clear" -msgstr "" - -#: mod/admin.php:1944 -msgid "Enable Debugging" -msgstr "" - -#: mod/admin.php:1945 -msgid "Log file" -msgstr "" - -#: mod/admin.php:1945 -msgid "" -"Must be writable by web server. Relative to your Friendica top-level " -"directory." -msgstr "" - -#: mod/admin.php:1946 -msgid "Log level" -msgstr "" - -#: mod/admin.php:1949 -msgid "PHP logging" -msgstr "" - -#: mod/admin.php:1950 -msgid "" -"To enable logging of PHP errors and warnings you can add the following to " -"the .htconfig.php file of your installation. The filename set in the " -"'error_log' line is relative to the friendica top-level directory and must " -"be writeable by the web server. The option '1' for 'log_errors' and " -"'display_errors' is to enable these options, set to '0' to disable them." -msgstr "" - -#: mod/admin.php:2078 -#, php-format -msgid "Lock feature %s" -msgstr "" - -#: mod/admin.php:2086 -msgid "Manage Additional Features" -msgstr "" - -#: mod/viewcontacts.php:75 -msgid "No contacts." -msgstr "" - -#: mod/network.php:190 mod/search.php:25 -msgid "Remove term" -msgstr "" - -#: mod/network.php:397 -#, php-format -msgid "" -"Warning: This group contains %s member from a network that doesn't allow non " -"public messages." -msgid_plural "" -"Warning: This group contains %s members from a network that doesn't allow " -"non public messages." -msgstr[0] "" -msgstr[1] "" - -#: mod/network.php:400 -msgid "Messages in this group won't be send to these receivers." -msgstr "" - -#: mod/network.php:528 -msgid "Private messages to this person are at risk of public disclosure." -msgstr "" - -#: mod/network.php:533 -msgid "Invalid contact." -msgstr "" - -#: mod/network.php:827 -msgid "Commented Order" -msgstr "" - -#: mod/network.php:830 -msgid "Sort by Comment Date" -msgstr "" - -#: mod/network.php:835 -msgid "Posted Order" -msgstr "" - -#: mod/network.php:838 -msgid "Sort by Post Date" -msgstr "" - -#: mod/network.php:849 -msgid "Posts that mention or involve you" -msgstr "" - -#: mod/network.php:857 -msgid "New" -msgstr "" - -#: mod/network.php:860 -msgid "Activity Stream - by date" -msgstr "" - -#: mod/network.php:868 -msgid "Shared Links" -msgstr "" - -#: mod/network.php:871 -msgid "Interesting Links" -msgstr "" - -#: mod/network.php:879 -msgid "Starred" -msgstr "" - -#: mod/network.php:882 -msgid "Favourite Posts" +#: mod/repair_ostatus.php:30 +msgid "Error" msgstr "" #: mod/search.php:100 @@ -8581,122 +7799,991 @@ msgstr "" msgid "Items tagged with: %s" msgstr "" -#: mod/notifications.php:35 -msgid "Invalid request identifier." +#: mod/settings.php:60 +msgid "Display" msgstr "" -#: mod/notifications.php:44 mod/notifications.php:180 -#: mod/notifications.php:258 -msgid "Discard" +#: mod/settings.php:67 mod/settings.php:890 +msgid "Social Networks" msgstr "" -#: mod/notifications.php:105 -msgid "Network Notifications" +#: mod/settings.php:88 +msgid "Connected apps" msgstr "" -#: mod/notifications.php:117 -msgid "Personal Notifications" +#: mod/settings.php:95 mod/uexport.php:45 +msgid "Export personal data" msgstr "" -#: mod/notifications.php:123 -msgid "Home Notifications" +#: mod/settings.php:102 +msgid "Remove account" msgstr "" -#: mod/notifications.php:152 -msgid "Show Ignored Requests" +#: mod/settings.php:157 +msgid "Missing some important data!" msgstr "" -#: mod/notifications.php:152 -msgid "Hide Ignored Requests" +#: mod/settings.php:271 +msgid "Failed to connect with email account using the settings provided." msgstr "" -#: mod/notifications.php:164 mod/notifications.php:228 -msgid "Notification type: " +#: mod/settings.php:276 +msgid "Email settings updated." msgstr "" -#: mod/notifications.php:167 +#: mod/settings.php:291 +msgid "Features updated" +msgstr "" + +#: mod/settings.php:361 +msgid "Relocate message has been send to your contacts" +msgstr "" + +#: mod/settings.php:380 +msgid "Empty passwords are not allowed. Password unchanged." +msgstr "" + +#: mod/settings.php:388 +msgid "Wrong password." +msgstr "" + +#: mod/settings.php:399 +msgid "Password changed." +msgstr "" + +#: mod/settings.php:401 +msgid "Password update failed. Please try again." +msgstr "" + +#: mod/settings.php:481 +msgid " Please use a shorter name." +msgstr "" + +#: mod/settings.php:483 +msgid " Name too short." +msgstr "" + +#: mod/settings.php:492 +msgid "Wrong Password" +msgstr "" + +#: mod/settings.php:497 +msgid " Not valid email." +msgstr "" + +#: mod/settings.php:503 +msgid " Cannot change to that email." +msgstr "" + +#: mod/settings.php:559 +msgid "Private forum has no privacy permissions. Using default privacy group." +msgstr "" + +#: mod/settings.php:563 +msgid "Private forum has no privacy permissions and no default privacy group." +msgstr "" + +#: mod/settings.php:603 +msgid "Settings updated." +msgstr "" + +#: mod/settings.php:680 mod/settings.php:706 mod/settings.php:742 +msgid "Add application" +msgstr "" + +#: mod/settings.php:684 mod/settings.php:710 +msgid "Consumer Key" +msgstr "" + +#: mod/settings.php:685 mod/settings.php:711 +msgid "Consumer Secret" +msgstr "" + +#: mod/settings.php:686 mod/settings.php:712 +msgid "Redirect" +msgstr "" + +#: mod/settings.php:687 mod/settings.php:713 +msgid "Icon url" +msgstr "" + +#: mod/settings.php:698 +msgid "You can't edit this application." +msgstr "" + +#: mod/settings.php:741 +msgid "Connected Apps" +msgstr "" + +#: mod/settings.php:745 +msgid "Client key starts with" +msgstr "" + +#: mod/settings.php:746 +msgid "No name" +msgstr "" + +#: mod/settings.php:747 +msgid "Remove authorization" +msgstr "" + +#: mod/settings.php:759 +msgid "No Plugin settings configured" +msgstr "" + +#: mod/settings.php:768 +msgid "Plugin Settings" +msgstr "" + +#: mod/settings.php:790 +msgid "Additional Features" +msgstr "" + +#: mod/settings.php:800 mod/settings.php:804 +msgid "General Social Media Settings" +msgstr "" + +#: mod/settings.php:810 +msgid "Disable intelligent shortening" +msgstr "" + +#: mod/settings.php:812 +msgid "" +"Normally the system tries to find the best link to add to shortened posts. " +"If this option is enabled then every shortened post will always point to the " +"original friendica post." +msgstr "" + +#: mod/settings.php:818 +msgid "Automatically follow any GNU Social (OStatus) followers/mentioners" +msgstr "" + +#: mod/settings.php:820 +msgid "" +"If you receive a message from an unknown OStatus user, this option decides " +"what to do. If it is checked, a new contact will be created for every " +"unknown user." +msgstr "" + +#: mod/settings.php:826 +msgid "Default group for OStatus contacts" +msgstr "" + +#: mod/settings.php:834 +msgid "Your legacy GNU Social account" +msgstr "" + +#: mod/settings.php:836 +msgid "" +"If you enter your old GNU Social/Statusnet account name here (in the format " +"user@domain.tld), your contacts will be added automatically. The field will " +"be emptied when done." +msgstr "" + +#: mod/settings.php:839 +msgid "Repair OStatus subscriptions" +msgstr "" + +#: mod/settings.php:848 mod/settings.php:849 #, php-format -msgid "suggested by %s" +msgid "Built-in support for %s connectivity is %s" msgstr "" -#: mod/notifications.php:173 mod/notifications.php:246 -msgid "Post a new friend activity" +#: mod/settings.php:848 mod/settings.php:849 +msgid "enabled" msgstr "" -#: mod/notifications.php:173 mod/notifications.php:246 -msgid "if applicable" +#: mod/settings.php:848 mod/settings.php:849 +msgid "disabled" msgstr "" -#: mod/notifications.php:195 -msgid "Claims to be known to you: " +#: mod/settings.php:849 +msgid "GNU Social (OStatus)" msgstr "" -#: mod/notifications.php:196 -msgid "yes" +#: mod/settings.php:883 +msgid "Email access is disabled on this site." msgstr "" -#: mod/notifications.php:196 -msgid "no" +#: mod/settings.php:895 +msgid "Email/Mailbox Setup" msgstr "" -#: mod/notifications.php:197 mod/notifications.php:202 -msgid "Shall your connection be bidirectional or not?" +#: mod/settings.php:896 +msgid "" +"If you wish to communicate with email contacts using this service " +"(optional), please specify how to connect to your mailbox." msgstr "" -#: mod/notifications.php:198 mod/notifications.php:203 +#: mod/settings.php:897 +msgid "Last successful email check:" +msgstr "" + +#: mod/settings.php:899 +msgid "IMAP server name:" +msgstr "" + +#: mod/settings.php:900 +msgid "IMAP port:" +msgstr "" + +#: mod/settings.php:901 +msgid "Security:" +msgstr "" + +#: mod/settings.php:901 mod/settings.php:906 +msgid "None" +msgstr "" + +#: mod/settings.php:902 +msgid "Email login name:" +msgstr "" + +#: mod/settings.php:903 +msgid "Email password:" +msgstr "" + +#: mod/settings.php:904 +msgid "Reply-to address:" +msgstr "" + +#: mod/settings.php:905 +msgid "Send public posts to all email contacts:" +msgstr "" + +#: mod/settings.php:906 +msgid "Action after import:" +msgstr "" + +#: mod/settings.php:906 +msgid "Move to folder" +msgstr "" + +#: mod/settings.php:907 +msgid "Move to folder:" +msgstr "" + +#: mod/settings.php:1003 +msgid "Display Settings" +msgstr "" + +#: mod/settings.php:1009 mod/settings.php:1032 +msgid "Display Theme:" +msgstr "" + +#: mod/settings.php:1010 +msgid "Mobile Theme:" +msgstr "" + +#: mod/settings.php:1011 +msgid "Suppress warning of insecure networks" +msgstr "" + +#: mod/settings.php:1011 +msgid "" +"Should the system suppress the warning that the current group contains " +"members of networks that can't receive non public postings." +msgstr "" + +#: mod/settings.php:1012 +msgid "Update browser every xx seconds" +msgstr "" + +#: mod/settings.php:1012 +msgid "Minimum of 10 seconds. Enter -1 to disable it." +msgstr "" + +#: mod/settings.php:1013 +msgid "Number of items to display per page:" +msgstr "" + +#: mod/settings.php:1013 mod/settings.php:1014 +msgid "Maximum of 100 items" +msgstr "" + +#: mod/settings.php:1014 +msgid "Number of items to display per page when viewed from mobile device:" +msgstr "" + +#: mod/settings.php:1015 +msgid "Don't show emoticons" +msgstr "" + +#: mod/settings.php:1016 +msgid "Calendar" +msgstr "" + +#: mod/settings.php:1017 +msgid "Beginning of week:" +msgstr "" + +#: mod/settings.php:1018 +msgid "Don't show notices" +msgstr "" + +#: mod/settings.php:1019 +msgid "Infinite scroll" +msgstr "" + +#: mod/settings.php:1020 +msgid "Automatic updates only at the top of the network page" +msgstr "" + +#: mod/settings.php:1021 +msgid "Bandwith Saver Mode" +msgstr "" + +#: mod/settings.php:1021 +msgid "" +"When enabled, embedded content is not displayed on automatic updates, they " +"only show on page reload." +msgstr "" + +#: mod/settings.php:1023 +msgid "General Theme Settings" +msgstr "" + +#: mod/settings.php:1024 +msgid "Custom Theme Settings" +msgstr "" + +#: mod/settings.php:1025 +msgid "Content Settings" +msgstr "" + +#: mod/settings.php:1026 view/theme/duepuntozero/config.php:63 +#: view/theme/frio/config.php:66 view/theme/quattro/config.php:69 +#: view/theme/vier/config.php:114 +msgid "Theme settings" +msgstr "" + +#: mod/settings.php:1110 +msgid "Account Types" +msgstr "" + +#: mod/settings.php:1111 +msgid "Personal Page Subtypes" +msgstr "" + +#: mod/settings.php:1112 +msgid "Community Forum Subtypes" +msgstr "" + +#: mod/settings.php:1119 +msgid "Personal Page" +msgstr "" + +#: mod/settings.php:1120 +msgid "This account is a regular personal profile" +msgstr "" + +#: mod/settings.php:1123 +msgid "Organisation Page" +msgstr "" + +#: mod/settings.php:1124 +msgid "This account is a profile for an organisation" +msgstr "" + +#: mod/settings.php:1127 +msgid "News Page" +msgstr "" + +#: mod/settings.php:1128 +msgid "This account is a news account/reflector" +msgstr "" + +#: mod/settings.php:1131 +msgid "Community Forum" +msgstr "" + +#: mod/settings.php:1132 +msgid "" +"This account is a community forum where people can discuss with each other" +msgstr "" + +#: mod/settings.php:1135 +msgid "Normal Account Page" +msgstr "" + +#: mod/settings.php:1136 +msgid "This account is a normal personal profile" +msgstr "" + +#: mod/settings.php:1139 +msgid "Soapbox Page" +msgstr "" + +#: mod/settings.php:1140 +msgid "Automatically approve all connection/friend requests as read-only fans" +msgstr "" + +#: mod/settings.php:1143 +msgid "Public Forum" +msgstr "" + +#: mod/settings.php:1144 +msgid "Automatically approve all contact requests" +msgstr "" + +#: mod/settings.php:1147 +msgid "Automatic Friend Page" +msgstr "" + +#: mod/settings.php:1148 +msgid "Automatically approve all connection/friend requests as friends" +msgstr "" + +#: mod/settings.php:1151 +msgid "Private Forum [Experimental]" +msgstr "" + +#: mod/settings.php:1152 +msgid "Private forum - approved members only" +msgstr "" + +#: mod/settings.php:1163 +msgid "OpenID:" +msgstr "" + +#: mod/settings.php:1163 +msgid "(Optional) Allow this OpenID to login to this account." +msgstr "" + +#: mod/settings.php:1171 +msgid "Publish your default profile in your local site directory?" +msgstr "" + +#: mod/settings.php:1177 +msgid "Publish your default profile in the global social directory?" +msgstr "" + +#: mod/settings.php:1184 +msgid "Hide your contact/friend list from viewers of your default profile?" +msgstr "" + +#: mod/settings.php:1188 +msgid "" +"If enabled, posting public messages to Diaspora and other networks isn't " +"possible." +msgstr "" + +#: mod/settings.php:1193 +msgid "Allow friends to post to your profile page?" +msgstr "" + +#: mod/settings.php:1198 +msgid "Allow friends to tag your posts?" +msgstr "" + +#: mod/settings.php:1203 +msgid "Allow us to suggest you as a potential friend to new members?" +msgstr "" + +#: mod/settings.php:1208 +msgid "Permit unknown people to send you private mail?" +msgstr "" + +#: mod/settings.php:1216 +msgid "Profile is not published." +msgstr "" + +#: mod/settings.php:1224 +#, php-format +msgid "Your Identity Address is '%s' or '%s'." +msgstr "" + +#: mod/settings.php:1231 +msgid "Automatically expire posts after this many days:" +msgstr "" + +#: mod/settings.php:1231 +msgid "If empty, posts will not expire. Expired posts will be deleted" +msgstr "" + +#: mod/settings.php:1232 +msgid "Advanced expiration settings" +msgstr "" + +#: mod/settings.php:1233 +msgid "Advanced Expiration" +msgstr "" + +#: mod/settings.php:1234 +msgid "Expire posts:" +msgstr "" + +#: mod/settings.php:1235 +msgid "Expire personal notes:" +msgstr "" + +#: mod/settings.php:1236 +msgid "Expire starred posts:" +msgstr "" + +#: mod/settings.php:1237 +msgid "Expire photos:" +msgstr "" + +#: mod/settings.php:1238 +msgid "Only expire posts by others:" +msgstr "" + +#: mod/settings.php:1269 +msgid "Account Settings" +msgstr "" + +#: mod/settings.php:1277 +msgid "Password Settings" +msgstr "" + +#: mod/settings.php:1279 +msgid "Leave password fields blank unless changing" +msgstr "" + +#: mod/settings.php:1280 +msgid "Current Password:" +msgstr "" + +#: mod/settings.php:1280 mod/settings.php:1281 +msgid "Your current password to confirm the changes" +msgstr "" + +#: mod/settings.php:1281 +msgid "Password:" +msgstr "" + +#: mod/settings.php:1285 +msgid "Basic Settings" +msgstr "" + +#: mod/settings.php:1287 +msgid "Email Address:" +msgstr "" + +#: mod/settings.php:1288 +msgid "Your Timezone:" +msgstr "" + +#: mod/settings.php:1289 +msgid "Your Language:" +msgstr "" + +#: mod/settings.php:1289 +msgid "" +"Set the language we use to show you friendica interface and to send you " +"emails" +msgstr "" + +#: mod/settings.php:1290 +msgid "Default Post Location:" +msgstr "" + +#: mod/settings.php:1291 +msgid "Use Browser Location:" +msgstr "" + +#: mod/settings.php:1294 +msgid "Security and Privacy Settings" +msgstr "" + +#: mod/settings.php:1296 +msgid "Maximum Friend Requests/Day:" +msgstr "" + +#: mod/settings.php:1296 mod/settings.php:1326 +msgid "(to prevent spam abuse)" +msgstr "" + +#: mod/settings.php:1297 +msgid "Default Post Permissions" +msgstr "" + +#: mod/settings.php:1298 +msgid "(click to open/close)" +msgstr "" + +#: mod/settings.php:1309 +msgid "Default Private Post" +msgstr "" + +#: mod/settings.php:1310 +msgid "Default Public Post" +msgstr "" + +#: mod/settings.php:1314 +msgid "Default Permissions for New Posts" +msgstr "" + +#: mod/settings.php:1326 +msgid "Maximum private messages per day from unknown people:" +msgstr "" + +#: mod/settings.php:1329 +msgid "Notification Settings" +msgstr "" + +#: mod/settings.php:1330 +msgid "By default post a status message when:" +msgstr "" + +#: mod/settings.php:1331 +msgid "accepting a friend request" +msgstr "" + +#: mod/settings.php:1332 +msgid "joining a forum/community" +msgstr "" + +#: mod/settings.php:1333 +msgid "making an interesting profile change" +msgstr "" + +#: mod/settings.php:1334 +msgid "Send a notification email when:" +msgstr "" + +#: mod/settings.php:1335 +msgid "You receive an introduction" +msgstr "" + +#: mod/settings.php:1336 +msgid "Your introductions are confirmed" +msgstr "" + +#: mod/settings.php:1337 +msgid "Someone writes on your profile wall" +msgstr "" + +#: mod/settings.php:1338 +msgid "Someone writes a followup comment" +msgstr "" + +#: mod/settings.php:1339 +msgid "You receive a private message" +msgstr "" + +#: mod/settings.php:1340 +msgid "You receive a friend suggestion" +msgstr "" + +#: mod/settings.php:1341 +msgid "You are tagged in a post" +msgstr "" + +#: mod/settings.php:1342 +msgid "You are poked/prodded/etc. in a post" +msgstr "" + +#: mod/settings.php:1344 +msgid "Activate desktop notifications" +msgstr "" + +#: mod/settings.php:1344 +msgid "Show desktop popup on new notifications" +msgstr "" + +#: mod/settings.php:1346 +msgid "Text-only notification emails" +msgstr "" + +#: mod/settings.php:1348 +msgid "Send text only notification emails, without the html part" +msgstr "" + +#: mod/settings.php:1350 +msgid "Advanced Account/Page Type Settings" +msgstr "" + +#: mod/settings.php:1351 +msgid "Change the behaviour of this account for special situations" +msgstr "" + +#: mod/settings.php:1354 +msgid "Relocate" +msgstr "" + +#: mod/settings.php:1355 +msgid "" +"If you have moved this profile from another server, and some of your " +"contacts don't receive your updates, try pushing this button." +msgstr "" + +#: mod/settings.php:1356 +msgid "Resend relocate message to contacts" +msgstr "" + +#: mod/subthread.php:104 +#, php-format +msgid "%1$s is following %2$s's %3$s" +msgstr "" + +#: mod/suggest.php:27 +msgid "Do you really want to delete this suggestion?" +msgstr "" + +#: mod/suggest.php:71 +msgid "" +"No suggestions available. If this is a new site, please try again in 24 " +"hours." +msgstr "" + +#: mod/suggest.php:84 mod/suggest.php:104 +msgid "Ignore/Hide" +msgstr "" + +#: mod/tagrm.php:43 +msgid "Tag removed" +msgstr "" + +#: mod/tagrm.php:82 +msgid "Remove Item Tag" +msgstr "" + +#: mod/tagrm.php:84 +msgid "Select a tag to remove: " +msgstr "" + +#: mod/uexport.php:37 +msgid "Export account" +msgstr "" + +#: mod/uexport.php:37 +msgid "" +"Export your account info and contacts. Use this to make a backup of your " +"account and/or to move it to another server." +msgstr "" + +#: mod/uexport.php:38 +msgid "Export all" +msgstr "" + +#: mod/uexport.php:38 +msgid "" +"Export your accout info, contacts and all your items as json. Could be a " +"very big file, and could take a lot of time. Use this to make a full backup " +"of your account (photos are not exported)" +msgstr "" + +#: mod/uimport.php:68 +msgid "Move account" +msgstr "" + +#: mod/uimport.php:69 +msgid "You can import an account from another Friendica server." +msgstr "" + +#: mod/uimport.php:70 +msgid "" +"You need to export your account from the old server and upload it here. We " +"will recreate your old account here with all your contacts. We will try also " +"to inform your friends that you moved here." +msgstr "" + +#: mod/uimport.php:71 +msgid "" +"This feature is experimental. We can't import contacts from the OStatus " +"network (GNU Social/Statusnet) or from Diaspora" +msgstr "" + +#: mod/uimport.php:72 +msgid "Account file" +msgstr "" + +#: mod/uimport.php:72 +msgid "" +"To export your account, go to \"Settings->Export your personal data\" and " +"select \"Export account\"" +msgstr "" + +#: mod/update_community.php:19 mod/update_display.php:23 +#: mod/update_network.php:27 mod/update_notes.php:36 mod/update_profile.php:35 +msgid "[Embedded content - reload page to view]" +msgstr "" + +#: mod/videos.php:124 +msgid "Do you really want to delete this video?" +msgstr "" + +#: mod/videos.php:129 +msgid "Delete Video" +msgstr "" + +#: mod/videos.php:208 +msgid "No videos selected" +msgstr "" + +#: mod/videos.php:400 +msgid "Recent Videos" +msgstr "" + +#: mod/videos.php:402 +msgid "Upload New Videos" +msgstr "" + +#: mod/viewcontacts.php:75 +msgid "No contacts." +msgstr "" + +#: mod/viewsrc.php:7 +msgid "Access denied." +msgstr "" + +#: mod/wall_attach.php:17 mod/wall_attach.php:25 mod/wall_attach.php:76 +#: mod/wall_upload.php:20 mod/wall_upload.php:33 mod/wall_upload.php:86 +#: mod/wall_upload.php:122 mod/wall_upload.php:125 +msgid "Invalid request." +msgstr "" + +#: mod/wall_attach.php:94 +msgid "Sorry, maybe your upload is bigger than the PHP configuration allows" +msgstr "" + +#: mod/wall_attach.php:94 +msgid "Or - did you try to upload an empty file?" +msgstr "" + +#: mod/wall_attach.php:105 +#, php-format +msgid "File exceeds size limit of %s" +msgstr "" + +#: mod/wall_attach.php:158 mod/wall_attach.php:174 +msgid "File upload failed." +msgstr "" + +#: mod/wallmessage.php:42 mod/wallmessage.php:106 +#, php-format +msgid "Number of daily wall messages for %s exceeded. Message failed." +msgstr "" + +#: mod/wallmessage.php:53 +msgid "Unable to check your home location." +msgstr "" + +#: mod/wallmessage.php:80 mod/wallmessage.php:89 +msgid "No recipient." +msgstr "" + +#: mod/wallmessage.php:127 #, php-format msgid "" -"Accepting %s as a friend allows %s to subscribe to your posts, and you will " -"also receive updates from them in your news feed." +"If you wish for %s to respond, please check that the privacy settings on " +"your site allow private mail from unknown senders." msgstr "" -#: mod/notifications.php:199 -#, php-format -msgid "" -"Accepting %s as a subscriber allows them to subscribe to your posts, but you " -"will not receive updates from them in your news feed." -msgstr "" - -#: mod/notifications.php:204 -#, php-format -msgid "" -"Accepting %s as a sharer allows them to subscribe to your posts, but you " -"will not receive updates from them in your news feed." -msgstr "" - -#: mod/notifications.php:215 -msgid "Friend" -msgstr "" - -#: mod/notifications.php:216 -msgid "Sharer" -msgstr "" - -#: mod/notifications.php:216 -msgid "Subscriber" -msgstr "" - -#: mod/notifications.php:266 -msgid "No introductions." -msgstr "" - -#: mod/notifications.php:307 -msgid "Show unread" -msgstr "" - -#: mod/notifications.php:307 -msgid "Show all" -msgstr "" - -#: mod/notifications.php:313 -#, php-format -msgid "No more %s notifications." -msgstr "" - -#: object/Item.php:385 +#: object/Item.php:359 msgid "via" msgstr "" +#: view/theme/duepuntozero/config.php:44 +msgid "greenzero" +msgstr "" + +#: view/theme/duepuntozero/config.php:45 +msgid "purplezero" +msgstr "" + +#: view/theme/duepuntozero/config.php:46 +msgid "easterbunny" +msgstr "" + +#: view/theme/duepuntozero/config.php:47 +msgid "darkzero" +msgstr "" + +#: view/theme/duepuntozero/config.php:48 +msgid "comix" +msgstr "" + +#: view/theme/duepuntozero/config.php:49 +msgid "slackr" +msgstr "" + +#: view/theme/duepuntozero/config.php:64 +msgid "Variations" +msgstr "" + +#: view/theme/frio/config.php:47 +msgid "Default" +msgstr "" + +#: view/theme/frio/config.php:59 +msgid "Note: " +msgstr "" + +#: view/theme/frio/config.php:59 +msgid "Check image permissions if all users are allowed to visit the image" +msgstr "" + +#: view/theme/frio/config.php:67 +msgid "Select scheme" +msgstr "" + +#: view/theme/frio/config.php:68 +msgid "Navigation bar background color" +msgstr "" + +#: view/theme/frio/config.php:69 +msgid "Navigation bar icon color " +msgstr "" + +#: view/theme/frio/config.php:70 +msgid "Link color" +msgstr "" + +#: view/theme/frio/config.php:71 +msgid "Set the background color" +msgstr "" + +#: view/theme/frio/config.php:72 +msgid "Content background transparency" +msgstr "" + +#: view/theme/frio/config.php:73 +msgid "Set the background image" +msgstr "" + +#: view/theme/frio/php/Image.php:23 +msgid "Repeat the image" +msgstr "" + +#: view/theme/frio/php/Image.php:23 +msgid "Will repeat your image to fill the background." +msgstr "" + +#: view/theme/frio/php/Image.php:25 +msgid "Stretch" +msgstr "" + +#: view/theme/frio/php/Image.php:25 +msgid "Will stretch to width/height of the image." +msgstr "" + +#: view/theme/frio/php/Image.php:27 +msgid "Resize fill and-clip" +msgstr "" + +#: view/theme/frio/php/Image.php:27 +msgid "Resize to fill and retain aspect ratio." +msgstr "" + +#: view/theme/frio/php/Image.php:29 +msgid "Resize best fit" +msgstr "" + +#: view/theme/frio/php/Image.php:29 +msgid "Resize to best fit and retain aspect ratio." +msgstr "" + +#: view/theme/frio/theme.php:226 +msgid "Guest" +msgstr "" + +#: view/theme/frio/theme.php:232 +msgid "Visitor" +msgstr "" + #: view/theme/quattro/config.php:70 msgid "Alignment" msgstr "" @@ -8709,7 +8796,7 @@ msgstr "" msgid "Center" msgstr "" -#: view/theme/quattro/config.php:71 view/theme/clean/config.php:108 +#: view/theme/quattro/config.php:71 msgid "Color scheme" msgstr "" @@ -8760,223 +8847,3 @@ msgstr "" #: view/theme/vier/theme.php:286 msgid "Quick Start" msgstr "" - -#: view/theme/duepuntozero/config.php:44 -msgid "greenzero" -msgstr "" - -#: view/theme/duepuntozero/config.php:45 -msgid "purplezero" -msgstr "" - -#: view/theme/duepuntozero/config.php:46 -msgid "easterbunny" -msgstr "" - -#: view/theme/duepuntozero/config.php:47 -msgid "darkzero" -msgstr "" - -#: view/theme/duepuntozero/config.php:48 -msgid "comix" -msgstr "" - -#: view/theme/duepuntozero/config.php:49 -msgid "slackr" -msgstr "" - -#: view/theme/duepuntozero/config.php:64 -msgid "Variations" -msgstr "" - -#: view/theme/clean/config.php:61 -msgid "Midnight" -msgstr "" - -#: view/theme/clean/config.php:62 -msgid "Zenburn" -msgstr "" - -#: view/theme/clean/config.php:63 -msgid "Bootstrap" -msgstr "" - -#: view/theme/clean/config.php:64 -msgid "Shades of Pink" -msgstr "" - -#: view/theme/clean/config.php:65 -msgid "Lime and Orange" -msgstr "" - -#: view/theme/clean/config.php:66 -msgid "GeoCities Retro" -msgstr "" - -#: view/theme/clean/config.php:92 -msgid "Background Image" -msgstr "" - -#: view/theme/clean/config.php:94 -msgid "" -"The URL to a picture (e.g. from your photo album) that should be used as " -"background image." -msgstr "" - -#: view/theme/clean/config.php:99 -msgid "Background Color" -msgstr "" - -#: view/theme/clean/config.php:101 -msgid "HEX value for the background color. Don't include the #" -msgstr "" - -#: view/theme/clean/config.php:115 -msgid "font size" -msgstr "" - -#: view/theme/clean/config.php:117 -msgid "base font size for your interface" -msgstr "" - -#: view/theme/clean/config.php:122 -msgid "Display Accesskeys" -msgstr "" - -#: view/theme/clean/config.php:124 -msgid "" -"Diaplay the access keys assigned to some menu element in the web interface." -msgstr "" - -#: view/theme/frio/php/Image.php:23 -msgid "Repeat the image" -msgstr "" - -#: view/theme/frio/php/Image.php:23 -msgid "Will repeat your image to fill the background." -msgstr "" - -#: view/theme/frio/php/Image.php:25 -msgid "Stretch" -msgstr "" - -#: view/theme/frio/php/Image.php:25 -msgid "Will stretch to width/height of the image." -msgstr "" - -#: view/theme/frio/php/Image.php:27 -msgid "Resize fill and-clip" -msgstr "" - -#: view/theme/frio/php/Image.php:27 -msgid "Resize to fill and retain aspect ratio." -msgstr "" - -#: view/theme/frio/php/Image.php:29 -msgid "Resize best fit" -msgstr "" - -#: view/theme/frio/php/Image.php:29 -msgid "Resize to best fit and retain aspect ratio." -msgstr "" - -#: view/theme/frio/config.php:47 -msgid "Default" -msgstr "" - -#: view/theme/frio/config.php:59 -msgid "Note: " -msgstr "" - -#: view/theme/frio/config.php:59 -msgid "Check image permissions if all users are allowed to visit the image" -msgstr "" - -#: view/theme/frio/config.php:67 -msgid "Select scheme" -msgstr "" - -#: view/theme/frio/config.php:68 -msgid "Navigation bar background color" -msgstr "" - -#: view/theme/frio/config.php:69 -msgid "Navigation bar icon color " -msgstr "" - -#: view/theme/frio/config.php:70 -msgid "Link color" -msgstr "" - -#: view/theme/frio/config.php:71 -msgid "Set the background color" -msgstr "" - -#: view/theme/frio/config.php:72 -msgid "Content background transparency" -msgstr "" - -#: view/theme/frio/config.php:73 -msgid "Set the background image" -msgstr "" - -#: view/theme/frio/theme.php:226 -msgid "Guest" -msgstr "" - -#: view/theme/frio/theme.php:232 -msgid "Visitor" -msgstr "" - -#: index.php:457 -msgid "toggle mobile" -msgstr "" - -#: boot.php:970 -msgid "Delete this item?" -msgstr "" - -#: boot.php:972 -msgid "show fewer" -msgstr "" - -#: boot.php:1696 -#, php-format -msgid "Update %s failed. See error logs." -msgstr "" - -#: boot.php:1808 -msgid "Create a New Account" -msgstr "" - -#: boot.php:1837 -msgid "Password: " -msgstr "" - -#: boot.php:1838 -msgid "Remember me" -msgstr "" - -#: boot.php:1841 -msgid "Or login using OpenID: " -msgstr "" - -#: boot.php:1847 -msgid "Forgot your password?" -msgstr "" - -#: boot.php:1850 -msgid "Website Terms of Service" -msgstr "" - -#: boot.php:1851 -msgid "terms of service" -msgstr "" - -#: boot.php:1853 -msgid "Website Privacy Policy" -msgstr "" - -#: boot.php:1854 -msgid "privacy policy" -msgstr "" diff --git a/view/templates/admin_site.tpl b/view/templates/admin_site.tpl index e670222d4d..86efb26a22 100644 --- a/view/templates/admin_site.tpl +++ b/view/templates/admin_site.tpl @@ -1,6 +1,6 @@

    {{$title}} - {{$page}}

    - +
    @@ -59,7 +59,7 @@ {{include file="field_checkbox.tpl" field=$hide_help}} {{include file="field_select.tpl" field=$singleuser}}
    - +

    {{$registration}}

    {{include file="field_input.tpl" field=$register_text}} {{include file="field_select.tpl" field=$register_policy}} @@ -74,7 +74,7 @@ {{include file="field_input.tpl" field=$maximagelength}} {{include file="field_input.tpl" field=$jpegimagequality}}
    - +

    {{$corporate}}

    {{include file="field_input.tpl" field=$allowed_sites}} {{include file="field_input.tpl" field=$allowed_email}} @@ -107,33 +107,26 @@ {{include file="field_checkbox.tpl" field=$thread_allow}} {{include file="field_checkbox.tpl" field=$newuser_private}} {{include file="field_checkbox.tpl" field=$enotify_no_content}} - {{include file="field_checkbox.tpl" field=$private_addons}} + {{include file="field_checkbox.tpl" field=$private_addons}} {{include file="field_checkbox.tpl" field=$disable_embedded}} {{include file="field_checkbox.tpl" field=$allow_users_remote_self}}
    - +

    {{$advanced}}

    {{include file="field_select.tpl" field=$rino}} - {{include file="field_checkbox.tpl" field=$no_utf}} {{include file="field_checkbox.tpl" field=$verifyssl}} {{include file="field_input.tpl" field=$proxy}} {{include file="field_input.tpl" field=$proxyuser}} {{include file="field_input.tpl" field=$timeout}} - {{if NOT $worker.2}} - {{include file="field_input.tpl" field=$delivery_interval}} - {{include file="field_input.tpl" field=$poll_interval}} - {{/if}} {{include file="field_input.tpl" field=$maxloadavg}} {{include file="field_input.tpl" field=$maxloadavg_frontend}} {{include file="field_input.tpl" field=$optimize_max_tablesize}} {{include file="field_input.tpl" field=$optimize_fragmentation}} {{include file="field_input.tpl" field=$abandon_days}} - {{include file="field_input.tpl" field=$lockpath}} {{include file="field_input.tpl" field=$temppath}} {{include file="field_input.tpl" field=$basepath}} {{include file="field_checkbox.tpl" field=$suppress_tags}} {{include file="field_checkbox.tpl" field=$nodeinfo}} - {{include file="field_input.tpl" field=$embedly}}

    {{$portable_contacts}}

    @@ -154,17 +147,14 @@

    {{$worker_title}}

    - {{include file="field_checkbox.tpl" field=$worker}} - {{if $worker.2}} - {{include file="field_input.tpl" field=$worker_queues}} - {{include file="field_checkbox.tpl" field=$worker_dont_fork}} - {{include file="field_checkbox.tpl" field=$worker_fastlane}} - {{include file="field_checkbox.tpl" field=$worker_frontend}} - {{/if}} + {{include file="field_input.tpl" field=$worker_queues}} + {{include file="field_checkbox.tpl" field=$worker_dont_fork}} + {{include file="field_checkbox.tpl" field=$worker_fastlane}} + {{include file="field_checkbox.tpl" field=$worker_frontend}}
    - + {{* separate form for relocate... *}}
    @@ -173,5 +163,5 @@
    - +
    diff --git a/view/templates/admin_summary.tpl b/view/templates/admin_summary.tpl index c8e8af2294..a8243b6149 100644 --- a/view/templates/admin_summary.tpl +++ b/view/templates/admin_summary.tpl @@ -11,7 +11,7 @@
    {{$queues.label}}
    -
    {{$queues.deliverq}} - {{$queues.queue}}{{if $workeractive}} - {{$queues.workerq}}{{/if}}
    +
    {{$queues.deliverq}} - {{$queues.queue}} - {{$queues.workerq}}
    {{$pending.0}}
    diff --git a/view/templates/event.tpl b/view/templates/event.tpl index 9cad2444ce..328e0e8a13 100644 --- a/view/templates/event.tpl +++ b/view/templates/event.tpl @@ -6,6 +6,7 @@ {{$event.html}} {{if $event.item.plink}}{{/if}} {{if $event.edit}}{{/if}} + {{if $event.drop}}{{/if}}
    {{/foreach}} diff --git a/view/templates/maintenance.tpl b/view/templates/maintenance.tpl index f43da542f8..e26af299f8 100644 --- a/view/templates/maintenance.tpl +++ b/view/templates/maintenance.tpl @@ -1,2 +1,3 @@ -
    {{$sysdown}}
    +

    {{$sysdown}}

    +
    {{$reason}}
    diff --git a/view/theme/frio/css/style.css b/view/theme/frio/css/style.css index 8d7a5f7696..47973ed448 100644 --- a/view/theme/frio/css/style.css +++ b/view/theme/frio/css/style.css @@ -2193,6 +2193,9 @@ ul li:hover .contact-wrapper a.contact-action-link:hover { #event-edit-form-wrapper #event-edit-time { padding: 10px 0; } +.event-buttons .plink-event-link { + margin-left: 20px; +} /* Profiles Page */ .profile-listing-table { display: table; diff --git a/view/theme/frio/js/textedit.js b/view/theme/frio/js/textedit.js index 02191f33de..d212ee0038 100644 --- a/view/theme/frio/js/textedit.js +++ b/view/theme/frio/js/textedit.js @@ -181,7 +181,7 @@ function dropItem(url, elementId) { $el.fadeTo('fast', 0.33, function () { $.get(url).then(function() { $el.remove(); - }).error(function() { + }).fail(function() { // @todo Show related error message $el.show(); }).always(function() { diff --git a/view/theme/frio/templates/event.tpl b/view/theme/frio/templates/event.tpl index ee28756866..dc37f19269 100644 --- a/view/theme/frio/templates/event.tpl +++ b/view/theme/frio/templates/event.tpl @@ -17,8 +17,9 @@
    - {{if $event.item.plink}}{{/if}} - {{if $event.edit}}{{/if}} + {{if $event.edit}}{{/if}} + {{if $event.drop}}{{/if}} + {{if $event.item.plink}}{{/if}}
    diff --git a/view/theme/frost-mobile/templates/admin_site.tpl b/view/theme/frost-mobile/templates/admin_site.tpl index 08b068c402..fb3694f599 100644 --- a/view/theme/frost-mobile/templates/admin_site.tpl +++ b/view/theme/frost-mobile/templates/admin_site.tpl @@ -52,7 +52,6 @@

    {{$advanced}}

    - {{include file="field_checkbox.tpl" field=$no_utf}} {{include file="field_checkbox.tpl" field=$verifyssl}} {{include file="field_input.tpl" field=$proxy}} {{include file="field_input.tpl" field=$proxyuser}} diff --git a/view/theme/frost/templates/admin_site.tpl b/view/theme/frost/templates/admin_site.tpl index e9f472a241..535242a3ec 100644 --- a/view/theme/frost/templates/admin_site.tpl +++ b/view/theme/frost/templates/admin_site.tpl @@ -52,7 +52,6 @@

    {{$advanced}}

    - {{include file="field_checkbox.tpl" field=$no_utf}} {{include file="field_checkbox.tpl" field=$verifyssl}} {{include file="field_input.tpl" field=$proxy}} {{include file="field_input.tpl" field=$proxyuser}}